-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
json_extract_path and type/2 #3273
Comments
Thanks for the report, I'll fix it later today. |
This is database behaviour though. When you say type(..., :string), you are actually telling the database to encode that json to string. Since the json is a string, you get a double quoted string. I think a lot of times the combination of type+json is not going to be what people expect, so I wonder if we should forbid mixing them altogether. |
I understand that if I give :string it would stringify it, but If I give it to my custom decoder it too will receive the quoted string. |
Yeah I think that's a good call, I believe to even get a decimal on PG we needed to |
@Hermanverschooten that's my point. You are stringifying a json type. Stringifying a json type is the equivalent to calling JSON.encode! on it, which means you are encoding the string to json. This is not Ecto semantics, this is all Postgres semantics. |
@josevalim I know, but I only took this as an example, my issue was that I have a custom type that will take either a |
What is the fragment variant that works? Which query does it emit? |
|
There is definitely something strange going on, if I do the queries in psql:
They both yield the same result. But ecto interprets them differently. |
I believe it's about the database after all: iex(4)> Postgrex.query!(pid, ~s| select json_extract_path('{"a":"hello"}', 'a'); |, []).rows
[["hello"]]
iex(5)> Postgrex.query!(pid, ~s| select json_extract_path('{"a":"hello"}', 'a')::varchar; |, []).rows
[["\"hello\""]] |
@wojtekmach Have you seen my queries above? They both return the same quoted string. |
Ok, I tried reproducing them: iex(5)> Postgrex.query!(pid, ~s|select '{"a":"hello"}'::json->'a'|, []).rows
[["hello"]]
iex(6)> Postgrex.query!(pid, ~s|select '{"a":"hello"}'::json->'a'::varchar|, []).rows
[["hello"]] So it seems there's a difference in behaviour between |
There is a difference with
|
It seems to be in postgrex:
|
It is not a postgrex issue, it is still PostgreSQL semantics. |
The thing is I am not, |
Type should not interfere with fragments. When you use fragments, it is your responsibility to ensure proper precedence and everything. If we automatically wrap it in parens, we can actually break code and make some constructs impossible, which defeats the purpose of fragments. In any way, the point is:
There is no situation where the casting here can be helpful and that's why I think we should not allow type to be used with json access or json_extract_path. The problem you are trying to solve cannot be addressed with casting. |
I do agree if you would allow the result to be passed to my custom ecto type, because that is what I am aiming for, not the casting at the database level, I would prefer it not to. If |
Or should we have another function to do that? |
Exactly. The functionality that you need is not in Ecto at the moment. The simplest solution for now is to do a separate pass on the selected data and converting it then. |
Environment
Trying to use either form of
json_extract_path
withtype/2
does not work as expected.Current behavior
and with the short form:
Expected behavior
type/2
should either allow both forms or neither.It is also kind of weird that if you omit the
type/2
it returns a plain"2020-11-23"
, but with there are quotes within the quotes"\"2020-11-23\""
, which means that if you use a custom ecto type it will receive the quoted string.The text was updated successfully, but these errors were encountered: