-
Notifications
You must be signed in to change notification settings - Fork 39
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
Simplify eval
to run directly inside the Query
monad
#56
Conversation
c0e3bf5
to
1598e38
Compare
@ocharles I'm quite confident that I have something now that will always give the expected results. |
b6b7fb3
to
919b614
Compare
rebind :: Table Expr a => a -> Query a | ||
rebind a = Query $ \_ -> Opaleye.QueryArr $ \(_, query, tag) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you document what this is doing? As it occurs after laterally
, it seems to kind of "undo" the need for lateral joins (as they've already served their purpose), so we go back to letting PostgreSQL do its thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what you mean. This is what makes it so that if you do (\x -> (x, x)) <$> evaluate (nextval "user_id_seq")
, both your x
s will have the same value. This is orthogonal to laterally
which adds the superfluous lateral references.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment anyway
@tomjaguarpaw at ZuriHac questioned whether the `Evaluation` monad was really unnecessary. And yes, it turns out that the `Evaluation` monad wasn't actually really adding any value. The real issue was Postgres's unspecified evaluation order (which in practice behaved like the broken `ListT` from transformers). We now maintain a stack of bindings from previous subselects in the `Query` monad, which future queries can reference. So for `evalulation`, to ensure that Postgres doesn't try to run a function once where we expect it to be run multiple times, we modify the expression to contain a bunch of superfluous lateral references to the previous queries. This ensures that it gets run every time.
@tomjaguarpaw pointed out at ZuriHac that the
Evaluation
monad is entirely unnecessary. I've tested this change and it seems to still do what I want it to do. Not sure why I ever thought it was necessary!