From dd19ae9276aff46b78e77d325d91d2e4e8815e8a Mon Sep 17 00:00:00 2001 From: Brandon Williams Date: Tue, 4 Nov 2025 10:13:23 -0600 Subject: [PATCH 1/3] Fix 'map' when calling database functions. --- Package.resolved | 20 +------- Sources/StructuredQueriesCore/Optional.swift | 10 +++- Tests/StructuredQueriesTests/MapTests.swift | 54 ++++++++++++++++++++ 3 files changed, 64 insertions(+), 20 deletions(-) create mode 100644 Tests/StructuredQueriesTests/MapTests.swift diff --git a/Package.resolved b/Package.resolved index 7b6e6951..9102edb5 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "b1e7fc8e75fb3f86eed27972a51c665f7e6482f3058b105c91aee6e1ad0b8018", + "originHash" : "073a03e2259fb84a5096d6021fa10f50c991ddb0c1c292921363371342a4a294", "pins" : [ { "identity" : "combine-schedulers", @@ -10,15 +10,6 @@ "version" : "1.0.3" } }, - { - "identity" : "swift-case-paths", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/swift-case-paths", - "state" : { - "revision" : "6989976265be3f8d2b5802c722f9ba168e227c71", - "version" : "1.7.2" - } - }, { "identity" : "swift-clocks", "kind" : "remoteSourceControl", @@ -100,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/Optional.swift b/Sources/StructuredQueriesCore/Optional.swift index 0788504a..a1d9f56f 100644 --- a/Sources/StructuredQueriesCore/Optional.swift +++ b/Sources/StructuredQueriesCore/Optional.swift @@ -275,7 +275,15 @@ extension QueryExpression where QueryValue: _OptionalProtocol { public func map( _ transform: (SQLQueryExpression) -> some QueryExpression ) -> some QueryExpression { - SQLQueryExpression(transform(SQLQueryExpression(queryFragment)).queryFragment) + SQLQueryExpression( + """ + IIF(\(self), \(transform(SQLQueryExpression(queryFragment))), NULL) + """ + ) + //SQLQueryExpression(transform(SQLQueryExpression(queryFragment)).queryFragment) +// Case(self).when(SQLQueryExpression("NULL"), then: SQLQueryExpression("NULL")).else( +// SQLQueryExpression(transform(SQLQueryExpression(queryFragment)).queryFragment) +// ) } /// Creates a new optional expression from this one by applying an unwrapped version of this diff --git a/Tests/StructuredQueriesTests/MapTests.swift b/Tests/StructuredQueriesTests/MapTests.swift new file mode 100644 index 00000000..a30deabd --- /dev/null +++ b/Tests/StructuredQueriesTests/MapTests.swift @@ -0,0 +1,54 @@ +import Dependencies +import Foundation +import InlineSnapshotTesting +import SQLite3 +import StructuredQueries +import StructuredQueriesSQLite +import StructuredQueriesTestSupport +import Testing +import _StructuredQueriesSQLite + +extension SnapshotTests { + @Suite struct MapTests { + @Dependency(\.defaultDatabase) var database + + @Test func mapWithDatabaseFunction() throws { + $increment.install(database.handle) + try database.execute(""" + CREATE TABLE "optionalIntegers" ( + "value" INTEGER + ) STRICT + """) + try database.execute(""" + INSERT INTO "optionalIntegers" ("value") VALUES (1), (NULL), (3) + """) + + assertQuery( + OptionalInteger.select { + $0.value.map { $increment($0) } + } + ) { + """ + SELECT IIF("optionalIntegers"."value", "increment"("optionalIntegers"."value"), NULL) + FROM "optionalIntegers" + """ + } results: { + """ + ┌─────┐ + │ 2 │ + │ nil │ + │ 4 │ + └─────┘ + """ + } + } + } +} + +@Table struct OptionalInteger { + let value: Int? +} +@DatabaseFunction(isDeterministic: true) +private func increment(_ value: Int) -> Int { + value + 1 +} From 434bc10f4380fde358646251b6e2f5b87ebc314a Mon Sep 17 00:00:00 2001 From: Brandon Williams Date: Tue, 4 Nov 2025 10:14:17 -0600 Subject: [PATCH 2/3] wip --- Sources/StructuredQueriesCore/Optional.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Sources/StructuredQueriesCore/Optional.swift b/Sources/StructuredQueriesCore/Optional.swift index a1d9f56f..6b37535b 100644 --- a/Sources/StructuredQueriesCore/Optional.swift +++ b/Sources/StructuredQueriesCore/Optional.swift @@ -280,10 +280,6 @@ extension QueryExpression where QueryValue: _OptionalProtocol { IIF(\(self), \(transform(SQLQueryExpression(queryFragment))), NULL) """ ) - //SQLQueryExpression(transform(SQLQueryExpression(queryFragment)).queryFragment) -// Case(self).when(SQLQueryExpression("NULL"), then: SQLQueryExpression("NULL")).else( -// SQLQueryExpression(transform(SQLQueryExpression(queryFragment)).queryFragment) -// ) } /// Creates a new optional expression from this one by applying an unwrapped version of this From 1b9c531dd8ac97281da61e591cd0cde72c368821 Mon Sep 17 00:00:00 2001 From: Brandon Williams Date: Tue, 4 Nov 2025 11:00:02 -0600 Subject: [PATCH 3/3] wip --- Sources/StructuredQueriesCore/Optional.swift | 8 +++----- Tests/StructuredQueriesTests/MapTests.swift | 2 +- Tests/StructuredQueriesTests/SelectTests.swift | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Sources/StructuredQueriesCore/Optional.swift b/Sources/StructuredQueriesCore/Optional.swift index 6b37535b..fa0c9c3b 100644 --- a/Sources/StructuredQueriesCore/Optional.swift +++ b/Sources/StructuredQueriesCore/Optional.swift @@ -275,11 +275,9 @@ extension QueryExpression where QueryValue: _OptionalProtocol { public func map( _ transform: (SQLQueryExpression) -> some QueryExpression ) -> some QueryExpression { - SQLQueryExpression( - """ - IIF(\(self), \(transform(SQLQueryExpression(queryFragment))), NULL) - """ - ) + Case(SQLQueryExpression("\(self) IS NULL")) + .when(SQLQueryExpression("1"), then: SQLQueryExpression("NULL")) + .else(SQLQueryExpression(transform(SQLQueryExpression(queryFragment)).queryFragment)) } /// Creates a new optional expression from this one by applying an unwrapped version of this diff --git a/Tests/StructuredQueriesTests/MapTests.swift b/Tests/StructuredQueriesTests/MapTests.swift index a30deabd..5e2242a4 100644 --- a/Tests/StructuredQueriesTests/MapTests.swift +++ b/Tests/StructuredQueriesTests/MapTests.swift @@ -29,7 +29,7 @@ extension SnapshotTests { } ) { """ - SELECT IIF("optionalIntegers"."value", "increment"("optionalIntegers"."value"), NULL) + SELECT CASE "optionalIntegers"."value" IS NULL WHEN 1 THEN NULL ELSE "increment"("optionalIntegers"."value") END FROM "optionalIntegers" """ } results: { diff --git a/Tests/StructuredQueriesTests/SelectTests.swift b/Tests/StructuredQueriesTests/SelectTests.swift index 626ae77c..da0f5146 100644 --- a/Tests/StructuredQueriesTests/SelectTests.swift +++ b/Tests/StructuredQueriesTests/SelectTests.swift @@ -1369,7 +1369,7 @@ extension SnapshotTests { } assertQuery(query) { """ - SELECT ("reminders"."priority") < (3) + SELECT CASE "reminders"."priority" IS NULL WHEN 1 THEN NULL ELSE ("reminders"."priority") < (3) END FROM "reminders" """ } results: {