Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQLInterpolation could not work with QueryInterfaceRequest #697

Closed
ryohji opened this issue Feb 7, 2020 · 3 comments
Closed

SQLInterpolation could not work with QueryInterfaceRequest #697

ryohji opened this issue Feb 7, 2020 · 3 comments
Labels

Comments

@ryohji
Copy link

ryohji commented Feb 7, 2020

What did you do?

I wrote the query (with GRDB 4.8.0), to select the color value from inner joined table:

try String.fetchOne(db, SQLRequest<String>("""
WITH
  Id(id) AS (SELECT id FROM TaggedItem WHERE itemId=\(itemId))
  Color(id,value) AS (SELECT id,value FROM TagMeta WHERE name="color")
SELECT value FROM Id
INNER JOIN Color USING(id)
INNER JOIN Tag USING(id)
ORDER BY Tag.priority
"""))

What did you expect to happen?

In the query above, there are two subqueries. I have TaggedItem and TagMeta struct, which conforms to both of PersistableRecord and FetchableRecord.
So, it looks pretty to replace the subquery such as TaggedItem.filter(Column("itemId") == itemId).

But SQLInterpolation does not accept QueryInterfaceRequest (such as TaggedItem.filter(...)), so I can not write the code such as:

try String.fetchOne(db, SQLRequest<String>("""
WITH
  Id(id) AS \(TaggedItem.filter(Column("itemId") == itemId))
...

What happened instead?

Xcode shows the error: "Instance method 'appendInterpolation' requires that 'QueryInterfaceRequest' conform to 'SQLExpressible'".

I know, your document said there is no support for QueryInterfaceRequest.

If there is more neat way to code, please let me know.
Thank you!

Environment

GRDB flavor(s): GRDB
GRDB version: 4.8.0
Installation method: CocoaPods
Xcode version: 11.2
Swift version: 5
Platform(s) running GRDB: iOS
macOS version running Xcode: 10.15.3

@groue
Copy link
Owner

groue commented Feb 7, 2020

Hello @ryohji

But SQLInterpolation does not accept QueryInterfaceRequest

This is true. You can't embed a query interface request in an SQL literal.

I hope to lift this limitation one day. #690 is actually one step in this direction.

The work that needs to be achieved is to turn SQLLiteral into a promise for SQL, just like query interface requests are. A promise for SQL is a value that can't emit any SQL until a database connection is available. For example, Player.filter(key: 1) can't emit any SQL until we can access the database, introspect the primary key of the players' table, and eventually produce SELECT * FROM player WHERE id = 1.

Currently SQLLiteral is not a promise. It can give you SQL without any database connection. And that's why it can't embed query interface requests. You have to pick another technique.

@groue groue added the support label Feb 7, 2020
@ryohji
Copy link
Author

ryohji commented Feb 7, 2020

@groue I got it! thank you!

@ryohji ryohji closed this as completed Feb 7, 2020
@groue groue mentioned this issue Mar 8, 2020
42 tasks
@groue groue mentioned this issue Apr 29, 2020
@groue groue changed the title SQLInterpolation could not works with QueryInterfaceRequest SQLInterpolation could not work with QueryInterfaceRequest May 1, 2020
@groue
Copy link
Owner

groue commented May 2, 2020

You can embed query interface requests in SQL literals with GRDB 5.0.0-beta

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants