Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Sources/SQLite/Typed/Operators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -558,45 +558,45 @@ public func <=<V: Value>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> where
}

public func ~=<V: Value>(lhs: ClosedRange<V>, rhs: Expression<V>) -> Expression<Bool> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) BETWEEN ? AND ?", rhs.bindings + [lhs.lowerBound.datatypeValue, lhs.upperBound.datatypeValue])
Expression("(\(rhs.template) BETWEEN ? AND ?)", rhs.bindings + [lhs.lowerBound.datatypeValue, lhs.upperBound.datatypeValue])
}

public func ~=<V: Value>(lhs: ClosedRange<V>, rhs: Expression<V?>) -> Expression<Bool?> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) BETWEEN ? AND ?", rhs.bindings + [lhs.lowerBound.datatypeValue, lhs.upperBound.datatypeValue])
Expression("(\(rhs.template) BETWEEN ? AND ?)", rhs.bindings + [lhs.lowerBound.datatypeValue, lhs.upperBound.datatypeValue])
}

public func ~=<V: Value>(lhs: Range<V>, rhs: Expression<V>) -> Expression<Bool> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) >= ? AND \(rhs.template) < ?",
Expression("(\(rhs.template) >= ? AND \(rhs.template) < ?)",
rhs.bindings + [lhs.lowerBound.datatypeValue] + rhs.bindings + [lhs.upperBound.datatypeValue])
}

public func ~=<V: Value>(lhs: Range<V>, rhs: Expression<V?>) -> Expression<Bool?> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) >= ? AND \(rhs.template) < ?",
Expression("(\(rhs.template) >= ? AND \(rhs.template) < ?)",
rhs.bindings + [lhs.lowerBound.datatypeValue] + rhs.bindings + [lhs.upperBound.datatypeValue])
}

public func ~=<V: Value>(lhs: PartialRangeThrough<V>, rhs: Expression<V>) -> Expression<Bool> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) <= ?", rhs.bindings + [lhs.upperBound.datatypeValue])
Expression("(\(rhs.template) <= ?)", rhs.bindings + [lhs.upperBound.datatypeValue])
}

public func ~=<V: Value>(lhs: PartialRangeThrough<V>, rhs: Expression<V?>) -> Expression<Bool?> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) <= ?", rhs.bindings + [lhs.upperBound.datatypeValue])
Expression("(\(rhs.template) <= ?)", rhs.bindings + [lhs.upperBound.datatypeValue])
}

public func ~=<V: Value>(lhs: PartialRangeUpTo<V>, rhs: Expression<V>) -> Expression<Bool> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) < ?", rhs.bindings + [lhs.upperBound.datatypeValue])
Expression("(\(rhs.template) < ?)", rhs.bindings + [lhs.upperBound.datatypeValue])
}

public func ~=<V: Value>(lhs: PartialRangeUpTo<V>, rhs: Expression<V?>) -> Expression<Bool?> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) < ?", rhs.bindings + [lhs.upperBound.datatypeValue])
Expression("(\(rhs.template) < ?)", rhs.bindings + [lhs.upperBound.datatypeValue])
}

public func ~=<V: Value>(lhs: PartialRangeFrom<V>, rhs: Expression<V>) -> Expression<Bool> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) >= ?", rhs.bindings + [lhs.lowerBound.datatypeValue])
Expression("(\(rhs.template) >= ?)", rhs.bindings + [lhs.lowerBound.datatypeValue])
}

public func ~=<V: Value>(lhs: PartialRangeFrom<V>, rhs: Expression<V?>) -> Expression<Bool?> where V.Datatype: Comparable & Value {
Expression("\(rhs.template) >= ?", rhs.bindings + [lhs.lowerBound.datatypeValue])
Expression("(\(rhs.template) >= ?)", rhs.bindings + [lhs.lowerBound.datatypeValue])
}

// MARK: -
Expand Down
11 changes: 11 additions & 0 deletions Tests/SQLiteTests/Schema/SchemaTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,17 @@ class SchemaTests: XCTestCase {
)
}

// https://github.com/stephencelis/SQLite.swift/issues/1056
// A column-level CHECK built from a range pattern (BETWEEN) must wrap its
// condition in parentheses, just like every other check condition does,
// otherwise SQLite rejects the generated `CREATE TABLE` statement.
func test_column_withRangeCheck_compilesValidCheckConstraint() {
XCTAssertEqual(
"CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64\" BETWEEN 0 AND 26))",
table.create { t in t.column(int64, check: 0...26 ~= int64) }
)
}

func test_column_withIntegerExpression_compilesPrimaryKeyAutoincrementColumnDefinitionExpression() {
XCTAssertEqual(
"CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
Expand Down
32 changes: 16 additions & 16 deletions Tests/SQLiteTests/Typed/OperatorsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,38 +274,38 @@ class OperatorsTests: XCTestCase {
}

func test_patternMatchingOperator_withComparableCountableClosedRange_buildsBetweenBooleanExpression() {
assertSQL("\"int\" BETWEEN 0 AND 5", 0...5 ~= int)
assertSQL("\"intOptional\" BETWEEN 0 AND 5", 0...5 ~= intOptional)
assertSQL("(\"int\" BETWEEN 0 AND 5)", 0...5 ~= int)
assertSQL("(\"intOptional\" BETWEEN 0 AND 5)", 0...5 ~= intOptional)
}

func test_patternMatchingOperator_withComparableClosedRange_buildsBetweenBooleanExpression() {
assertSQL("\"double\" BETWEEN 1.2 AND 4.5", 1.2...4.5 ~= double)
assertSQL("\"doubleOptional\" BETWEEN 1.2 AND 4.5", 1.2...4.5 ~= doubleOptional)
assertSQL("(\"double\" BETWEEN 1.2 AND 4.5)", 1.2...4.5 ~= double)
assertSQL("(\"doubleOptional\" BETWEEN 1.2 AND 4.5)", 1.2...4.5 ~= doubleOptional)
}

func test_patternMatchingOperator_withComparableRange_buildsBooleanExpression() {
assertSQL("\"double\" >= 1.2 AND \"double\" < 4.5", 1.2..<4.5 ~= double)
assertSQL("\"doubleOptional\" >= 1.2 AND \"doubleOptional\" < 4.5", 1.2..<4.5 ~= doubleOptional)
assertSQL("(\"double\" >= 1.2 AND \"double\" < 4.5)", 1.2..<4.5 ~= double)
assertSQL("(\"doubleOptional\" >= 1.2 AND \"doubleOptional\" < 4.5)", 1.2..<4.5 ~= doubleOptional)
}

func test_patternMatchingOperator_withComparablePartialRangeThrough_buildsBooleanExpression() {
assertSQL("\"double\" <= 4.5", ...4.5 ~= double)
assertSQL("\"doubleOptional\" <= 4.5", ...4.5 ~= doubleOptional)
assertSQL("(\"double\" <= 4.5)", ...4.5 ~= double)
assertSQL("(\"doubleOptional\" <= 4.5)", ...4.5 ~= doubleOptional)
}

func test_patternMatchingOperator_withComparablePartialRangeUpTo_buildsBooleanExpression() {
assertSQL("\"double\" < 4.5", ..<4.5 ~= double)
assertSQL("\"doubleOptional\" < 4.5", ..<4.5 ~= doubleOptional)
assertSQL("(\"double\" < 4.5)", ..<4.5 ~= double)
assertSQL("(\"doubleOptional\" < 4.5)", ..<4.5 ~= doubleOptional)
}

func test_patternMatchingOperator_withComparablePartialRangeFrom_buildsBooleanExpression() {
assertSQL("\"double\" >= 4.5", 4.5... ~= double)
assertSQL("\"doubleOptional\" >= 4.5", 4.5... ~= doubleOptional)
assertSQL("(\"double\" >= 4.5)", 4.5... ~= double)
assertSQL("(\"doubleOptional\" >= 4.5)", 4.5... ~= doubleOptional)
}

func test_patternMatchingOperator_withComparableClosedRangeString_buildsBetweenBooleanExpression() {
assertSQL("\"string\" BETWEEN 'a' AND 'b'", "a"..."b" ~= string)
assertSQL("\"stringOptional\" BETWEEN 'a' AND 'b'", "a"..."b" ~= stringOptional)
assertSQL("(\"string\" BETWEEN 'a' AND 'b')", "a"..."b" ~= string)
assertSQL("(\"stringOptional\" BETWEEN 'a' AND 'b')", "a"..."b" ~= stringOptional)
}

func test_doubleAndOperator_withBooleanExpressions_buildsCompoundExpression() {
Expand Down Expand Up @@ -373,7 +373,7 @@ class OperatorsTests: XCTestCase {
let begin = Date(timeIntervalSince1970: 0)
let end = Date(timeIntervalSince1970: 5000)
assertSQL(
"\"date\" >= '1970-01-01T00:00:00.000' AND \"date\" < '1970-01-01T01:23:20.000'",
"(\"date\" >= '1970-01-01T00:00:00.000' AND \"date\" < '1970-01-01T01:23:20.000')",
(begin..<end) ~= date
)
}
Expand All @@ -382,7 +382,7 @@ class OperatorsTests: XCTestCase {
let begin = Date(timeIntervalSince1970: 0)
let end = Date(timeIntervalSince1970: 5000)
assertSQL(
"\"date\" BETWEEN '1970-01-01T00:00:00.000' AND '1970-01-01T01:23:20.000'",
"(\"date\" BETWEEN '1970-01-01T00:00:00.000' AND '1970-01-01T01:23:20.000')",
(begin...end) ~= date
)
}
Expand Down
Loading