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..fa0c9c3b 100644 --- a/Sources/StructuredQueriesCore/Optional.swift +++ b/Sources/StructuredQueriesCore/Optional.swift @@ -275,7 +275,9 @@ extension QueryExpression where QueryValue: _OptionalProtocol { public func map( _ transform: (SQLQueryExpression) -> some QueryExpression ) -> some QueryExpression { - SQLQueryExpression(transform(SQLQueryExpression(queryFragment)).queryFragment) + 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 new file mode 100644 index 00000000..5e2242a4 --- /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 CASE "optionalIntegers"."value" IS NULL WHEN 1 THEN NULL ELSE "increment"("optionalIntegers"."value") END + FROM "optionalIntegers" + """ + } results: { + """ + ┌─────┐ + │ 2 │ + │ nil │ + │ 4 │ + └─────┘ + """ + } + } + } +} + +@Table struct OptionalInteger { + let value: Int? +} +@DatabaseFunction(isDeterministic: true) +private func increment(_ value: Int) -> Int { + value + 1 +} 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: {