Add with_columns/2 to assign column names to fragment sources#4759
Conversation
|
I had talked about it in discord but the reason why You could have some guarantees of some kind or ways to check but that is a pretty deadly footgun if someone changes the schema. I don't think that makes the |
|
Thank you @greg-rychlewski! I think the combination of PS: we may have discussed this already, apologies. |
|
Oh yes I think we could definitely do something like that. I was a bit unsure about it because it would be the only fragment helper that does not have a corresponding ? In the fragment string. Because we need to append it to the table identifier in the adapter (e.g f0 (col1, col2)). I am definitely not against it though because every solution has some kind of drawback. Let me know if I’m misunderstanding what you said though. |
|
Oh sorry I did misunderstand. Your example had it in the fragment string. So if you do it that way then we will get double “as” when the adapter creates the sql. And it could get tricky figuring out if the string has a table identifier/dealing with conflicts in the other autogenerated table names I’m still not against trying it out just letting you know why I opted out of that way |
|
So maybe we introduce it as syntax on |
|
Yeah that was the second main option I was considering seriously. We could call it column_names or something like that. The main thing I didn’t like is that you could not associate the columns right on the source like we do for values. And also I guess we don’t want to allow it outside fragments because the rest of the sources have their names handled automatically. But yeah that one and the one I submitted were the main 2 options I thought had the least drawbacks. I’m ok going with whichever one you like best |
|
One other random thing that popped into my head is introducing something like fragment_source where the second argument has to be the list of columns. I’m not sure it is a good api extension but just thinking of things that could be less subtle and still targeted to fragments |
|
We could support |
|
Yeah I think that would be simple! I’ll push it here so we can see how it looks |
|
@josevalim WDYT? |
| define the column names so that they can be referenced in other | ||
| parts of the query. For example: | ||
|
|
||
| from(f in fragment("select generate_series(?::integer, ?::integer) as x", ^0, ^10), select: f.x) |
There was a problem hiding this comment.
Now I realize the splice_identifier would work like this:
from(f in fragment("select generate_series(?::integer, ?::integer) AS ?", ^0, ^10, splice_identifiers([:x])))
Although I don't know if database performance is worse.
josevalim
left a comment
There was a problem hiding this comment.
I have dropped some suggestions but I also realized there is another way to make it work with splice_identifiers. I have a slight preference for splice_identifiers but I like the current approach if wrapping it in a select has worse perforamnce.
Co-authored-by: José Valim <jose.valim@gmail.com>
Co-authored-by: José Valim <jose.valim@gmail.com>
|
I think we can't guarantee there won't be worse performance across all databases and fragments, but I think it is unlikely to happen. The only thing I could potentially see as an issue is if the subquery was materialized for some reason. But I wasn't able to get that to happen in my own tests or find any examples when searching. I could do
|
|
Now that I think about it there is actually a functional advantage to this way as well. Currently you cannot select the entire source if it is a fragment because we say "what are you talking about, you're a random string i don't know your columns". Having it in the metadata like this we could support it. |
|
Sounds good to me! One last thing, after you mentioned subqueries, to make sure we cover all bases, why not: I am not quite sure I like it myself but it may suit better (or not) the subquery machinery! |
|
Oh sorry I'm not too sure what you were saying sounds good. Keeping |
|
I meant the current PR, "Keeping columns", sounds good! Unless you think the |
|
Oh I get what you meant now. It’s a bit less intuitive to me but I can understand the idea |
|
I committed your review suggestions btw. So all ready to merge if you’re ok with it |
josevalim
left a comment
There was a problem hiding this comment.
Ship it! ❤️
Currently you cannot select the entire source if it is a fragment because we say "what are you talking about, you're a random string i don't know your columns". Having it in the metadata like this we could support it.
Let's give it a try in a subsequent PR to validate this is really the direction we want to go?
|
Yeah definitely :) I should be able today or tomorrow |
In the doc for this function is the rationale for the feature.
I chose to create
with_columns/2instead of adding something like acolumnsoption tofrom/joinbecause I think the main use for this will be inside custom macros and for that it's nicer if it's attached directly to the source. It's also a simpler change.Ecto SQL companion: elixir-ecto/ecto_sql#743