From cc3f4b5b9e438c7d27d7f5fe55e0bc7bc0e3fc0d Mon Sep 17 00:00:00 2001 From: alrocar Date: Wed, 2 Oct 2024 11:05:18 +0200 Subject: [PATCH] support extract --- src/custom_types.c | 11 +++++++++ src/deparse.c | 44 ++++++++++++++++++++++++++++++++++ src/include/clickhousedb_fdw.h | 1 + 3 files changed, 56 insertions(+) diff --git a/src/custom_types.c b/src/custom_types.c index 6585d49..fdbf3af 100644 --- a/src/custom_types.c +++ b/src/custom_types.c @@ -27,6 +27,8 @@ #define F_TIMESTAMP_ZONE 2069 #define F_TIMESTAMPTZ_ZONE 1159 #define F_TIMESTAMPTZ_PART 1171 +#define F_TIMESTAMP_EXTRACT 6202 +#define F_TIMESTAMPTZ_EXTRACT 6203 #define F_TO_TIMESTAMP 1778 #define F_ARRAY_POSITION 3277 #define F_STRPOS 868 @@ -99,6 +101,8 @@ CustomObjectDef *chfdw_check_for_custom_function(Oid funcid) { case F_TIMESTAMP_TRUNC: case F_TIMESTAMPTZ_TRUNC: + case F_TIMESTAMP_EXTRACT: + case F_TIMESTAMPTZ_EXTRACT: case F_TIMESTAMP_ZONE: case F_TIMESTAMPTZ_ZONE: case F_TIMESTAMP_PART: @@ -145,6 +149,13 @@ CustomObjectDef *chfdw_check_for_custom_function(Oid funcid) entry->custom_name[0] = '\1'; break; } + case F_TIMESTAMPTZ_EXTRACT: + case F_TIMESTAMP_EXTRACT: + { + entry->cf_type = CF_EXTRACT; + entry->custom_name[0] = '\1'; + break; + } case F_TIMESTAMP_ZONE: case F_TIMESTAMPTZ_ZONE: { diff --git a/src/deparse.c b/src/deparse.c index 72ca941..e121099 100644 --- a/src/deparse.c +++ b/src/deparse.c @@ -2468,6 +2468,50 @@ deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context) appendStringInfoChar(buf, ')'); return; } + else if (cdef && cdef->cf_type == CF_EXTRACT) + { + if (list_length(node->args) != 2) + elog(ERROR, "extract requires exactly two arguments"); + + Const *arg = (Const *) linitial(node->args); + char *parttype = TextDatumGetCString(arg->constvalue); + CSTRING_TOLOWER(parttype); + + Expr *source_expr = (Expr *) lsecond(node->args); + + if (strcmp(parttype, "day") == 0) + appendStringInfoString(buf, "toDayOfMonth"); + else if (strcmp(parttype, "doy") == 0) + appendStringInfoString(buf, "toDayOfYear"); + else if (strcmp(parttype, "dow") == 0) + appendStringInfoString(buf, "toDayOfWeek"); + else if (strcmp(parttype, "year") == 0) + appendStringInfoString(buf, "toYear"); + else if (strcmp(parttype, "month") == 0) + appendStringInfoString(buf, "toMonth"); + else if (strcmp(parttype, "hour") == 0) + appendStringInfoString(buf, "toHour"); + else if (strcmp(parttype, "minute") == 0) + appendStringInfoString(buf, "toMinute"); + else if (strcmp(parttype, "second") == 0) + appendStringInfoString(buf, "toSecond"); + else if (strcmp(parttype, "quarter") == 0) + appendStringInfoString(buf, "toQuarter"); + else if (strcmp(parttype, "isoyear") == 0) + appendStringInfoString(buf, "toISOYear"); + else if (strcmp(parttype, "week") == 0) + appendStringInfoString(buf, "toISOWeek"); + else if (strcmp(parttype, "epoch") == 0) + appendStringInfoString(buf, "toUnixTimestamp"); + else + elog(ERROR, "extract cannot be exported for: %s", parttype); + + pfree(parttype); + appendStringInfoChar(buf, '('); + deparseExpr(source_expr, context); + appendStringInfoChar(buf, ')'); + return; + } else if (cdef && cdef->cf_type == CF_ISTORE_SEED) { if (!context->func) diff --git a/src/include/clickhousedb_fdw.h b/src/include/clickhousedb_fdw.h index 43e218e..91f9eae 100644 --- a/src/include/clickhousedb_fdw.h +++ b/src/include/clickhousedb_fdw.h @@ -270,6 +270,7 @@ typedef enum { CF_AJTIME_TO_TIMESTAMP, /* ajtime to timestamp */ CF_DATE_TRUNC, /* date_trunc function */ CF_DATE_PART, /* date_part function */ + CF_EXTRACT, /* extract function */ CF_TIMESTAMPTZ_PL_INTERVAL, /* timestamptz + interval */ CF_TIMEZONE, /* timezone */ CF_TO_TIMESTAMP,