Support tuples in filter expressions#2344
Conversation
|
Hello, @JakeBecker! This is your first Pull Request that will be reviewed by Ebert, an automatic Code Review service. It will leave comments on this diff with potential issues and style violations found in the code as you push new commits. You can also see all the issues found on this Pull Request on its review page. Please check our documentation for more information. |
Would that be actually valid in Postgres? Or, to go a bit deeper, how would we encode tuples in Postgrex? /cc @ericmj |
| :utc_datetime | :naive_datetime | :date | :time | :any | | ||
| :utc_datetime_usec | :naive_datetime_usec | :time_usec | ||
| @typep composite :: {:array, t} | {:map, t} | {:embed, Ecto.Embedded.t} | {:in, t} | ||
| @typep composite :: {:array, t} | {:map, t} | {:embed, Ecto.Embedded.t} | {:in, t} | {:tuple, [t]} |
There was a problem hiding this comment.
We should probably handle this in the planner as we don't want to expose the tuple type to users. For example, we don't want to allow field :foo, {:tuple, [:integer, :integer]}.
There was a problem hiding this comment.
Is this different from :in? I assumed that in was just for x.some_field in ^arr, and that tuple could behave similarly in that neither should be used for an actual field type.
In postgrex we can decode anonymous composite types to tuples because we have type information for each element in the composite. We cannot encode anonymous composites because when encoding we dont have type information for each element. If the composite type is named, for example a table type, we can encode it but you would have to be explicit with a type cast because postgres can usually not infer composite types. So in short, no we cant. |
|
I'm still fuzzy on the type system in Postgrex and on Postgres's binary protocol. Is a tuple significantly different from other parameters? In either case, we can often determine at compile time the type. In Is an anonymous tuple possible to encode like this? I took a brief stab at this but I was stymied by the type system with |
|
Okay, I think I get it. Postgrex gets a |
|
@JakeBecker How does it work for MySQL? It just works? |
|
Nope, doesn't seem to work there either. When I try to execute a query with an expression like |
|
@JakeBecker so probably we just can't accept it, which I think makes this way less useful? |
|
I notice that if you do an expression like Something like that might work for tuples too. I'm not sure where that transformation happens though. |
|
@JakeBecker then I would rather force developers to use |
|
Using |
|
Okay, I undid those changes. |
|
This looks great @JakeBecker! Can we have a test in filter_test or in planner_test that shows we raise a reasonably good message if someone tries |
… a tuple of equal size
|
❤️ 💚 💙 💛 💜 |
MySQL and Postgres support tuple comparisons, as discussed in this mailing list thread: https://groups.google.com/forum/#!topic/elixir-ecto/M5P7RYHg5FU
I've taken a stab at adding support for tuple syntax in queries, so you can do things like
where([a], {a.x, a.y} > {^foo,^bar}). It should handle casting parameters correctly.One thing I was not able to do was to make it accept parameters that are tuples. I think it'd be nice if it could do this, so you could do something like
{a.x,a.y} > ^cursor, but I found the type system in Postgrex particularly hard to make sense of. I could use some help from someone more experienced with it to make that work.Please review. Thanks!