diff --git a/src/adjust.c b/src/adjust.c index 05322ce..a83bbf7 100644 --- a/src/adjust.c +++ b/src/adjust.c @@ -93,6 +93,7 @@ CustomObjectDef *chfdw_check_for_custom_function(Oid funcid) case 868: // strpos case F_BTRIM: case F_BTRIM1: + case F_TO_TIMESTAMP: special_builtin = true; break; default: @@ -153,6 +154,12 @@ CustomObjectDef *chfdw_check_for_custom_function(Oid funcid) strcpy(entry->custom_name, "position"); break; } + case F_TO_TIMESTAMP: + { + entry->cf_type = CF_TO_TIMESTAMP; + entry->custom_name[0] = '\1'; + break; + } } if (special_builtin) diff --git a/src/deparse.c b/src/deparse.c index 2c3c52a..72ca941 100644 --- a/src/deparse.c +++ b/src/deparse.c @@ -2359,6 +2359,16 @@ deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context) * Normal function: display as proname(args). */ cdef = appendFunctionName(node->funcid, context); + + if (cdef && cdef->cf_type == CF_TO_TIMESTAMP) + { + appendStringInfoString(buf, "parseDateTimeBestEffortOrNull"); + appendStringInfoChar(buf, '('); + deparseExpr(list_nth(node->args, 0), context); + appendStringInfoChar(buf, ')'); + return; + } + if (cdef && cdef->cf_type == CF_DATE_TRUNC) { Const *arg = (Const *) linitial(node->args); @@ -2409,7 +2419,7 @@ deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context) { appendStringInfoString(buf, "(toDateTime64("); deparseExpr(list_nth(node->args, 1), context); - appendStringInfoString(buf, ", 1))"); + appendStringInfoString(buf, ", 1, 'UTC'))"); } else { diff --git a/src/include/clickhousedb_fdw.h b/src/include/clickhousedb_fdw.h index 24145f3..3bc437e 100644 --- a/src/include/clickhousedb_fdw.h +++ b/src/include/clickhousedb_fdw.h @@ -268,6 +268,7 @@ typedef enum { CF_DATE_PART, /* date_part function */ CF_TIMESTAMPTZ_PL_INTERVAL, /* timestamptz + interval */ CF_TIMEZONE, /* timezone */ + CF_TO_TIMESTAMP, CF_COUNTRY_TYPE, CF_AJTIME_PL_INTERVAL, CF_AJTIME_MI_INTERVAL, diff --git a/tests/expected/functions.out b/tests/expected/functions.out index 2450b6d..667e86d 100644 --- a/tests/expected/functions.out +++ b/tests/expected/functions.out @@ -233,6 +233,22 @@ SELECT uniq_exact(a) FILTER(WHERE b>1) FROM t1; 1 (1 row) +EXPLAIN (VERBOSE, COSTS OFF) SELECT c as d1 FROM t1 WHERE c >= to_timestamp('2019-01-01 00:00:00.000000', 'YYYY-MM-DD HH24:MI:SS.US') GROUP BY d1 ORDER BY d1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan + Output: c + Relations: Aggregate on (t1) + Remote SQL: SELECT c FROM regression.t1 WHERE ((c >= parseDateTimeBestEffortOrNull('2019-01-01 00:00:00.000000'))) GROUP BY c ORDER BY c ASC +(4 rows) + +SELECT c as d1 FROM t1 WHERE c >= to_timestamp('2019-01-01 00:00:00.000000', 'YYYY-MM-DD HH24:MI:SS.US') GROUP BY d1 ORDER BY d1; + d1 +------------------------ + 2019-01-01 10:00:00 + 2019-01-02 10:00:00 +(2 rows) + EXPLAIN (VERBOSE, COSTS OFF) SELECT date_trunc('dAy', c at time zone 'UTC') as d1 FROM t1 GROUP BY d1 ORDER BY d1; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/tests/sql/functions.sql b/tests/sql/functions.sql index d59f0f9..9898f56 100644 --- a/tests/sql/functions.sql +++ b/tests/sql/functions.sql @@ -78,6 +78,9 @@ SELECT uniq_exact(a) FROM t1; EXPLAIN (VERBOSE, COSTS OFF) SELECT uniq_exact(a) FILTER(WHERE b>1) FROM t1; SELECT uniq_exact(a) FILTER(WHERE b>1) FROM t1; +EXPLAIN (VERBOSE, COSTS OFF) SELECT c as d1 FROM t1 WHERE c >= to_timestamp('2019-01-01 00:00:00.000000', 'YYYY-MM-DD HH24:MI:SS.US') GROUP BY d1 ORDER BY d1; +SELECT c as d1 FROM t1 WHERE c >= to_timestamp('2019-01-01 00:00:00.000000', 'YYYY-MM-DD HH24:MI:SS.US') GROUP BY d1 ORDER BY d1; + EXPLAIN (VERBOSE, COSTS OFF) SELECT date_trunc('dAy', c at time zone 'UTC') as d1 FROM t1 GROUP BY d1 ORDER BY d1; SELECT date_trunc('day', c at time zone 'UTC') as d1 FROM t1 GROUP BY d1 ORDER BY d1;