import XCTest @testable import GRDB class SQLLiteralTests: GRDBTestCase { func testSQLInitializer() throws { try makeDatabaseQueue().inDatabase { db in let query = SQL(sql: """ SELECT * FROM player WHERE id = \("?") """, arguments: [1]) let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE id = ? """) XCTAssertEqual(arguments, [1]) } } func testPlusOperator() throws { try makeDatabaseQueue().inDatabase { db in var query = SQL(sql: "SELECT * ") query = query + SQL(sql: "FROM player ") query = query + SQL(sql: "WHERE id = ? ", arguments: [1]) query = query + SQL(sql: "AND name = ?", arguments: ["Arthur"]) let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE id = ? AND name = ? """) XCTAssertEqual(arguments, [1, "Arthur"]) } } func testPlusEqualOperator() throws { try makeDatabaseQueue().inDatabase { db in var query = SQL(sql: "SELECT * ") query += SQL(sql: "FROM player ") query += SQL(sql: "WHERE id = ? ", arguments: [1]) query += SQL(sql: "AND name = ?", arguments: ["Arthur"]) let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE id = ? AND name = ? """) XCTAssertEqual(arguments, [1, "Arthur"]) } } func testAppendLiteral() throws { try makeDatabaseQueue().inDatabase { db in var query = SQL(sql: "SELECT * ") query.append(literal: SQL(sql: "FROM player ")) query.append(literal: SQL(sql: "WHERE id = ? ", arguments: [1])) query.append(literal: SQL(sql: "AND name = ?", arguments: ["Arthur"])) let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE id = ? AND name = ? """) XCTAssertEqual(arguments, [1, "Arthur"]) } } func testAppendRawSQL() throws { try makeDatabaseQueue().inDatabase { db in var query = SQL(sql: "SELECT * ") query.append(sql: "FROM player ") query.append(sql: "WHERE score > \(1000) ") query.append(sql: "AND \("name") = :name", arguments: ["name": "Arthur"]) let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE score > 1000 AND name = :name """) XCTAssertEqual(arguments, ["name": "Arthur"]) } } func testSequenceJoined() throws { try makeDatabaseQueue().inDatabase { db in // A sequence that can't be consumed twice var i = 0 let sequence = AnySequence { return AnyIterator { guard i < 3 else { return nil } i += 1 return SQL(sql: "(\(i) = ?)", arguments: [i]) } } do { i = 0 let joined = sequence.joined() let (sql, arguments) = try joined.build(db) XCTAssertEqual(sql, "(1 = ?)(2 = ?)(3 = ?)") XCTAssertEqual(arguments, [1, 2, 3]) } do { i = 0 let joined = sequence.joined(separator: " AND ") let (sql, arguments) = try joined.build(db) XCTAssertEqual(sql, "(1 = ?) AND (2 = ?) AND (3 = ?)") XCTAssertEqual(arguments, [1, 2, 3]) } } } func testCollectionJoined() throws { try makeDatabaseQueue().inDatabase { db in let collection = AnyCollection([ SQL(sql: "SELECT * "), SQL(sql: "FROM player "), SQL(sql: "WHERE score > ? ", arguments: [1000]), SQL(sql: "AND name = :name", arguments: ["name": "Arthur"]), ]) do { let joined = collection.joined() let (sql, arguments) = try joined.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE score > ? AND name = :name """) XCTAssertEqual(arguments, [1000] + ["name": "Arthur"]) } do { let joined = collection.joined(separator: " ") let (sql, arguments) = try joined.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE score > ? AND name = :name """) XCTAssertEqual(arguments, [1000] + ["name": "Arthur"]) } } } func testQualifiedSQLLiteral() throws { struct Player: TableRecord { } try makeDatabaseQueue().write { db in try db.create(table: "player") { t in t.column("name", .text) t.column("createdAt", .datetime) } do { // Test of SQL.init(_:) documentation (plus qualification) let columnLiteral = SQL(Column("name")) let suffixLiteral = SQL("O'Brien".databaseValue) let literal = [columnLiteral, suffixLiteral].joined(separator: " || ") let request = Player.aliased(TableAlias(name: "p")).select(literal) try assertEqualSQL(db, request, """ SELECT "p"."name" || 'O''Brien' FROM "player" "p" """) } do { // Test qualification of interpolated literal let literal: SQL = "\(Column("name")) || 'foo'" let request = Player.aliased(TableAlias(name: "p")).select(literal) try assertEqualSQL(db, request, """ SELECT "p"."name" || 'foo' FROM "player" "p" """) } } } } extension SQLLiteralTests { func testLiteralInitializer() throws { try makeDatabaseQueue().inDatabase { db in let query = SQL(""" SELECT * FROM player WHERE id = \(1) """) let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE id = ? """) XCTAssertEqual(arguments, [1]) } } func testRawSQLInterpolation() throws { try makeDatabaseQueue().inDatabase { db in let query: SQL = """ SELECT * \(sql: "FROM player") \(sql: "WHERE score > \(1000)") \(sql: "AND \("name") = :name", arguments: ["name": "Arthur"]) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE score > 1000 AND name = :name """) XCTAssertEqual(arguments, ["name": "Arthur"]) } } func testSelectableInterpolation() throws { try makeDatabaseQueue().inDatabase { db in do { // Non-existential let query: SQL = """ SELECT \(AllColumns()) FROM player """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player """) XCTAssert(arguments.isEmpty) } do { // Existential let query: SQL = """ SELECT \(AllColumns() as any SQLSelectable) FROM player """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player """) XCTAssert(arguments.isEmpty) } do { // Existential let query: SQL = """ SELECT \(nil as (any SQLSelectable)?) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT NULL """) XCTAssert(arguments.isEmpty) } } } func testTableInterpolation() throws { try makeDatabaseQueue().inDatabase { db in struct Player: TableRecord { } do { // Table let table = Table("player") let query: SQL = """ SELECT * FROM \(table) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM "player" """) XCTAssert(arguments.isEmpty) } do { // Non-existential let query: SQL = """ SELECT * FROM \(Player.self) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM "player" """) XCTAssert(arguments.isEmpty) } do { // Non-existential let query: SQL = """ INSERT INTO \(tableOf: Player()) DEFAULT VALUES """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ INSERT INTO "player" DEFAULT VALUES """) XCTAssert(arguments.isEmpty) } do { // Existential let query: SQL = """ INSERT INTO \(tableOf: Player() as any TableRecord) DEFAULT VALUES """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ INSERT INTO "player" DEFAULT VALUES """) XCTAssert(arguments.isEmpty) } } } func testTableSelectionInterpolation() throws { try makeDatabaseQueue().inDatabase { db in struct Player: TableRecord { } struct AltPlayer: TableRecord { static let databaseSelection: [any SQLSelectable] = [Column("id"), Column("name")] } do { let query: SQL = """ SELECT \(columnsOf: Player.self) FROM player """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT "player".* FROM player """) XCTAssert(arguments.isEmpty) } do { let query: SQL = """ SELECT \(columnsOf: Player.self, tableAlias: "p") FROM player p """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT "p".* FROM player p """) XCTAssert(arguments.isEmpty) } do { let query: SQL = """ SELECT \(columnsOf: AltPlayer.self) FROM player """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT "altPlayer"."id", "altPlayer"."name" FROM player """) XCTAssert(arguments.isEmpty) } do { let query: SQL = """ SELECT \(columnsOf: AltPlayer.self, tableAlias: "p") FROM player p """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT "p"."id", "p"."name" FROM player p """) XCTAssert(arguments.isEmpty) } } } func testExpressibleInterpolation() throws { try makeDatabaseQueue().inDatabase { db in let a = Column("a") let b = Column("b") let integer: Int = 1 let optionalInteger: Int? = 2 let nilInteger: Int? = nil let query: SQL = """ SELECT \(a), \(a + 1), \(2 * (a + 1)), \(a < b), \(integer), \(optionalInteger), \(nilInteger), \(a == nilInteger) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT "a", "a" + ?, ? * ("a" + ?), "a" < "b", ?, ?, NULL, "a" IS NULL """) XCTAssertEqual(arguments, [1, 2, 1, 1, 2]) } } func testDatabaseValueConvertibleInterpolation() throws { try makeDatabaseQueue().inDatabase { db in func test(value: V, isInterpolatedAs dbValue: DatabaseValue) throws { let query: SQL = "SELECT \(value)" let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, "SELECT ?") XCTAssertEqual(arguments, [dbValue]) } struct V: DatabaseValueConvertible { var databaseValue: DatabaseValue { "V".databaseValue } static func fromDatabaseValue(_ dbValue: DatabaseValue) -> V? { nil } } try test(value: 42, isInterpolatedAs: 42.databaseValue) try test(value: 1.23, isInterpolatedAs: 1.23.databaseValue) try test(value: "foo", isInterpolatedAs: "foo".databaseValue) try test(value: "foo".data(using: .utf8)!, isInterpolatedAs: "foo".data(using: .utf8)!.databaseValue) try test(value: V(), isInterpolatedAs: "V".databaseValue) } } func testDataInterpolation() throws { try makeDatabaseQueue().inDatabase { db in // This test makes sure the Sequence conformance of Data does not // kick in. let data = "SQLite".data(using: .utf8)! let query: SQL = "SELECT \(data)" let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, "SELECT ?") XCTAssertEqual(arguments, [data]) } } func testAliasedExpressionInterpolation() throws { try makeDatabaseQueue().inDatabase { db in let query: SQL = """ SELECT \(Column("name").forKey("foo")), \(1.databaseValue.forKey("bar")) FROM player """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT "name" AS "foo", ? AS "bar" FROM player """) XCTAssertEqual(arguments, [1]) } } func testCodingKeyInterpolation() throws { try makeDatabaseQueue().inDatabase { db in enum CodingKeys: String, CodingKey { case name } let query: SQL = """ SELECT \(CodingKeys.name) FROM player """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT "name" FROM player """) XCTAssert(arguments.isEmpty) } } func testCodingKeyColumnInterpolation() throws { try makeDatabaseQueue().inDatabase { db in enum CodingKeys: String, CodingKey, ColumnExpression { case name } let query: SQL = """ SELECT \(CodingKeys.name) FROM player """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT "name" FROM player """) XCTAssert(arguments.isEmpty) } } func testExpressibleSequenceInterpolation() throws { try makeDatabaseQueue().inDatabase { db in let set: Set = [1] let array = ["foo", "bar", "baz"] let expressions: [any SQLExpressible] = [Column("a"), Column("b") + 2] let query: SQL = """ SELECT * FROM player WHERE teamId IN \(set) AND name IN \(array) AND c IN \(expressions) AND d IN \([]) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE teamId IN (?) AND name IN (?,?,?) AND c IN ("a","b" + ?) AND d IN (SELECT NULL WHERE NULL) """) XCTAssertEqual(arguments, [1, "foo", "bar", "baz", 2]) } } func testOrderingTermInterpolation() throws { try makeDatabaseQueue().inDatabase { db in let query: SQL = """ SELECT * FROM player ORDER BY \(Column("name").desc) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player ORDER BY "name" DESC """) XCTAssert(arguments.isEmpty) } } func testSQLLiteralInterpolation() throws { try makeDatabaseQueue().inDatabase { db in let condition: SQL = "name = \("Arthur")" let query: SQL = """ SELECT *, \(true) FROM player WHERE \(literal: condition) AND score > \(1000) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT *, ? FROM player WHERE name = ? AND score > ? """) XCTAssertEqual(arguments, [true, "Arthur", 1000]) } } func testSQLLiteralInterpolation2() throws { // Since SQL conforms to SQLExpressible, make sure it is NOT // interpreted as an expression when embedded in another literal. let literal: SQL = "\("foo") \(SQL("bar \("baz".dropFirst())"))" XCTAssertEqual(literal.elements.count, 4) switch literal.elements[0] { case .expression: break; default: XCTFail("Expected expression") } switch literal.elements[1] { case .sql(" ", []): break; default: XCTFail("Expected sql") } switch literal.elements[2] { case .sql("bar ", []): break; default: XCTFail("Expected sql") } switch literal.elements[3] { case .expression: break; default: XCTFail("Expected expression") } let (sql, arguments) = try makeDatabaseQueue().read(literal.build) XCTAssertEqual(sql, "? bar ?") XCTAssertEqual(arguments, ["foo", "az"]) } func testSQLRequestInterpolation() throws { try makeDatabaseQueue().inDatabase { db in let subquery: SQLRequest = "SELECT MAX(score) - \(10) FROM player" let query: SQL = """ SELECT * FROM player WHERE score = (\(subquery)) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE score = (SELECT MAX(score) - ? FROM player) """) XCTAssertEqual(arguments, [10]) } } func testQueryInterfaceRequestInterpolation() throws { try makeDatabaseQueue().inDatabase { db in try db.create(table: "player") { t in t.autoIncrementedPrimaryKey("id") t.column("score", .integer) } struct Player: TableRecord { } let subquery = Player.select(max(Column("score")) - 10) let query: SQL = """ SELECT * FROM player WHERE score = (\(subquery)) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE score = (SELECT MAX("score") - ? FROM "player") """) XCTAssertEqual(arguments, [10]) } } func testJoinedQueryInterfaceRequestInterpolation() throws { try makeDatabaseQueue().inDatabase { db in try db.create(table: "team") { t in t.autoIncrementedPrimaryKey("id") } try db.create(table: "player") { t in t.autoIncrementedPrimaryKey("id") t.belongsTo("team") t.column("score", .integer) } struct Player: TableRecord { } struct Team: TableRecord { } let subquery = Player .select(max(Column("score")) - 10) .joining(required: Player.belongsTo(Team.self)) let query: SQL = """ SELECT * FROM player WHERE score = (\(subquery)) """ let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE score = (SELECT MAX("player"."score") - ? FROM "player" JOIN "team" ON "team"."id" = "player"."teamId") """) XCTAssertEqual(arguments, [10]) } } func testPlusOperatorWithInterpolation() throws { try makeDatabaseQueue().inDatabase { db in var query: SQL = "SELECT \(AllColumns()) " query = query + "FROM player " query = query + "WHERE id = \(1)" let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE id = ? """) XCTAssertEqual(arguments, [1]) } } func testPlusEqualOperatorWithInterpolation() throws { try makeDatabaseQueue().inDatabase { db in var query: SQL = "SELECT \(AllColumns()) " query += "FROM player " query += "WHERE id = \(1)" let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE id = ? """) XCTAssertEqual(arguments, [1]) } } func testAppendLiteralWithInterpolation() throws { try makeDatabaseQueue().inDatabase { db in var query: SQL = "SELECT \(AllColumns()) " query.append(literal: "FROM player ") query.append(literal: "WHERE id = \(1)") let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE id = ? """) XCTAssertEqual(arguments, [1]) } } func testAppendRawSQLWithInterpolation() throws { try makeDatabaseQueue().inDatabase { db in var query: SQL = "SELECT \(AllColumns()) " query.append(sql: "FROM player ") query.append(sql: "WHERE score > \(1000) ") query.append(sql: "AND \("name") = :name", arguments: ["name": "Arthur"]) let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player WHERE score > 1000 AND name = :name """) XCTAssertEqual(arguments, ["name": "Arthur"]) } } func testQualifiedSQLInterpolation() throws { struct Player: TableRecord { } try makeDatabaseQueue().write { db in try db.create(table: "player") { t in t.column("name", .text) t.column("createdAt", .datetime) } let nameColumn = Column("name") let baseRequest = Player.aliased(TableAlias(name: "p")) do { let alteredNameLiteral = SQL("\(nameColumn) || \("O'Brien")") let request = baseRequest.select(literal: alteredNameLiteral) try assertEqualSQL(db, request, """ SELECT "p"."name" || 'O''Brien' FROM "player" "p" """) } do { let alteredNameLiteral = SQL("\(nameColumn) || \("O'Brien")") let alteredNameColumn = alteredNameLiteral.forKey("alteredName") let request = baseRequest.select(alteredNameColumn) try assertEqualSQL(db, request, """ SELECT "p"."name" || 'O''Brien' AS "alteredName" FROM "player" "p" """) } do { let subquery: SQLRequest = "SELECT MAX(\(nameColumn)) FROM \(Player.self)" let conditionLiteral = SQL("\(nameColumn) = (\(subquery))") let request = baseRequest.filter(literal: conditionLiteral) try assertEqualSQL(db, request, """ SELECT "p".* FROM "player" "p" WHERE "p"."name" = (SELECT MAX("name") FROM "player") """) } do { // Test of documentation let date = "2020-01-23" let createdAt = Column("createdAt") let creationDate = SQL("DATE(\(createdAt))") let request = Player.filter(creationDate == date) try assertEqualSQL(db, request, """ SELECT * FROM "player" WHERE (DATE("createdAt")) = '2020-01-23' """) } do { // Here we test that users can define functions that return // literal expressions (existential variant). func date(_ value: any SQLExpressible) -> SQLExpression { SQL("DATE(\(value))").sqlExpression } let createdAt = Column("createdAt") let request = Player.filter(date(createdAt) == "2020-01-23") try assertEqualSQL(db, request, """ SELECT * FROM "player" WHERE (DATE("createdAt")) = '2020-01-23' """) } do { // Here we test that users can define functions that return // literal expressions (generic variant). func date(_ value: some SQLExpressible) -> SQLExpression { SQL("DATE(\(value))").sqlExpression } let createdAt = Column("createdAt") let request = Player.filter(date(createdAt) == "2020-01-23") try assertEqualSQL(db, request, """ SELECT * FROM "player" WHERE (DATE("createdAt")) = '2020-01-23' """) } do { // Here we test that users can still define functions that // return literal expressions with the previously // supported technique (existential variant). func date(_ value: any SQLExpressible) -> SQLExpression { SQL("DATE(\(value.sqlExpression))").sqlExpression } let createdAt = Column("createdAt") let request = Player.filter(date(createdAt) == "2020-01-23") try assertEqualSQL(db, request, """ SELECT * FROM "player" WHERE (DATE("createdAt")) = '2020-01-23' """) } do { // Here we test that users can still define functions that // return literal expressions with the previously // supported technique (generic variant). func date(_ value: some SQLExpressible) -> SQLExpression { SQL("DATE(\(value.sqlExpression))").sqlExpression } let createdAt = Column("createdAt") let request = Player.filter(date(createdAt) == "2020-01-23") try assertEqualSQL(db, request, """ SELECT * FROM "player" WHERE (DATE("createdAt")) = '2020-01-23' """) } } } func testCollationInterpolation() throws { try makeDatabaseQueue().inDatabase { db in do { // Database.CollationName let query: SQL = "SELECT * FROM player ORDER BY email COLLATION \(.nocase)" let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player ORDER BY email COLLATION NOCASE """) XCTAssertEqual(arguments, []) } do { // DatabaseCollation let query: SQL = "SELECT * FROM player ORDER BY name COLLATION \(.localizedCompare)" let (sql, arguments) = try query.build(db) XCTAssertEqual(sql, """ SELECT * FROM player ORDER BY name COLLATION swiftLocalizedCompare """) XCTAssertEqual(arguments, []) } } } func testIsEmpty() { XCTAssertTrue(SQL(elements: []).isEmpty) XCTAssertTrue(SQL(sql: "").isEmpty) XCTAssertTrue(SQL("").isEmpty) } func testProtocolResolution() throws { // SQL can feed ordering, selection, and expressions. acceptOrderingTerm_generic(SQL("")) acceptSelectable_generic(SQL("")) acceptSpecificExpressible_generic(SQL("")) acceptExpressible_generic(SQL("")) acceptOrderingTerm_existential(SQL("")) acceptSelectable_existential(SQL("")) acceptSpecificExpressible_existential(SQL("")) acceptExpressible_existential(SQL("")) // SQL can build complex expressions and orderings _ = SQL("") + 1 _ = SQL("").desc // Swift String literals are interpreted as String, even when SQL // is an accepted type. // // should not compile: XCTAssertEqual(acceptOrderingTerm_generic(""), String(describing: String.self)) // should not compile: XCTAssertEqual(acceptSelectable_generic(""), String(describing: String.self)) // should not compile: XCTAssertEqual(acceptSpecificExpressible_generic(""), String(describing: String.self)) XCTAssertEqual(acceptExpressible_generic(""), String(describing: String.self)) // should not compile: XCTAssertEqual(acceptOrderingTerm_existential(""), String(describing: String.self)) // should not compile: XCTAssertEqual(acceptSelectable_existential(""), String(describing: String.self)) // should not compile: XCTAssertEqual(acceptSpecificExpressible_existential(""), String(describing: String.self)) XCTAssertEqual(acceptExpressible_existential(""), String(describing: String.self)) // When a literal can be interpreted as an ordering, a selection, or an // expression, then the expression interpretation is favored. // This test targets TableAlias subscript. // // should not compile: XCTAssertEqual(overloaded_generic(""), "a") XCTAssertEqual(overloaded_generic(SQL("")), "SQLSpecificExpressible") // should not compile: XCTAssertEqual(overloaded_existential(""), "a") XCTAssertEqual(overloaded_existential(SQL("")), "SQLSpecificExpressible") // In practice: try makeDatabaseQueue().write { db in struct Player: TableRecord { } try db.create(table: "player") { t in t.autoIncrementedPrimaryKey("id") t.column("name") t.column("score") } let statement = try Player .select(SQL("id"), SQL("score").forKey("theScore")) .filter(SQL("name = \("O'Brien")") && SQL("score > 1000")) .order(SQL("score ASC"), SQL("name").desc) .makePreparedRequest(db) .statement XCTAssertEqual(statement.sql, """ SELECT id, score AS "theScore" \ FROM "player" \ WHERE (name = ?) AND (score > 1000) ORDER BY score ASC, name DESC """) XCTAssertEqual(statement.arguments, ["O'Brien"]) } } } // Support for testProtocolResolution() @discardableResult private func acceptOrderingTerm_generic(_ x: some SQLOrderingTerm) -> String { String(describing: type(of: x)) } @discardableResult private func acceptSelectable_generic(_ x: some SQLSelectable) -> String { String(describing: type(of: x)) } @discardableResult private func acceptSpecificExpressible_generic(_ x: some SQLSpecificExpressible) -> String { String(describing: type(of: x)) } @discardableResult private func acceptExpressible_generic(_ x: some SQLExpressible) -> String { String(describing: type(of: x)) } private func overloaded_generic(_ x: some SQLOrderingTerm) -> String { "SQLOrderingTerm" } private func overloaded_generic(_ x: some SQLSelectable) -> String { "SQLSelectable" } private func overloaded_generic(_ x: some SQLSpecificExpressible & SQLSelectable & SQLOrderingTerm) -> String { "SQLSpecificExpressible" } @discardableResult private func acceptOrderingTerm_existential(_ x: any SQLOrderingTerm) -> String { String(describing: type(of: x)) } @discardableResult private func acceptSelectable_existential(_ x: any SQLSelectable) -> String { String(describing: type(of: x)) } @discardableResult private func acceptSpecificExpressible_existential(_ x: any SQLSpecificExpressible) -> String { String(describing: type(of: x)) } @discardableResult private func acceptExpressible_existential(_ x: any SQLExpressible) -> String { String(describing: type(of: x)) } private func overloaded_existential(_ x: any SQLOrderingTerm) -> String { "SQLOrderingTerm" } private func overloaded_existential(_ x: any SQLSelectable) -> String { "SQLSelectable" } private func overloaded_existential(_ x: any SQLSpecificExpressible & SQLSelectable & SQLOrderingTerm) -> String { "SQLSpecificExpressible" }