mirror of https://github.com/citusdata/citus.git
Adds SQL syntax function calls related changes to ruleutils_14.c
Relevant PG commit: 40c24bfef92530bd846e111c1742c2a54441c62cpull/5209/head
parent
b4f76303c6
commit
1cb865deb8
|
@ -413,6 +413,7 @@ static void get_agg_expr(Aggref *aggref, deparse_context *context,
|
|||
static void get_agg_combine_expr(Node *node, deparse_context *context,
|
||||
void *callback_arg);
|
||||
static void get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context);
|
||||
static bool get_func_sql_syntax(FuncExpr *expr, deparse_context *context);
|
||||
static void get_coercion_expr(Node *arg, deparse_context *context,
|
||||
Oid resulttype, int32 resulttypmod,
|
||||
Node *parentNode);
|
||||
|
@ -6132,7 +6133,8 @@ looks_like_function(Node *node)
|
|||
{
|
||||
case T_FuncExpr:
|
||||
/* OK, unless it's going to deparse as a cast */
|
||||
return (((FuncExpr *) node)->funcformat == COERCE_EXPLICIT_CALL);
|
||||
return (((FuncExpr *) node)->funcformat == COERCE_EXPLICIT_CALL ||
|
||||
((FuncExpr *) node)->funcformat == COERCE_SQL_SYNTAX);
|
||||
case T_NullIfExpr:
|
||||
case T_CoalesceExpr:
|
||||
case T_MinMaxExpr:
|
||||
|
@ -6234,6 +6236,18 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the function was called using one of the SQL spec's random special
|
||||
* syntaxes, try to reproduce that. If we don't recognize the function,
|
||||
* fall through.
|
||||
*/
|
||||
if (expr->funcformat == COERCE_SQL_SYNTAX)
|
||||
{
|
||||
if (get_func_sql_syntax(expr, context))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Normal function: display as proname(args). First we need to extract
|
||||
* the argument datatypes.
|
||||
|
@ -6470,6 +6484,225 @@ get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_func_sql_syntax - Parse back a SQL-syntax function call
|
||||
*
|
||||
* Returns true if we successfully deparsed, false if we did not
|
||||
* recognize the function.
|
||||
*/
|
||||
static bool
|
||||
get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
|
||||
{
|
||||
StringInfo buf = context->buf;
|
||||
Oid funcoid = expr->funcid;
|
||||
|
||||
switch (funcoid)
|
||||
{
|
||||
case F_TIMEZONE_INTERVAL_TIMESTAMP:
|
||||
case F_TIMEZONE_INTERVAL_TIMESTAMPTZ:
|
||||
case F_TIMEZONE_INTERVAL_TIMETZ:
|
||||
case F_TIMEZONE_TEXT_TIMESTAMP:
|
||||
case F_TIMEZONE_TEXT_TIMESTAMPTZ:
|
||||
case F_TIMEZONE_TEXT_TIMETZ:
|
||||
/* AT TIME ZONE ... note reversed argument order */
|
||||
appendStringInfoChar(buf, '(');
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
appendStringInfoString(buf, " AT TIME ZONE ");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
case F_OVERLAPS_TIMESTAMPTZ_INTERVAL_TIMESTAMPTZ_INTERVAL:
|
||||
case F_OVERLAPS_TIMESTAMPTZ_INTERVAL_TIMESTAMPTZ_TIMESTAMPTZ:
|
||||
case F_OVERLAPS_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ_INTERVAL:
|
||||
case F_OVERLAPS_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ:
|
||||
case F_OVERLAPS_TIMESTAMP_INTERVAL_TIMESTAMP_INTERVAL:
|
||||
case F_OVERLAPS_TIMESTAMP_INTERVAL_TIMESTAMP_TIMESTAMP:
|
||||
case F_OVERLAPS_TIMESTAMP_TIMESTAMP_TIMESTAMP_INTERVAL:
|
||||
case F_OVERLAPS_TIMESTAMP_TIMESTAMP_TIMESTAMP_TIMESTAMP:
|
||||
case F_OVERLAPS_TIMETZ_TIMETZ_TIMETZ_TIMETZ:
|
||||
case F_OVERLAPS_TIME_INTERVAL_TIME_INTERVAL:
|
||||
case F_OVERLAPS_TIME_INTERVAL_TIME_TIME:
|
||||
case F_OVERLAPS_TIME_TIME_TIME_INTERVAL:
|
||||
case F_OVERLAPS_TIME_TIME_TIME_TIME:
|
||||
/* (x1, x2) OVERLAPS (y1, y2) */
|
||||
appendStringInfoString(buf, "((");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoString(buf, ", ");
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
appendStringInfoString(buf, ") OVERLAPS (");
|
||||
get_rule_expr((Node *) lthird(expr->args), context, false);
|
||||
appendStringInfoString(buf, ", ");
|
||||
get_rule_expr((Node *) lfourth(expr->args), context, false);
|
||||
appendStringInfoString(buf, "))");
|
||||
return true;
|
||||
|
||||
case F_IS_NORMALIZED:
|
||||
/* IS xxx NORMALIZED */
|
||||
appendStringInfoString(buf, "((");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoString(buf, ") IS");
|
||||
if (list_length(expr->args) == 2)
|
||||
{
|
||||
Const *con = (Const *) lsecond(expr->args);
|
||||
|
||||
Assert(IsA(con, Const) &&
|
||||
con->consttype == TEXTOID &&
|
||||
!con->constisnull);
|
||||
appendStringInfo(buf, " %s",
|
||||
TextDatumGetCString(con->constvalue));
|
||||
}
|
||||
appendStringInfoString(buf, " NORMALIZED)");
|
||||
return true;
|
||||
|
||||
case F_PG_COLLATION_FOR:
|
||||
/* COLLATION FOR */
|
||||
appendStringInfoString(buf, "COLLATION FOR (");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
/*
|
||||
* XXX EXTRACT, a/k/a date_part(), is intentionally not covered
|
||||
* yet. Add it after we change the return type to numeric.
|
||||
*/
|
||||
|
||||
case F_NORMALIZE:
|
||||
/* NORMALIZE() */
|
||||
appendStringInfoString(buf, "NORMALIZE(");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
if (list_length(expr->args) == 2)
|
||||
{
|
||||
Const *con = (Const *) lsecond(expr->args);
|
||||
|
||||
Assert(IsA(con, Const) &&
|
||||
con->consttype == TEXTOID &&
|
||||
!con->constisnull);
|
||||
appendStringInfo(buf, ", %s",
|
||||
TextDatumGetCString(con->constvalue));
|
||||
}
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
case F_OVERLAY_BIT_BIT_INT4:
|
||||
case F_OVERLAY_BIT_BIT_INT4_INT4:
|
||||
case F_OVERLAY_BYTEA_BYTEA_INT4:
|
||||
case F_OVERLAY_BYTEA_BYTEA_INT4_INT4:
|
||||
case F_OVERLAY_TEXT_TEXT_INT4:
|
||||
case F_OVERLAY_TEXT_TEXT_INT4_INT4:
|
||||
/* OVERLAY() */
|
||||
appendStringInfoString(buf, "OVERLAY(");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoString(buf, " PLACING ");
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
appendStringInfoString(buf, " FROM ");
|
||||
get_rule_expr((Node *) lthird(expr->args), context, false);
|
||||
if (list_length(expr->args) == 4)
|
||||
{
|
||||
appendStringInfoString(buf, " FOR ");
|
||||
get_rule_expr((Node *) lfourth(expr->args), context, false);
|
||||
}
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
case F_POSITION_BIT_BIT:
|
||||
case F_POSITION_BYTEA_BYTEA:
|
||||
case F_POSITION_TEXT_TEXT:
|
||||
/* POSITION() ... extra parens since args are b_expr not a_expr */
|
||||
appendStringInfoString(buf, "POSITION((");
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
appendStringInfoString(buf, ") IN (");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoString(buf, "))");
|
||||
return true;
|
||||
|
||||
case F_SUBSTRING_BIT_INT4:
|
||||
case F_SUBSTRING_BIT_INT4_INT4:
|
||||
case F_SUBSTRING_BYTEA_INT4:
|
||||
case F_SUBSTRING_BYTEA_INT4_INT4:
|
||||
case F_SUBSTRING_TEXT_INT4:
|
||||
case F_SUBSTRING_TEXT_INT4_INT4:
|
||||
/* SUBSTRING FROM/FOR (i.e., integer-position variants) */
|
||||
appendStringInfoString(buf, "SUBSTRING(");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoString(buf, " FROM ");
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
if (list_length(expr->args) == 3)
|
||||
{
|
||||
appendStringInfoString(buf, " FOR ");
|
||||
get_rule_expr((Node *) lthird(expr->args), context, false);
|
||||
}
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
case F_SUBSTRING_TEXT_TEXT_TEXT:
|
||||
/* SUBSTRING SIMILAR/ESCAPE */
|
||||
appendStringInfoString(buf, "SUBSTRING(");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoString(buf, " SIMILAR ");
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
appendStringInfoString(buf, " ESCAPE ");
|
||||
get_rule_expr((Node *) lthird(expr->args), context, false);
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
case F_BTRIM_BYTEA_BYTEA:
|
||||
case F_BTRIM_TEXT:
|
||||
case F_BTRIM_TEXT_TEXT:
|
||||
/* TRIM() */
|
||||
appendStringInfoString(buf, "TRIM(BOTH");
|
||||
if (list_length(expr->args) == 2)
|
||||
{
|
||||
appendStringInfoChar(buf, ' ');
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
}
|
||||
appendStringInfoString(buf, " FROM ");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
case F_LTRIM_TEXT:
|
||||
case F_LTRIM_TEXT_TEXT:
|
||||
/* TRIM() */
|
||||
appendStringInfoString(buf, "TRIM(LEADING");
|
||||
if (list_length(expr->args) == 2)
|
||||
{
|
||||
appendStringInfoChar(buf, ' ');
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
}
|
||||
appendStringInfoString(buf, " FROM ");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
case F_RTRIM_TEXT:
|
||||
case F_RTRIM_TEXT_TEXT:
|
||||
/* TRIM() */
|
||||
appendStringInfoString(buf, "TRIM(TRAILING");
|
||||
if (list_length(expr->args) == 2)
|
||||
{
|
||||
appendStringInfoChar(buf, ' ');
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
}
|
||||
appendStringInfoString(buf, " FROM ");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoChar(buf, ')');
|
||||
return true;
|
||||
|
||||
case F_XMLEXISTS:
|
||||
/* XMLEXISTS ... extra parens because args are c_expr */
|
||||
appendStringInfoString(buf, "XMLEXISTS((");
|
||||
get_rule_expr((Node *) linitial(expr->args), context, false);
|
||||
appendStringInfoString(buf, ") PASSING (");
|
||||
get_rule_expr((Node *) lsecond(expr->args), context, false);
|
||||
appendStringInfoString(buf, "))");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* ----------
|
||||
* get_coercion_expr
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue