-
-
Notifications
You must be signed in to change notification settings - Fork 22
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
Computing time 'INTERVAL' with postgres #97
Comments
A workaround could be to write the filter as: $filter = ['created_on_datetime > NOW() - \'1 YEAR\'::interval']; But I still have to find how to properly escape it in Pdo when it's parametrized: $filter = ['created_on_datetime > NOW() - \'? YEAR\'::interval', $years]; This give error:
Other tries: $filter = ['created_on_datetime > NOW() - cast(? as interval)', $year.' YEAR']; // OK, but I would like to avoid concat
$filter = ['created_on_datetime > NOW() - cast(\'? DAY\' as interval)', $year]; // FAIL
$filter = ['created_on_datetime > NOW() - cast(concat(?::integer, \' DAY\') as interval)', $year]; // Fail
$filter = ['created_on_datetime > NOW() - cast(concat(cast(?) as integer, \' DAY\') as interval)', $year]; // FAIL
$filter = ['created_on_datetime > NOW() - cast(concat(?, \' DAY\') as interval)', $year]; // FAIL |
use the Date method to encapsulate the expression in a function, that'll skip the qoutation of parameters and fields inside. See duplicate: #28 (comment) |
Thanks for your answer, is `DATE()` an internal cortex keyword? I can't find it in Postgres doc https://www.postgresql.org/docs/9.1/functions-datetime.html
|
it's a SQL function as far as i know |
The best I can get is: $filter = ['created_on_datetime > NOW() - cast(? as interval)', $year.' DAY']; $filter = ['created_on_datetime > DATE(NOW() - INTERVAL ?)', $year.' YEAR']; // FAIL
// PDOStatement: ERROR: syntax error at or near "$1" LINE 1: ...ERE "created_on_datetime" > DATE(NOW() - INTERVAL $1) ORDER ... ^
$filter = ['created_on_datetime > DATE(NOW() - INTERVAL \'? YEAR\')', $year]; // FAIL
// PDOStatement: ERROR: invalid input syntax for type interval: "? YEAR" LINE 1: ...ERE "created_on_datetime" > DATE(NOW() - INTERVAL '? YEAR') ... ^ |
seems like the DATE function is not available for postgre. Try this one for postgre: $filter = ["created_on_datetime > date_trunc('second', INTERVAL '? YEAR')", $year];
// or begin without parameter, since I'm not sure about where to put that atm without testing
$filter = ["created_on_datetime > date_trunc('second', INTERVAL '1 YEAR')"]; |
$filter = ["created_on_datetime > date_trunc('second', INTERVAL '? YEAR')", GK_SITE_NEWS_DISPLAY_DAYS_VALIDITY];
// PDOStatement: ERROR: invalid input syntax for type interval: "? YEAR" LINE 1: ...ated_on_datetime" > date_trunc('second', INTERVAL '? YEAR') ... ^
$filter = ["created_on_datetime > date_trunc('second', INTERVAL '1 YEAR')"];
// PDOStatement: ERROR: operator does not exist: timestamp with time zone > interval LINE 1: ...etime" FROM "gk_news" WHERE "created_on_datetime" > date_tru... ^ HINT: No operator matches the given name and argument types. You might need to add explicit type casts. |
That's good! See the hint:
I'm not sure what type your |
Despite of this workaround.. it seem more complicated in postgre than other engine.. maybe i should just add an option somehow to display automatic field quotation for specific parts of the query?! |
We missed the $filter = ["created_on_datetime > NOW() - date_trunc('second', INTERVAL '1 YEAR')"];
// Works, but not with '? YEAR' - seems related to Pdo
$filter = ["created_on_datetime > NOW() - date_trunc('second', INTERVAL '? YEAR')", GK_SITE_NEWS_DISPLAY_DAYS_VALIDITY];
// PDOStatement: ERROR: invalid input syntax for type interval: "? YEAR" LINE 1: ...datetime" > NOW() - date_trunc('second', INTERVAL '? YEAR') ... ^ My best option right now still seems to be $filter = ['created_on_datetime > NOW() - cast(? as interval)', GK_SITE_NEWS_DISPLAY_DAYS_VALIDITY.' DAY']; How would the option be used, would it be a list of keywords to not quote? |
Could it be that the NOW() need to be set within the function? |
@ikkez thanks for yor help. We're getting quite close to something "usable"/"clean". This syntax may work with a little update to the library. $filter = ["created_on_datetime > NOW() - CAST(? || ' YEAR' as INTERVAL)", GK_SITE_NEWS_DISPLAY_DAYS_VALIDITY]; But problem here is that
Problem is there: Line 2585 in 364caaa
This substitution have to be conditioned to the driver used. I've tried to workaround it without updating $filter = ["created_on_datetime > NOW() - CAST(CONCAT(?, ' YEAR') AS INTERVAL)", GK_SITE_NEWS_DISPLAY_DAYS_VALIDITY];
// PDOStatement: ERROR: could not determine data type of parameter $1
$filter = ["created_on_datetime > NOW() - CAST(CONCAT(CAST(? AS INTEGER), ' YEAR') AS INTERVAL)", GK_SITE_NEWS_DISPLAY_DAYS_VALIDITY];
// PDOStatement: ERROR: syntax error at or near ""AS"" LINE 1: ...NOW() - CAST(CONCAT(CAST($1 AS INTEGER), ' YEAR') "AS" "INTE... ^ I start wondering why this auto quoting is there, what are the use case behind it? |
Oh! I may simply follow the doc! I'll test that…
Edit: OK it fix the example from my first post, but to have it dynamic, bind only one @ikkez Would you a dedicated issue for the |
An approach is to use CREATE OR REPLACE FUNCTION public.fresher_than(
datetime timestamp with time zone,
duration integer,
unit character varying)
RETURNS boolean
LANGUAGE 'plpgsql'
AS $BODY$BEGIN
RETURN datetime > NOW() - CAST(duration || ' ' || unit as INTERVAL);
END;$BODY$; And use it as: $filter = ["fresher_than(created_on_datetime, ?, 'YEAR')", $years]; This is fine for me, @ikkez you may close the issue if you wish 👍 Note: a view would probably had success there too. |
I'm having troubles selecting rows based on datetime calculation on a Postgres database.
The query I'm trying to build looks like:
A simple code example to reproduce could be:
From the debug lines I've added to the cortex code, the generated query is:
Note the double quotes added automatically around the
INTERVAL
keyword. (Without them the query works fine.Those leads to the Postgres error:
I've tracked the quotes adder down to the function
sql_quoteCondition()
f3-cortex/lib/db/cortex.php
Lines 2683 to 2706 in 364caaa
Here is a regex101 fork, were we clearly see the
INTERVAL
captured as acolumn
name.https://regex101.com/r/AP2mRH/1
I'm on:
I hope this one will not give you more sleepless nights 😉
The text was updated successfully, but these errors were encountered: