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

Simplify eval to run directly inside the Query monad #56

Merged
merged 1 commit into from
Jun 22, 2021

Conversation

shane-circuithub
Copy link
Contributor

@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!

@shane-circuithub
Copy link
Contributor Author

@ocharles I'm quite confident that I have something now that will always give the expected results.

Comment on lines +54 to +58
rebind :: Table Expr a => a -> Query a
rebind a = Query $ \_ -> Opaleye.QueryArr $ \(_, query, tag) ->
Copy link
Contributor

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.

Copy link
Contributor Author

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 xs will have the same value. This is orthogonal to laterally which adds the superfluous lateral references.

Copy link
Contributor Author

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants