-
Notifications
You must be signed in to change notification settings - Fork 108
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
Postgres Materialized CTE functions #354
base: master
Are you sure you want to change the base?
Postgres Materialized CTE functions #354
Conversation
fixes #345 |
aeef50c
to
f65a42d
Compare
Is there a way that we can avoid more postgres specific stuff in the internal module? Since |
we could somehow insert it? the key part i think is:
and the |
Yah so the whole point is to keep that modifier text open for extension. Its obviously less safe from an implementation perspective but who is to say that MySQL won't come out with their own custom modifiers. You have a couple of options here that are all pretty distateful each in their own way.
So to answer your question, yes leaving the modifier as a free for all is kind of icky but the end user won't see it only the implementer. |
f65a42d
to
daec0db
Compare
@belevy thank you for explaining. I think I got it, and have addressed your comments. Let me know if there is anything else to address! |
I ran stylish-haskell on the files that were modified in this PR so I could mark off that check list item, just in case it caused anyone pause. For reference, however, it failed for me on
|
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.
Thank you for moving the postgresql specifics out of Internal. I feel bad requesting more changes, especially after how long I took reviewing. I think we are getting close, perhaps @parsonsmatt has opinions but I feel like with the exception of the few notes I made it seems pretty good.
src/Database/Esqueleto/Experimental/From/CommonTableExpression.hs
Outdated
Show resolved
Hide resolved
-- [Common Table Expression Materialization](https://www.postgresql.org/docs/14/queries-with.html#id-1.5.6.12.7). | ||
-- | ||
-- /Since: 3.5.10.0/ | ||
withMaterialized :: ( ToAlias a |
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.
We probably want to also support non materialized so perhaps the materialization modifier can be passed in as an argument and we can provide helpers materialized
and notMaterialized
to safely select from. In fact, the more general versions could be in the core module and then whether we export with as withInternal noModifier
or withInternal
is whether you use with from the core module or with from this module.
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.
So here was what I was thinking with this PR:
with
, in Database/Esqueleto/Experimental/From/CommonTableExpression.hs, is
usable for any of the sql backends; it doesn't do anything with materialized.- If a postgres user wants to just use regular
with
CTE and have postgres
figure out if it wants to materialize it or not, they can just usewith
from the normal module.
- If a postgres user wants to just use regular
- the
MATERIALIZED
modifier is only supported in postgres, so the ability to
specify this behavior is in the pg specific module.- If a pg user wishes to force pg to materialize the cte, they must import the
pg module and usewithMaterialized
- If a pg user wishes to force pg to materialize the cte, they must import the
- But, besides
MATERIALIZED
, there is also aNOT MATERIALIZED
possible
modifier, which I have not added support for in this version . I can add
it if desired, however, but I'll discuss why I didn't do it below.
Given that, when you say:
We probably want to also support non materialized
Are you referring to when no materialization modifier is specified, or when
the NOT MATERIALIZED
modifier is intended to be used? Either way is fine; it
makes sense to include something that would do NOT MATERIALIZED
, for
completeness.
On the topic of supporting the NOT MATERIALIZED
modifier, here is what my
thought process was:
I saw the following function pattern when investigating this feature:
with
withRecursive
To me, this implied I should add these functions:
withMaterialized
withMaterializedRecursive
But, for NOT MATERIALIZED
, following the pattern would result in even more
functions (and this just seemed like too many):
withNotMaterialized
withNotMaterializedRecursive
So, I didn't add them; totally fine with adding them, I just want to make sure
we're talking about the same thing.
Also, I just re-examined the docs for pg 12-15, and I notice that recursive CTEs are
always "materialized", so withMaterializedRecursive
and
withNotMaterializedRecursive
are superfluous. FYI, according to my tests
with pg 15, all of these combinations actually function, even if they all
actually behave in the same way.
So, given the above, I think the API should be one of these two choices:
- first scenario, I delete
withMaterializedRecursive
and addwithNotMaterialized
- second scenario, add modifiers as arguments
- pg module would have
with
function having two arguments- first argument is
Maybe Materilalization
data Materilization = Materialized | NotMaterialized
- So three possible settings,
None
for providing no materialized modifierJust Materialized
for providingMATERIALIZED
modifierJust NotMaterialized
for providingNOT MATERIALIZED
modifier
- the second argument is
query
, as it is today
- first argument is
withRecursive
is deleted
- the regular
with
function should have the same API as today in Experimental.From.CommonTableExpression.
- pg module would have
Thoughts?
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.
@belevy I went ahead and made this change anyway; to me the alternate implementation seems more confusing. So for users of the library, if they want to use regular CTE, they use with
from esqueleto/src/Database/Esqueleto/Experimental/From/CommonTableExpression.hs
.
If they want the the postgresql specific behavior, they use withMaterialized
and withNotMaterialized
from esqueleto/src/Database/Esqueleto/PostgreSQL.hs
But if you do want it to change, please let me know; i'd like to get this done sooner rather than later
7b2d34d
to
b0ebe5d
Compare
b0ebe5d
to
07dd001
Compare
07dd001
to
4a56932
Compare
Adds
withMaterialized
function to support this non-standard postgres behavior.Before submitting your PR, check that you've:
@since
declarations to the Haddock.stylish-haskell
and otherwise adhered to the style guide.After submitting your PR: