stephencelis / SQLite.swift

A type-safe, Swift-language layer over SQLite3.
MIT License
9.72k stars 1.57k forks source link

table not found when calling select(table[*]) #756

Closed danielmatzke closed 3 years ago

danielmatzke commented 6 years ago

Hello,

after upgrading a project to the latest version of Swift and SQLite.swift, several test cases in the app failed. Having a closer look into it I see identical code behaves different with different versions of SQLite, where the newer version throws an exception. I suspect that this problem is related to SQLite.swift itself. While I cannot publish the entire project, here are logs from the app before and after upgrading.

This test code is identical for both versions, however the behaviour is different:

print("----------------------------------")
let query1 = paintings.table
    .filter(paintings.table[paintings.id] == paintingId)
let items1 = try db.prepare(query1)
print("1: \(query1.asSQL())")
let i1 = items1.map { $0 }
print("\(i1)")

print("----------------------------------")
let query2 = paintings.table
    .filter(paintings.table[paintings.id] == paintingId)
    .join(self.table, on: paintings.table[paintings.locationId] == table[self.id])
let items2 = try db.prepare(query2)
print("2: \(query2.asSQL())")
let i2 = items2.map { $0 }
print("\(i2)")

print("----------------------------------")
let query3 = paintings.table
    .filter(paintings.table[paintings.id] == paintingId)
    .join(self.table, on: paintings.table[paintings.locationId] == self.table[self.id])
    .select(distinct: self.table[*])
print("3: \(query3.asSQL())")
//swiftlint:disable:next force_try
let items3 = try! db.prepare(query3)
let i3 = items3.map { $0 }
print("\(i3)")

print("----------------------------------")

Here is the output from the swift-2.3 version (a):

----------------------------------
1: SELECT * FROM "Paintings" WHERE ("Paintings"."id" = '493C5180-EE3B-4870-99C1-52CD69CCCD4C')
[SQLite.Row(columnNames: ["\"artistId\"": 11, "\"locationId\"": 12, "\"id\"": 0, "\"latitude\"": 5, "\"copyright\"": 9, "\"exhibitionRoom\"": 4, "\"longitude\"": 6, "\"positionInEpoch\"": 8, "\"positionInTopic\"": 7, "\"originalTitle\"": 1, "\"fileName\"": 2, "\"yearOfCreation\"": 3, "\"topicId\"": 13, "\"epochId\"": 14, "\"exhibitionId\"": 10], values: [Optional("493C5180-EE3B-4870-99C1-52CD69CCCD4C"), Optional("Some fancy title"), Optional("somePath"), Optional("1996"), Optional("1A3"), Optional(48.853414999999998), Optional(2.348805), Optional(1), nil, Optional("Musee du Louvre"), Optional("B2A3E1C5-9107-4BA4-8ED0-A6FBBFF759DB"), Optional("E6603141-7A13-4BF2-BE69-20AE36036479"), Optional("A14627BD-9BC3-456C-A21A-F38BCFA69E7F"), Optional("7D3B36F5-700C-4FE9-A60D-E5A934783232"), Optional("A3F590F7-0527-4C26-A063-FD07B9A01FF3")])]
----------------------------------
2: SELECT * FROM "Paintings" INNER JOIN "Locations" ON ("Paintings"."locationId" = "Locations"."id") WHERE ("Paintings"."id" = '493C5180-EE3B-4870-99C1-52CD69CCCD4C')
[SQLite.Row(columnNames: ["\"Paintings\".\"id\"": 0, "\"Locations\".\"fileName\"": 17, "\"Paintings\".\"longitude\"": 6, "\"Locations\".\"countryId\"": 21, "\"Paintings\".\"positionInEpoch\"": 8, "\"Paintings\".\"exhibitionRoom\"": 4, "\"Paintings\".\"locationId\"": 12, "\"Locations\".\"regionId\"": 22, "\"Paintings\".\"yearOfCreation\"": 3, "\"Paintings\".\"exhibitionId\"": 10, "\"Paintings\".\"topicId\"": 13, "\"Locations\".\"latitude\"": 18, "\"Paintings\".\"fileName\"": 2, "\"Locations\".\"name\"": 16, "\"Paintings\".\"positionInTopic\"": 7, "\"Paintings\".\"originalTitle\"": 1, "\"Locations\".\"longitude\"": 19, "\"Locations\".\"recommendedMapZoomLevel\"": 20, "\"Paintings\".\"artistId\"": 11, "\"Paintings\".\"epochId\"": 14, "\"Paintings\".\"copyright\"": 9, "\"Locations\".\"id\"": 15, "\"Paintings\".\"latitude\"": 5], values: [Optional("493C5180-EE3B-4870-99C1-52CD69CCCD4C"), Optional("Some fancy title"), Optional("somePath"), Optional("1996"), Optional("1A3"), Optional(48.853414999999998), Optional(2.348805), Optional(1), nil, Optional("Musee du Louvre"), Optional("B2A3E1C5-9107-4BA4-8ED0-A6FBBFF759DB"), Optional("E6603141-7A13-4BF2-BE69-20AE36036479"), Optional("A14627BD-9BC3-456C-A21A-F38BCFA69E7F"), Optional("7D3B36F5-700C-4FE9-A60D-E5A934783232"), Optional("A3F590F7-0527-4C26-A063-FD07B9A01FF3"), Optional("A14627BD-9BC3-456C-A21A-F38BCFA69E7F"), Optional("Paris"), Optional("parisThumb.jpg"), Optional(48.853409999999997), Optional(2.3488000000000002), Optional(14), Optional("24268F6E-D7FA-4FB2-852F-9AFB0285B6E0"), Optional("91C90ED3-E726-4F61-A308-A60C73343E42")])]
----------------------------------
3: SELECT DISTINCT "Locations".* FROM "Paintings" INNER JOIN "Locations" ON ("Paintings"."locationId" = "Locations"."id") WHERE ("Paintings"."id" = '493C5180-EE3B-4870-99C1-52CD69CCCD4C')
[SQLite.Row(columnNames: ["\"Locations\".\"fileName\"": 2, "\"Locations\".\"countryId\"": 6, "\"Locations\".\"name\"": 1, "\"Locations\".\"longitude\"": 4, "\"Locations\".\"recommendedMapZoomLevel\"": 5, "\"Locations\".\"id\"": 0, "\"Locations\".\"regionId\"": 7, "\"Locations\".\"latitude\"": 3], values: [Optional("A14627BD-9BC3-456C-A21A-F38BCFA69E7F"), Optional("Paris"), Optional("parisThumb.jpg"), Optional(48.853409999999997), Optional(2.3488000000000002), Optional(14), Optional("24268F6E-D7FA-4FB2-852F-9AFB0285B6E0"), Optional("91C90ED3-E726-4F61-A308-A60C73343E42")])]

Here is the test output from the master version (b) ::

----------------------------------
1: SELECT * FROM "Paintings" WHERE ("Paintings"."id" = '5068054D-88C6-4712-AD73-060880AB9945')
[SQLite.Row(columnNames: ["\"positionInEpoch\"": 8, "\"locationId\"": 12, "\"originalTitle\"": 1, "\"yearOfCreation\"": 3, "\"latitude\"": 5, "\"artistId\"": 11, "\"exhibitionId\"": 10, "\"id\"": 0, "\"fileName\"": 2, "\"positionInTopic\"": 7, "\"copyright\"": 9, "\"exhibitionRoom\"": 4, "\"longitude\"": 6, "\"epochId\"": 14, "\"topicId\"": 13], values: [Optional("5068054D-88C6-4712-AD73-060880AB9945"), Optional("Some fancy title"), Optional("somePath"), Optional("1996"), Optional("1A3"), Optional(48.853414999999998), Optional(2.348805), Optional(1), nil, Optional("Musee du Louvre"), Optional("3BEF5106-D2AE-49D2-9027-851CC9012C59"), Optional("F9AAF2C0-57D5-4718-BE57-36442836AEB2"), Optional("D2CC1763-8B90-433F-AAC9-DBE41813482C"), Optional("605EECF1-591A-4422-AAA5-B7892DC7CA64"), Optional("F01CD6D9-52AD-4E2E-88AD-CF10C4F23AAF")])]
----------------------------------
2: SELECT * FROM "Paintings" INNER JOIN "Locations" ON ("Paintings"."locationId" = "Locations"."id") WHERE ("Paintings"."id" = '5068054D-88C6-4712-AD73-060880AB9945')
[SQLite.Row(columnNames: ["\"Paintings\".\"exhibitionRoom\"": 4, "\"Paintings\".\"positionInEpoch\"": 8, "\"Paintings\".\"locationId\"": 12, "\"Locations\".\"id\"": 15, "\"Locations\".\"longitude\"": 19, "\"Locations\".\"regionId\"": 22, "\"Paintings\".\"positionInTopic\"": 7, "\"Paintings\".\"topicId\"": 13, "\"Paintings\".\"epochId\"": 14, "\"Paintings\".\"artistId\"": 11, "\"Locations\".\"countryId\"": 21, "\"Paintings\".\"id\"": 0, "\"Paintings\".\"originalTitle\"": 1, "\"Paintings\".\"fileName\"": 2, "\"Paintings\".\"copyright\"": 9, "\"Locations\".\"recommendedMapZoomLevel\"": 20, "\"Locations\".\"name\"": 16, "\"Paintings\".\"yearOfCreation\"": 3, "\"Paintings\".\"longitude\"": 6, "\"Paintings\".\"latitude\"": 5, "\"Locations\".\"latitude\"": 18, "\"Paintings\".\"exhibitionId\"": 10, "\"Locations\".\"fileName\"": 17], values: [Optional("5068054D-88C6-4712-AD73-060880AB9945"), Optional("Some fancy title"), Optional("somePath"), Optional("1996"), Optional("1A3"), Optional(48.853414999999998), Optional(2.348805), Optional(1), nil, Optional("Musee du Louvre"), Optional("3BEF5106-D2AE-49D2-9027-851CC9012C59"), Optional("F9AAF2C0-57D5-4718-BE57-36442836AEB2"), Optional("D2CC1763-8B90-433F-AAC9-DBE41813482C"), Optional("605EECF1-591A-4422-AAA5-B7892DC7CA64"), Optional("F01CD6D9-52AD-4E2E-88AD-CF10C4F23AAF"), Optional("D2CC1763-8B90-433F-AAC9-DBE41813482C"), Optional("Paris"), Optional("parisThumb.jpg"), Optional(48.853409999999997), Optional(2.3488000000000002), Optional(14), Optional("E9A45D60-34BF-475E-A721-84325A97773A"), Optional("F64674A9-D311-4E58-B7BC-A2DD01C91911")])]
----------------------------------
3: SELECT DISTINCT "Locations".* FROM "Paintings" INNER JOIN "Locations" ON ("Paintings"."locationId" = "Locations"."id") WHERE ("Paintings"."id" = '5068054D-88C6-4712-AD73-060880AB9945')
Fatal error: 'try!' expression unexpectedly raised an error: No such table: "Locations": file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.69.2/src/swift/stdlib/public/core/ErrorType.swift, line 181

The exception is thrown when query3 is executed, which adds the part .select(distinct: table[*]). As far as I see it, the output of query2 is identical (except for GUIDs and column ordering). Therefore I suspect that this issue is related to the upgrade in SQLite.

Build Information

danielmatzke commented 6 years ago

Note that the code works fine, when replacing the line

.select(distinct: self.table[*])

with explicit column names

.select(distinct: self.table[self.id], self.table[self.name], self.table[self.fileName],
        self.table[self.latitude], self.table[self.longitude], self.table[self.recommendedMapZoomLevel],
        self.table[self.countryId], self.table[self.regionId])

(where self.id equals Expression<String>("id") and so on)

jberkel commented 3 years ago

does this still apply to 0.13.0? If yes, please reopen