Skip to content

Computing time 'INTERVAL' with postgres #97

@kumy

Description

@kumy

I'm having troubles selecting rows based on datetime calculation on a Postgres database.

The query I'm trying to build looks like:

SELECT *
FROM "news"
WHERE "created_on_datetime" > NOW()- INTERVAL '1 YEAR'
ORDER BY "created_on_datetime" DESC;

A simple code example to reproduce could be:

        $newsModel = new News();
        $filter = ['created_on_datetime > NOW() - INTERVAL \'1 YEAR\''];
        $news = $newsModel->find($filter);

From the debug lines I've added to the cortex code, the generated query is:

SELECT "id","title","content","author","created_on_datetime" FROM "news" WHERE "created_on_datetime" > NOW() - "INTERVAL" '1 YEAR'

Note the double quotes added automatically around the INTERVAL keyword. (Without them the query works fine.
Those leads to the Postgres error:

Error in query (7): ERROR: type "INTERVAL" does not exist
LINE 1: ...M "news" WHERE "created_on_datetime" > NOW() - "INTERVAL"...

I've tracked the quotes adder down to the function sql_quoteCondition()

f3-cortex/lib/db/cortex.php

Lines 2683 to 2706 in 364caaa

/**
* quote identifiers in condition
* @param string $cond
* @param object $db
* @return string
*/
public function sql_quoteCondition($cond, $db) {
// https://www.debuggex.com/r/6AXwJ1Y3Aac8aocQ/3
// https://regex101.com/r/yM5vK4/1
// this took me lots of sleepless nights
$out = preg_replace_callback('/'.
'\w+\((?:(?>[^()]+)|\((?:(?>[^()]+)|^(?R))*\))*\)|'. // exclude SQL function names "foo("
'(?:(\b(?<!:)'. // exclude bind parameter ":foo"
'[a-zA-Z_](?:[\w\-_.]+\.?))'. // match only identifier, exclude values
'(?=[\s<>=!)]|$))/i', // only when part of condition or within brackets
function($match) use($db) {
if (!isset($match[1]))
return $match[0];
if (preg_match('/\b(AND|OR|IN|LIKE|NOT|HAVING|SELECT|FROM|WHERE)\b/i',$match[1]))
return $match[1];
return $db->quotekey($match[1]);
}, $cond);
return $out ?: $cond;
}

Here is a regex101 fork, were we clearly see the INTERVAL captured as a column name.
https://regex101.com/r/AP2mRH/1

I'm on:

/**
 *  Cortex - the flexible data mapper for the PHP Fat-Free Framework
 *  […]
 *  @package DB
 *  @version 1.6.0
 *  @date 03.02.2019
 *  @since 24.04.2012
 */

I hope this one will not give you more sleepless nights 😉

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions