A little confused about horizontal filtering and type casting #1650
-
Server: postgrest/7.0.1 Hello, This is not really a bug, or at least I don't think so. Maybe more a request for more documentation as I'm a little puzzled by the behavior observed. Following the tutorial, I see that this query:
Gets translated to this SQL:
Initially, I was trying to ensure those queries would be valid:
Etc. However the same
I didn't find any documentation regarding this: http://postgrest.org/en/v7.0.0/api.html#horizontal-filtering-rows Could you please clarify this behavior? Thanks. |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments
-
@benjamin-thomas Hey there,
In the The date inputs like now, today, yesterday are special in pg. They're documented here: https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-TABLE. So you can do: select 'tomorrow'::timestamp;
2020-11-17 00:00:00
select 'yesterday'::timestamp;
2020-11-15 00:00:00
pg parsing can look crazy here, but in fact it ignores certain special chars: select ')()()()()tomorrow()()()('::timestamp;
2020-11-17 00:00:00 |
Beta Was this translation helpful? Give feedback.
-
Got you, thanks @steve-chavez. So all incoming input strings are converted to their final type by pg itself. I wouldn't have guessed about its crazy parsing ;) This can lead to surprising results though, at least theoretically:
I gather pgrest uses prepared statements and queries are probably cached? See change log entry: I suppose we should not use those special keywords like
Is that correct? |
Beta Was this translation helpful? Give feedback.
-
@benjamin-thomas Not really, it should be fine to use them through pgrest. The caution in the pg docs, refers to this case: prepare nowstm as select 'now'::timestamptz;
execute nowstm;
2020-11-17 17:47:24.720227-05
execute nowstm;
2020-11-17 17:47:24.720227-05
-- will keep giving the same result In our case, the prepare nowstminput as select $1::timestamptz;
execute nowstminput('now');
2020-11-17 17:57:56.983879-05
execute nowstminput('now');
2020-11-17 17:58:09.186483-05
-- value will keep changing You should avoid using the special date inputs in a function/view definition though. For example: create or replace view nowview as select 'now'::timestamptz; That will give the same value for as long as the view lives. |
Beta Was this translation helpful? Give feedback.
-
Of course, this makes perfect sense now, thanks! Keep up the great work, I find pgrest very interesting :) I'll try to contribute a doc update this week-end, so keeping this open for a bit |
Beta Was this translation helpful? Give feedback.
-
Btw, the curl -X PATCH -H "Prefer: return=representation" -H "Content-Type: application/json" "localhost:80/actor?actor_id=eq.1" -d @- << JSON
{"last_update": "now"}
JSON
[{"actor_id":1,"first_name":"Penelope","last_name":"Guiness","last_update":"2020-12-02T02:29:32.698689"}] Wonder if we should document the special date inputs somewhere. This also looks similar to PostgREST/postgrest-docs#273 in that we take advantage of pg literal representations. |
Beta Was this translation helpful? Give feedback.
-
@steve-chavez I haven't forgotten you. I was planning on proposing a doc update before closing. I think this behavior should definitely be described, and I also think some kind of "best practices" should be mentioned (although slightly out of scope). By that I mean that using those textual representation has some consequences such as dealing with time zone issues, etc. In short, I concluded that they're ok to use, but only if used with In other words, |
Beta Was this translation helpful? Give feedback.
-
I'd really like to see the longer explanation for this :). My gut feeling is that the best way would be to always use timezone, otherwise you might get unexpected results. Do you have an example showing the problem when doing so? |
Beta Was this translation helpful? Give feedback.
-
@wolfgangwalther ok I'll code a little and simple example project showing the different gotchas I'm hinting at. I could be missing something so it'll be interesting to find that out ;) |
Beta Was this translation helpful? Give feedback.
@benjamin-thomas Hey there,
unknown
casting lets pg infer the type based on the context.In the
SELECT 'true'::unknown = true
case, the right operand is a boolean so the left operand is converted to the same type. Thentrue = true
is true.The date inputs like now, today, yesterday are special in pg. They're documented here: https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-TABLE.
So you can do:
pg parsing can look crazy here, but in fact it ignores certain special chars: