Protocol
SQLExpression
protocol SQLExpression : Sendable
Mentioned in
Overview
SQLExpressions are not well-enough organized in practice to be considered a proper Abstract Syntax Tree representation, but they nonetheless conceptually act as AST nodes. As such, anything which is executed as SQL by an SQLDatabase is represented by a value conforming to SQLExpression - even if that value is an instance of SQLRaw containing arbitrary SQL text.
The single requirement of SQLExpression is the serialize(to:) method, which must output the appropriate raw text, bindings, and/or subexpressions to the provided SQLSerializer when invoked. Most interaction with SQLDialect takes place in the serialization logic of various SQLExpressions - for example, SQLIdentifier uses the identifierQuote of the serializer’s dialect when quoting identifiers (naturally enough). Many SQLExpressions - especially those representing entire SQL queries, such as SQLSelect or SQLCreateTable - function solely as containers of other expressions which are serialized in an appropriate sequence.
See SQLSerializer and serialize(_:) for additional details regarding serialization.
Here is an example of implementing a trivial (and somewhat pointless) SQLExpression:
public struct SQLOptionalExpression<E: SQLExpression>: SQLExpression {
public var subexpression: E?
public init(_ subexpression: E?) {
self.subexpression = subexpression
}
public func serialize(to serializer: inout SQLSerializer) {
if let subexpression = self.subexpression {
subexpression.serialize(to: serializer)
}
}
}
Note
The example expression above treats the type of the “subexpression” it contains generically; this is currently considered best practice whenever possible. However, this pattern is unfortunately not adopted by any of the expressions included in SQLKit itself - instead, the existential type any SQLExpression is used with great abandon. This is, to say the least, not optimal, but as usual with pre-existing public API, it cannot be changed until the next major version bump. The API in its present form was designed back when Swift 5.1 was the current release; the language features needed to usefully handle expressions generically were largely absent before Swift 5.7, and even then it would have been severely limited before the advent of Swift 5.9 and support for variadic generics.
Topics
Instance Methods
serialize(to:)Invoked when a request is made to serialize the expression to raw SQL.
Relationships
Inherits From
Swift.SendableSwift.SendableMetatype
Conforming Types
SQLAliasSQLAlterColumnDefinitionTypeSQLAlterEnumSQLAlterTableSQLBetweenSQLBinaryExpressionSQLBinaryOperatorSQLBindSQLColumnSQLColumnAssignmentSQLColumnConstraintAlgorithmSQLColumnDefinitionSQLCommonTableExpressionSQLCommonTableExpressionGroupSQLConflictResolutionStrategySQLConstraintSQLCreateEnumSQLCreateIndexSQLCreateTableSQLCreateTriggerSQLCreateTrigger.EachSpecifierSQLCreateTrigger.EventSpecifierSQLCreateTrigger.OrderSpecifierSQLCreateTrigger.TimingSpecifierSQLCreateTrigger.WhenSpecifierSQLDataTypeSQLDeleteSQLDirectionSQLDistinctSQLDropBehaviorSQLDropEnumSQLDropIndexSQLDropTableSQLDropTriggerSQLEnumDataTypeSQLExcludedColumnSQLForeignKeySQLForeignKeyActionSQLFunctionSQLGroupExpressionSQLIdentifierSQLInsertSQLInsertModifierSQLJoinSQLJoinMethodSQLListSQLLiteralSQLLockingClauseSQLNestedSubpathExpressionSQLOrderBySQLQualifiedTableSQLQueryStringSQLRawSQLReturningSQLSelectSQLStatementSQLSubquerySQLTableConstraintAlgorithmSQLUnionSQLUnionJoinerSQLUnionSubquerySQLUpdate
See Also
Fundamentals
SQLSerializerEncapsulates the most basic operations for serializingSQLExpressions into a raw SQL string and a (potentially empty) sequence of bound parameter values.SQLStatementAn alternative API for serialization ofSQLExpressions.