-
Notifications
You must be signed in to change notification settings - Fork 36
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
Crashing query: Incorrectly capturing variables #19
Comments
I think a |
@ocharles I agree. |
I can confirm that this query works: SELECT ALL T0.f0 AS f0, T2.f0 AS f1 FROM (SELECT ALL 0 AS f0) T0
INNER JOIN LATERAL (SELECT ALL T1.f0 AS f0 FROM (SELECT ALL 0 AS f0) T1
WHERE (T0.f0 = T1.f0)) T2 ON (0=0); |
NB Not all flavours of SQL support something equivalent to |
OK. Does this mean a monadic interface can be given sensible semantics for the SQL+ |
As I understand it |
I just realised this has nothing to do with aggregation! I changed the title accordingly. |
@tomjaguarpaw Would you tell me that how the arrow interface of Opaleye prevent this issue? So far, I understand that the arrow interface of Opaleye is equivalent to a state monad. I must misunderstand something. |
The arrow interface of Opaleye is not equivalent to a state monad. The implementation of Opaleye's The problem with relational-record in this particular case seems to be that you can apply relation :: QuerySimple (Projection Flat r) -> Relation () r in the code captureVariable i = relation $ do
...
relation :: QuerySimple () (Projection Flat r) -> Relation () r In order to achieve the desired effect you would have to limit yourself to only arrow operations on relation :: QuerySimple a (Projection Flat r) -> Relation a r In Opaleye I believe we have the invariant that a value I'm afraid I can't say much more about relational-record because I don't really understand the setup of |
Not to derail the conversation too much but I still think HOAS or something
|
I'm skeptical than HOAS is related, since this is not your common or garden
lambda-calculus-style variable-capture problem, but if you can make anything
of that I would be delighted!
|
HOAS isn't very good at limiting what part of the context can be captured
by a closure, so I'm not sure how it would help here. In fact that's one of
the reasons why adequacy does not hold for many HOAS encodings. This is in
contrast with environment indexed de bruijn encodings, which are quite good
at that (but a royal pain in other regards).
However, given the existence of `LATERAL`, and the assumption that the SQL
query optimizer will do just as good a job at finding an efficient plan as
it otherwise would without that keyword where it is not necessary, is
making the expressive power of the interface weaker a problem worth solving?
|
I don't think it's an easy decision to make in the general case. LATERAL is
not standard SQL. It is available in Postgres, but only since 9.4, i.e. in
the last 6 months. Other SQL RDBMSes may have an equivalent, but I don't
think all do.
I won't be adding support for LATERAL into Opaleye until 9.4 is old, because
I know I have users who are not currently prepared to upgrade.
relational-record may take a different point of view.
|
When passing projections into a query-building monad This example suggests that this problem occurs not only when projections It is easy to implement an Arrow wrapper for HRR. When using this wrapper, the Arrow expression scope (between In Opaleye, passing columns (which correspond to HRR projections) to the HRR can express each ON clause and UNION like(UNION, EXCEPT, INTERSECT) operations, I do not yet have a good idea for how to solve this issue. |
To be fair, we would like to include the ON vs WHERE issue in our HRR paper. That is, SQL generated by HRR is simpler but its type-safety is weaker than that of Opaleye. |
It may be possible to lift up and to combine |
Having used HaskellDB for a couple years I can add my 2¢ that I don't care about looking at the generated SQL as long as it's correct, so prioritizing readability over correctness is not an aim I'd go for. |
But what about performance? I heard that complex SQL statements generated by HaskellDB are slow with MySQL. |
With MySQL, yes. I admit I don't care at all about anything other than PostgreSQL. |
:-) |
@tomjaguarpaw Thanks for reporing this issue. I added an arrow-combinator module 'Database.Relational.Query.Arrow' to import the idea of Opaleye! Building queries using combinators imported from 'Database.Relational.Query.Arrow' Combinator implementations are involved in I think using this new module makes relational-record safer on the same level with Opaleye. |
SQL does not allow the right-hand clause of an INNER JOIN to reference columns defined in the left-
hand clause. However, relational-record does not enforce this restriction in the type system. It is trivial to create a well-typed yet crashing query:
The generated SQL is
and Postgres reports
NB this is why Opaleye uses a query arrow arrow instead of a query monad.
The text was updated successfully, but these errors were encountered: