diff --git a/Package.resolved b/Package.resolved index 279f6581..51ff02b7 100644 --- a/Package.resolved +++ b/Package.resolved @@ -91,15 +91,6 @@ "version" : "602.0.0" } }, - { - "identity" : "swift-tagged", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/swift-tagged", - "state" : { - "revision" : "3907a9438f5b57d317001dc99f3f11b46882272b", - "version" : "0.10.0" - } - }, { "identity" : "xctest-dynamic-overlay", "kind" : "remoteSourceControl", diff --git a/Sources/StructuredQueriesCore/Statements/CommonTableExpression.swift b/Sources/StructuredQueriesCore/Statements/CommonTableExpression.swift index 555681a2..9649c969 100644 --- a/Sources/StructuredQueriesCore/Statements/CommonTableExpression.swift +++ b/Sources/StructuredQueriesCore/Statements/CommonTableExpression.swift @@ -1,6 +1,7 @@ /// Creates a common table expression that can be used to factor subqueries, or create hierarchical /// or recursive queries of trees and graphs. -public struct With: Statement, Sendable { +public struct With: Statement, Sendable { + public typealias QueryValue = Base.QueryValue public typealias From = Never var ctes: [CommonTableExpressionClause] @@ -9,7 +10,7 @@ public struct With: Statement, Sendable { @_disfavoredOverload public init( @CommonTableExpressionBuilder _ ctes: () -> [CommonTableExpressionClause], - query statement: () -> some Statement + query statement: () -> Base ) { self.ctes = ctes() self.statement = statement().query @@ -22,7 +23,21 @@ public struct With: Statement, Sendable { where S.QueryValue == (), S.Joins == (repeat each J), - QueryValue == (S.From, repeat each J) + Base == Select<(S.From, repeat each J), S.From, (repeat each J)> + { + self.ctes = ctes() + self.statement = statement().query + } + + @_disfavoredOverload + public init( + @CommonTableExpressionBuilder _ ctes: () -> [CommonTableExpressionClause], + query statement: () -> S + ) + where + S.QueryValue == (), + S.Joins == (), + Base == Select { self.ctes = ctes() self.statement = statement().query @@ -40,6 +55,8 @@ public struct With: Statement, Sendable { } } +extension With: PartialSelectStatement where Base: PartialSelectStatement {} + extension QueryFragment { fileprivate var presence: Self? { isEmpty ? nil : self } } diff --git a/Sources/StructuredQueriesSQLiteCore/Views.swift b/Sources/StructuredQueriesSQLiteCore/Views.swift index 1bcf85c6..12b38534 100644 --- a/Sources/StructuredQueriesSQLiteCore/Views.swift +++ b/Sources/StructuredQueriesSQLiteCore/Views.swift @@ -7,7 +7,7 @@ extension Table where Self: _Selection { /// - ifNotExists: Adds an `IF NOT EXISTS` clause to the `CREATE VIEW` statement. /// - select: A statement describing the contents of the view. /// - Returns: A temporary trigger. - public static func createTemporaryView( + public static func createTemporaryView( ifNotExists: Bool = false, as select: Selection ) -> TemporaryView @@ -21,7 +21,7 @@ extension Table where Self: _Selection { /// This type of statement is returned from ``Table/createTemporaryView(ifNotExists:as:)``. /// /// To learn more, see . -public struct TemporaryView: Statement +public struct TemporaryView: Statement where Selection.QueryValue == View { public typealias QueryValue = () public typealias From = Never diff --git a/Tests/StructuredQueriesTests/ViewsTests.swift b/Tests/StructuredQueriesTests/ViewsTests.swift index eb6a564a..131df7da 100644 --- a/Tests/StructuredQueriesTests/ViewsTests.swift +++ b/Tests/StructuredQueriesTests/ViewsTests.swift @@ -62,6 +62,34 @@ extension SnapshotTests { """ } } + + @Test func ctes() { + assertQuery( + CompletedReminder.createTemporaryView( + as: With { + Reminder + .where(\.isCompleted) + .select { CompletedReminder.Columns(reminderID: $0.id, title: $0.title) } + } query: { + CompletedReminder.all + } + ) + ) { + """ + CREATE TEMPORARY VIEW + "completedReminders" + ("reminderID", "title") + AS + WITH "completedReminders" AS ( + SELECT "reminders"."id" AS "reminderID", "reminders"."title" AS "title" + FROM "reminders" + WHERE "reminders"."isCompleted" + ) + SELECT "completedReminders"."reminderID", "completedReminders"."title" + FROM "completedReminders" + """ + } + } } } @@ -70,7 +98,3 @@ private struct CompletedReminder { let reminderID: Reminder.ID let title: String } - -extension Table where Self: _Selection { - static func foo() {} -}