Skip to content

Simplify eval to run directly inside the Query monad#56

Merged
shane-circuithub merged 1 commit intomasterfrom
eval
Jun 22, 2021
Merged

Simplify eval to run directly inside the Query monad#56
shane-circuithub merged 1 commit intomasterfrom
eval

Conversation

@shane-circuithub
Copy link
Copy Markdown
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
Copy Markdown
Contributor Author

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

@shane-circuithub shane-circuithub force-pushed the eval branch 2 times, most recently from b6b7fb3 to 919b614 Compare June 21, 2021 23:08
Comment on lines +54 to +58
rebind :: Table Expr a => a -> Query a
rebind a = Query $ \_ -> Opaleye.QueryArr $ \(_, query, tag) ->
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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