diff --git a/Sources/SQLKit/Builders/Prototypes/SQLUnqualifiedColumnListBuilder.swift b/Sources/SQLKit/Builders/Prototypes/SQLUnqualifiedColumnListBuilder.swift index 1fbb8965..fd8c5dc2 100644 --- a/Sources/SQLKit/Builders/Prototypes/SQLUnqualifiedColumnListBuilder.swift +++ b/Sources/SQLKit/Builders/Prototypes/SQLUnqualifiedColumnListBuilder.swift @@ -14,7 +14,7 @@ extension SQLUnqualifiedColumnListBuilder { @inlinable @discardableResult public func column(_ column: String) -> Self { - self.column(column == "*" ? SQLLiteral.all : SQLColumn(column)) + self.column(SQLColumn(column)) } /// Specify a single column to be included in the list of columns for the query. @@ -36,7 +36,7 @@ extension SQLUnqualifiedColumnListBuilder { @inlinable @discardableResult public func columns(_ columns: [String]) -> Self { - self.columns(columns.map { $0 == "*" ? SQLLiteral.all as any SQLExpression : SQLColumn($0) }) + self.columns(columns.map { SQLColumn($0) }) } /// Specify mutiple columns to be included in the list of columns for the query. diff --git a/Sources/SQLKit/Expressions/Basics/SQLColumn.swift b/Sources/SQLKit/Expressions/Basics/SQLColumn.swift index 6bdb1fc3..2b316ac0 100644 --- a/Sources/SQLKit/Expressions/Basics/SQLColumn.swift +++ b/Sources/SQLKit/Expressions/Basics/SQLColumn.swift @@ -1,18 +1,26 @@ /// An expression representing an optionally table-qualified column in an SQL table. public struct SQLColumn: SQLExpression { - /// The column name, usually an ``SQLIdentifier``. + /// The column name. + /// + /// Usually an ``SQLIdentifier``. public var name: any SQLExpression - /// If specified, the table to which the column belongs. Usually an ``SQLIdentifier`` when not `nil`. + /// If specified, the table to which the column belongs. + /// + /// Usually an ``SQLIdentifier`` or ``SQLQualifiedTable`` when not `nil`. public var table: (any SQLExpression)? /// Create an ``SQLColumn`` from a name and optional table name. + /// + /// A column name of `*` is treated as ``SQLLiteral/all`` rather than as an identifier. To specify a column whose + /// actual name consists of a sole asterisk (probably not a good idea to have one of those in the first place), + /// use ``init(_:table:)-77d24`` and `SQLIdentifier("*")`. @inlinable public init(_ name: String, table: String? = nil) { - self.init(SQLIdentifier(name), table: table.flatMap(SQLIdentifier.init(_:))) + self.init(name == "*" ? SQLLiteral.all : SQLIdentifier(name), table: table.flatMap(SQLIdentifier.init(_:))) } - /// Create an ``SQLColumn`` from an identifier and optional table identifier. + /// Create an ``SQLColumn`` from an identifier and optional table expression. @inlinable public init(_ name: any SQLExpression, table: (any SQLExpression)? = nil) { self.name = name diff --git a/Tests/SQLKitTests/BasicQueryTests.swift b/Tests/SQLKitTests/BasicQueryTests.swift index feb22ad2..9b4d8bfd 100644 --- a/Tests/SQLKitTests/BasicQueryTests.swift +++ b/Tests/SQLKitTests/BasicQueryTests.swift @@ -10,16 +10,22 @@ final class BasicQueryTests: XCTestCase { // MARK: Select - func testSelect_unqualifiedColums() { + func testSelect_unqualifiedColumns() { XCTAssertSerialization( of: self.db.select() + .column("*") .column("name") + .column(SQLLiteral.all) .column(SQLIdentifier("name")) + .columns("*") .columns("name") + .columns(["*"]) .columns(["name"]) + .columns(SQLLiteral.all) .columns(SQLIdentifier("name")) + .columns([SQLLiteral.all]) .columns([SQLIdentifier("name")]), - is: "SELECT ``name``, ``name``, ``name``, ``name``, ``name``, ``name``" + is: "SELECT *, ``name``, *, ``name``, *, ``name``, *, ``name``, *, ``name``, *, ``name``" ) } diff --git a/Tests/SQLKitTests/SQLExpressionTests.swift b/Tests/SQLKitTests/SQLExpressionTests.swift index 0045d269..6e51740d 100644 --- a/Tests/SQLKitTests/SQLExpressionTests.swift +++ b/Tests/SQLKitTests/SQLExpressionTests.swift @@ -265,4 +265,13 @@ final class SQLExpressionTests: XCTestCase { self.db._dialect.literalStringQuote = SQLQueryString("~") XCTAssertSerialization(of: self.db.raw("\(ident: "hello") \(literal: "there")"), is: "_hello_ ~there~") } + + func testColumns() { + XCTAssertSerialization(of: self.db.raw("\(SQLColumn("*"))"), is: "*") + XCTAssertSerialization(of: self.db.raw("\(SQLColumn(SQLIdentifier("*")))"), is: "``*``") + XCTAssertSerialization(of: self.db.raw("\(SQLColumn(SQLLiteral.all))"), is: "*") + XCTAssertSerialization(of: self.db.raw("\(SQLColumn("*", table: "foo"))"), is: "``foo``.*") + XCTAssertSerialization(of: self.db.raw("\(SQLColumn(SQLIdentifier("*"), table: SQLIdentifier("foo")))"), is: "``foo``.``*``") + XCTAssertSerialization(of: self.db.raw("\(SQLColumn(SQLLiteral.all, table: SQLIdentifier("foo")))"), is: "``foo``.*") + } }