Files

338 lines
22 KiB
Swift

import XCTest
@testable import GRDB
class SQLExpressionIsConstantTests: GRDBTestCase {
func testColumn() throws {
try makeDatabaseQueue().write { db in
try db.create(table: "t") { $0.autoIncrementedPrimaryKey("id") }
let alias = TableAlias(tableName: "t")
// Column
try XCTAssertEqual(Column("a").sqlExpression.column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual(Column("a").sqlExpression.column(db, for: alias, acceptsBijection: false), nil)
// DatabaseValue
try XCTAssertEqual("foo".sqlExpression.column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual("foo".sqlExpression.column(db, for: alias, acceptsBijection: false), nil)
// SQLExpressionAssociativeBinary
try XCTAssertEqual([].joined(operator: .multiply).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual([].joined(operator: .multiply).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual([Column("a")].joined(operator: .multiply).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual([Column("a")].joined(operator: .multiply).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual([alias[Column("a")]].joined(operator: .multiply).column(db, for: alias, acceptsBijection: true), "a")
try XCTAssertEqual([alias[Column("a")]].joined(operator: .multiply).column(db, for: alias, acceptsBijection: false), "a")
try XCTAssertEqual([-alias[Column("a")]].joined(operator: .multiply).column(db, for: alias, acceptsBijection: true), "a")
try XCTAssertEqual([-alias[Column("a")]].joined(operator: .multiply).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] * "foo".databaseValue).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] * "foo".databaseValue).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual((alias[Column("a")] + "foo".databaseValue).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] + "foo".databaseValue).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual((alias[Column("a")] + alias[Column("b")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] + alias[Column("b")]).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual([alias[Column("a")], "foo".databaseValue].joined(operator: .concat).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual([alias[Column("a")], "foo".databaseValue].joined(operator: .concat).column(db, for: alias, acceptsBijection: true), "a")
// SQLExpressionBetween
try XCTAssertEqual((1...3).contains(alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((1...3).contains(alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
// SQLExpressionBinary
try XCTAssertEqual((alias[Column("a")] - "foo".databaseValue).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] - "foo".databaseValue).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual((alias[Column("a")] - alias[Column("b")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] - alias[Column("b")]).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual((alias[Column("a")] < "foo".databaseValue).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] < "foo".databaseValue).column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionCollate
try XCTAssertEqual(Column("a").collating(.binary).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(Column("a").collating(.binary).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual(alias[Column("a")].collating(.binary).column(db, for: alias, acceptsBijection: false), "a")
try XCTAssertEqual(alias[Column("a")].collating(.binary).column(db, for: alias, acceptsBijection: true), "a")
try XCTAssertEqual((alias[Column("a")] + "foo".databaseValue).collating(.binary).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] + "foo".databaseValue).collating(.binary).column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionContains
try XCTAssertEqual([1, 2, 3].contains(alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual([1, 2, 3].contains(alias[Column("a")]).column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionCount
try XCTAssertEqual(count(alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(count(alias[Column("a")]).column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionCountDistinct
try XCTAssertEqual(count(distinct: alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(count(distinct: alias[Column("a")]).column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionEqual
try XCTAssertEqual((alias[Column("a")] == "foo").column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] == "foo").column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionFastPrimaryKey
try XCTAssertEqual(SQLExpression.fastPrimaryKey.column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.fastPrimaryKey.column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionFunction
try XCTAssertEqual(length(alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(length(alias[Column("a")]).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual((alias[Column("a")] ?? "foo").column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((alias[Column("a")] ?? "foo").column(db, for: alias, acceptsBijection: true), "a")
// SQLExpression.isEmpty
try XCTAssertEqual(SQLExpression.isEmpty(alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.isEmpty(alias[Column("a")]).column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionLiteral
try XCTAssertEqual(SQL("\(alias[Column("a")]) * 2").sqlExpression.column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQL("\(alias[Column("a")]) * 2").sqlExpression.column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionNot
try XCTAssertEqual((!alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((!alias[Column("a")]).column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionQualifiedFastPrimaryKey
try XCTAssertEqual(alias[SQLExpression.fastPrimaryKey].column(db, for: alias, acceptsBijection: false), "id")
try XCTAssertEqual(alias[SQLExpression.fastPrimaryKey].column(db, for: alias, acceptsBijection: true), "id")
// SQLExpression.tableMatch
try XCTAssertEqual(SQLExpression.tableMatch(alias, alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.tableMatch(alias, alias[Column("a")]).column(db, for: alias, acceptsBijection: true), nil)
// SQLExpressionUnary
try XCTAssertEqual((-Column("a")).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((-Column("a")).column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual((-alias[Column("a")]).column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual((-alias[Column("a")]).column(db, for: alias, acceptsBijection: true), "a")
// SQLQualifiedColumn
try XCTAssertEqual(alias[Column("a")].column(db, for: alias, acceptsBijection: false), "a")
try XCTAssertEqual(alias[Column("a")].column(db, for: alias, acceptsBijection: true), "a")
try XCTAssertEqual(TableAlias()[Column("a")].column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(TableAlias()[Column("a")].column(db, for: alias, acceptsBijection: true), nil)
// SQLExpression.rowValue
try XCTAssertEqual(SQLExpression.rowValue([1.sqlExpression])!.column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.rowValue([1.sqlExpression])!.column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual(SQLExpression.rowValue([alias[Column("a")]])!.column(db, for: alias, acceptsBijection: false), "a")
try XCTAssertEqual(SQLExpression.rowValue([alias[Column("a")]])!.column(db, for: alias, acceptsBijection: true), "a")
try XCTAssertEqual(SQLExpression.rowValue([-alias[Column("a")]])!.column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.rowValue([-alias[Column("a")]])!.column(db, for: alias, acceptsBijection: true), "a")
try XCTAssertEqual(SQLExpression.rowValue([1.sqlExpression, 2.sqlExpression])!.column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.rowValue([1.sqlExpression, 2.sqlExpression])!.column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual(SQLExpression.rowValue([alias[Column("a")], 2.sqlExpression])!.column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.rowValue([alias[Column("a")], 2.sqlExpression])!.column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual(SQLExpression.rowValue([1.sqlExpression, alias[Column("a")]])!.column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.rowValue([1.sqlExpression, alias[Column("a")]])!.column(db, for: alias, acceptsBijection: true), nil)
try XCTAssertEqual(SQLExpression.rowValue([alias[Column("a")], alias[Column("a")]])!.column(db, for: alias, acceptsBijection: false), nil)
try XCTAssertEqual(SQLExpression.rowValue([alias[Column("a")], alias[Column("a")]])!.column(db, for: alias, acceptsBijection: true), nil)
}
}
func testIdentifyingColumns() throws {
try makeDatabaseQueue().write { db in
try db.create(table: "t") { $0.autoIncrementedPrimaryKey("id") }
let alias = TableAlias(tableName: "t")
// Column
try XCTAssertEqual(Column("a").sqlExpression.identifyingColums(db, for: alias), [])
// DatabaseValue
try XCTAssertEqual("foo".sqlExpression.identifyingColums(db, for: alias), [])
// SQLExpressionAssociativeBinary
try XCTAssertEqual((alias[Column("a")] == 1 || alias[Column("b")] == 2).identifyingColums(db, for: alias), [])
try XCTAssertEqual((alias[Column("a")] == 1 && alias[Column("b")] == 2).identifyingColums(db, for: alias), ["a", "b"])
try XCTAssertEqual((alias[Column("a")] == 1 && TableAlias()[Column("b")] == 2).identifyingColums(db, for: alias), ["a"])
// SQLExpressionBetween
try XCTAssertEqual((1...3).contains(alias[Column("a")]).identifyingColums(db, for: alias), [])
// SQLExpressionBinary
try XCTAssertEqual((alias[Column("a")] - 1).identifyingColums(db, for: alias), [])
// SQLExpressionCollate
try XCTAssertEqual((alias[Column("a")] == 1).collating(.binary).identifyingColums(db, for: alias), ["a"])
// SQLExpressionContains
try XCTAssertEqual([1, 2, 3].contains(alias[Column("a")]).identifyingColums(db, for: alias), [])
// SQLExpressionCount
try XCTAssertEqual(count(alias[Column("a")]).identifyingColums(db, for: alias), [])
// SQLExpressionCountDistinct
try XCTAssertEqual(count(distinct: alias[Column("a")]).identifyingColums(db, for: alias), [])
// SQLExpressionEqual
try XCTAssertEqual((alias[Column("a")] == nil).identifyingColums(db, for: alias), ["a"])
try XCTAssertEqual((alias[Column("a")] == 1).identifyingColums(db, for: alias), ["a"])
try XCTAssertEqual((1 == alias[Column("a")]).identifyingColums(db, for: alias), ["a"])
try XCTAssertEqual((-alias[Column("a")] == 1).identifyingColums(db, for: alias), ["a"])
try XCTAssertEqual(((alias[Column("a")] * 2) == 1).identifyingColums(db, for: alias), [])
try XCTAssertEqual(((alias[Column("a")] + 2) == 1).identifyingColums(db, for: alias), [])
try XCTAssertEqual(((alias[Column("a")] - 2) == 1).identifyingColums(db, for: alias), [])
try XCTAssertEqual((alias[SQLExpression.fastPrimaryKey] == 1).identifyingColums(db, for: alias), ["id"])
try XCTAssertEqual((alias[Column("a")] == alias[Column("b")]).identifyingColums(db, for: alias), [])
try XCTAssertEqual((TableAlias()[Column("a")] == nil).identifyingColums(db, for: alias), [])
try XCTAssertEqual((TableAlias()[Column("a")] == 1).identifyingColums(db, for: alias), [])
try XCTAssertEqual((SQLExpression.rowValue([alias[SQLExpression.fastPrimaryKey]])! == 1).identifyingColums(db, for: alias), ["id"])
// SQLExpressionFastPrimaryKey
try XCTAssertEqual(SQLExpression.fastPrimaryKey.identifyingColums(db, for: alias), [])
// SQLExpressionFunction
try XCTAssertEqual(length(alias[Column("a")]).identifyingColums(db, for: alias), [])
// SQLExpression.isEmpty
try XCTAssertEqual(SQLExpression.isEmpty(alias[Column("a")]).identifyingColums(db, for: alias), [])
// SQLExpressionLiteral
// SQLExpressionNot
try XCTAssertEqual((!alias[Column("a")]).identifyingColums(db, for: alias), [])
// SQLExpressionQualifiedFastPrimaryKey
try XCTAssertEqual(alias[SQLExpression.fastPrimaryKey].identifyingColums(db, for: alias), [])
// SQLExpression.tableMatch
// SQLExpressionUnary
try XCTAssertEqual((-alias[Column("a")]).identifyingColums(db, for: alias), [])
// SQLQualifiedColumn
try XCTAssertEqual(alias[Column("a")].identifyingColums(db, for: alias), [])
// SQLExpression.rowValue
try XCTAssertEqual(SQLExpression.rowValue([alias[SQLExpression.fastPrimaryKey]])!.identifyingColums(db, for: alias), [])
try XCTAssertEqual(SQLExpression.rowValue([alias[SQLExpression.fastPrimaryKey] == 1])!.identifyingColums(db, for: alias), ["id"])
}
}
func testIdentifyingRowIDs() throws {
try makeDatabaseQueue().write { db in
try db.create(table: "t") { $0.autoIncrementedPrimaryKey("id") }
let alias = TableAlias(tableName: "t")
// Column
// DatabaseValue
// SQLExpressionAssociativeBinary
try XCTAssertEqual((alias[Column("id")] == 1 || alias[Column("id")] == 3).identifyingRowIDs(db, for: alias), [1, 3])
try XCTAssertEqual((alias[Column("id")] == 1 && alias[Column("id")] == 3).identifyingRowIDs(db, for: alias), [])
try XCTAssertEqual((alias[Column("id")] == 1 && alias[Column("id")] == 1).identifyingRowIDs(db, for: alias), [1])
// SQLExpressionBetween
try XCTAssertEqual((0...Int.max).contains(TableAlias()[Column("id")]).identifyingRowIDs(db, for: alias), nil)
// SQLExpressionBinary
// SQLExpressionCollate
// SQLExpressionContains
try XCTAssertEqual([1, 2, 3].contains(TableAlias()[Column("id")]).identifyingRowIDs(db, for: alias), nil)
try XCTAssertEqual([1, 2, 3].contains(alias[Column("id")]).identifyingRowIDs(db, for: alias), [1, 2, 3])
try XCTAssertEqual([].contains(alias[Column("id")]).identifyingRowIDs(db, for: alias), [])
try XCTAssertEqual([1, 2, 3].contains(alias[Column("id")] + 1).identifyingRowIDs(db, for: alias), nil)
// SQLExpressionCount
// SQLExpressionCountDistinct
// SQLExpressionEqual
try XCTAssertEqual((TableAlias()[Column("id")] == 1).identifyingRowIDs(db, for: alias), nil)
try XCTAssertEqual((alias[Column("id")] == 1).identifyingRowIDs(db, for: alias), [1])
try XCTAssertEqual((alias[Column("id")] == nil).identifyingRowIDs(db, for: alias), [])
try XCTAssertEqual(((alias[Column("id")] + 1) == 2).identifyingRowIDs(db, for: alias), nil)
// SQLExpressionFastPrimaryKey
// SQLExpressionFunction
// SQLExpression.isEmpty
// SQLExpressionLiteral
// SQLExpressionNot
// SQLExpressionQualifiedFastPrimaryKey
// SQLExpression.tableMatch
// SQLExpressionUnary
// SQLQualifiedColumn
// SQLExpression.rowValue
}
}
func testIsConstantInRequest() {
// Column
XCTAssertFalse(Column("a").sqlExpression.isConstantInRequest)
// DatabaseValue
XCTAssertTrue(1.sqlExpression.isConstantInRequest)
// SQLExpressionAssociativeBinary
XCTAssertTrue([].joined(operator: .multiply).isConstantInRequest)
XCTAssertTrue([1.databaseValue].joined(operator: .multiply).isConstantInRequest)
XCTAssertFalse([Column("a")].joined(operator: .multiply).isConstantInRequest)
XCTAssertTrue([1.databaseValue, 2.databaseValue].joined(operator: .multiply).isConstantInRequest)
XCTAssertFalse([Column("a"), 2.databaseValue].joined(operator: .multiply).isConstantInRequest)
XCTAssertFalse([1.databaseValue, Column("a")].joined(operator: .multiply).isConstantInRequest)
// SQLExpressionBetween
XCTAssertTrue((1...3).contains(1.databaseValue).isConstantInRequest)
XCTAssertFalse((1...3).contains(Column("a")).isConstantInRequest)
// SQLExpressionBinary
XCTAssertTrue((1.databaseValue - 2.databaseValue).isConstantInRequest)
XCTAssertFalse((Column("a") - 2.databaseValue).isConstantInRequest)
XCTAssertFalse((1.databaseValue - Column("a")).isConstantInRequest)
// CAST
XCTAssertTrue(cast(1.databaseValue, as: .real).isConstantInRequest)
XCTAssertFalse(cast(Column("a"), as: .real).isConstantInRequest)
// SQLExpressionCollate
XCTAssertTrue("foo".databaseValue.collating(.binary).isConstantInRequest)
XCTAssertFalse(Column("a").collating(.binary).isConstantInRequest)
// SQLExpressionContains
XCTAssertFalse([1, 2, 3].contains(Column("a")).isConstantInRequest)
// SQLExpressionCount
XCTAssertFalse(count(Column("a")).isConstantInRequest)
// SQLExpressionCountDistinct
XCTAssertFalse(count(distinct: Column("a")).isConstantInRequest)
// SQLExpressionEqual
XCTAssertTrue((1.databaseValue == 2.databaseValue).isConstantInRequest)
XCTAssertFalse((Column("a") == 2.databaseValue).isConstantInRequest)
XCTAssertFalse((1.databaseValue == Column("a")).isConstantInRequest)
// SQLExpressionFastPrimaryKey
XCTAssertFalse(SQLExpression.fastPrimaryKey.isConstantInRequest)
// SQLExpressionFunction
XCTAssertTrue(length("foo".databaseValue).isConstantInRequest)
XCTAssertFalse(length(Column("a")).isConstantInRequest)
// SQLExpression.isEmpty
XCTAssertTrue(SQLExpression.isEmpty("foo".sqlExpression).isConstantInRequest)
XCTAssertFalse(SQLExpression.isEmpty(Column("a").sqlExpression).isConstantInRequest)
// SQLExpressionLiteral
XCTAssertFalse(SQL("1").sqlExpression.isConstantInRequest)
// SQLExpressionNot
XCTAssertTrue((!(true.databaseValue)).isConstantInRequest)
XCTAssertFalse((!Column("a")).isConstantInRequest)
// SQLExpressionQualifiedFastPrimaryKey
XCTAssertFalse(SQLExpression.fastPrimaryKey.qualified(with: TableAlias()).isConstantInRequest)
// SQLExpression.tableMatch
XCTAssertFalse(SQLExpression.tableMatch(TableAlias(), "foo".sqlExpression).isConstantInRequest)
// SQLExpressionUnary
XCTAssertTrue((-(1.databaseValue)).isConstantInRequest)
XCTAssertFalse((-Column("a")).isConstantInRequest)
// SQLQualifiedColumn
XCTAssertFalse(Column("a").sqlExpression.qualified(with: TableAlias()).isConstantInRequest)
// SQLExpression.rowValue
XCTAssertTrue(SQLExpression.rowValue([1.sqlExpression])!.isConstantInRequest)
XCTAssertFalse(SQLExpression.rowValue([Column("a").sqlExpression])!.isConstantInRequest)
XCTAssertTrue(SQLExpression.rowValue([1.sqlExpression, 2.sqlExpression])!.isConstantInRequest)
XCTAssertFalse(SQLExpression.rowValue([Column("a").sqlExpression, 2.sqlExpression])!.isConstantInRequest)
XCTAssertFalse(SQLExpression.rowValue([1.sqlExpression, Column("a").sqlExpression])!.isConstantInRequest)
}
}