mirror of https://github.com/citusdata/citus.git
Update ruleutils_96 with latest PostgreSQL changes
See: postgres/postgres@41ada83774 postgres/postgres@3b0c2dbed0 postgres/postgres@ff2d537223pull/1632/head
parent
0e134a9178
commit
ebecde8f6e
|
@ -386,6 +386,9 @@ static void get_rule_expr(Node *node, deparse_context *context,
|
||||||
bool showimplicit);
|
bool showimplicit);
|
||||||
static void get_rule_expr_toplevel(Node *node, deparse_context *context,
|
static void get_rule_expr_toplevel(Node *node, deparse_context *context,
|
||||||
bool showimplicit);
|
bool showimplicit);
|
||||||
|
static void get_rule_expr_funccall(Node *node, deparse_context *context,
|
||||||
|
bool showimplicit);
|
||||||
|
static bool looks_like_function(Node *node);
|
||||||
static void get_oper_expr(OpExpr *expr, deparse_context *context);
|
static void get_oper_expr(OpExpr *expr, deparse_context *context);
|
||||||
static void get_func_expr(FuncExpr *expr, deparse_context *context,
|
static void get_func_expr(FuncExpr *expr, deparse_context *context,
|
||||||
bool showimplicit);
|
bool showimplicit);
|
||||||
|
@ -3282,8 +3285,11 @@ get_update_query_targetlist_def(Query *query, List *targetList,
|
||||||
/*
|
/*
|
||||||
* We must dig down into the expr to see if it's a PARAM_MULTIEXPR
|
* We must dig down into the expr to see if it's a PARAM_MULTIEXPR
|
||||||
* Param. That could be buried under FieldStores and ArrayRefs
|
* Param. That could be buried under FieldStores and ArrayRefs
|
||||||
* (cf processIndirection()), and underneath those there could be
|
* and CoerceToDomains (cf processIndirection()), and underneath
|
||||||
* an implicit type coercion.
|
* those there could be an implicit type coercion. Because we
|
||||||
|
* would ignore implicit type coercions anyway, we don't need to
|
||||||
|
* be as careful as processIndirection() is about descending past
|
||||||
|
* implicit CoerceToDomains.
|
||||||
*/
|
*/
|
||||||
expr = (Node *) tle->expr;
|
expr = (Node *) tle->expr;
|
||||||
while (expr)
|
while (expr)
|
||||||
|
@ -3302,6 +3308,14 @@ get_update_query_targetlist_def(Query *query, List *targetList,
|
||||||
break;
|
break;
|
||||||
expr = (Node *) aref->refassgnexpr;
|
expr = (Node *) aref->refassgnexpr;
|
||||||
}
|
}
|
||||||
|
else if (IsA(expr, CoerceToDomain))
|
||||||
|
{
|
||||||
|
CoerceToDomain *cdomain = (CoerceToDomain *) expr;
|
||||||
|
|
||||||
|
if (cdomain->coercionformat != COERCE_IMPLICIT_CAST)
|
||||||
|
break;
|
||||||
|
expr = (Node *) cdomain->arg;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5763,6 +5777,63 @@ get_rule_expr_toplevel(Node *node, deparse_context *context,
|
||||||
get_rule_expr(node, context, showimplicit);
|
get_rule_expr(node, context, showimplicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_rule_expr_funccall - Parse back a function-call expression
|
||||||
|
*
|
||||||
|
* Same as get_rule_expr(), except that we guarantee that the output will
|
||||||
|
* look like a function call, or like one of the things the grammar treats as
|
||||||
|
* equivalent to a function call (see the func_expr_windowless production).
|
||||||
|
* This is needed in places where the grammar uses func_expr_windowless and
|
||||||
|
* you can't substitute a parenthesized a_expr. If what we have isn't going
|
||||||
|
* to look like a function call, wrap it in a dummy CAST() expression, which
|
||||||
|
* will satisfy the grammar --- and, indeed, is likely what the user wrote to
|
||||||
|
* produce such a thing.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
get_rule_expr_funccall(Node *node, deparse_context *context,
|
||||||
|
bool showimplicit)
|
||||||
|
{
|
||||||
|
if (looks_like_function(node))
|
||||||
|
get_rule_expr(node, context, showimplicit);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StringInfo buf = context->buf;
|
||||||
|
|
||||||
|
appendStringInfoString(buf, "CAST(");
|
||||||
|
/* no point in showing any top-level implicit cast */
|
||||||
|
get_rule_expr(node, context, false);
|
||||||
|
appendStringInfo(buf, " AS %s)",
|
||||||
|
format_type_with_typemod(exprType(node),
|
||||||
|
exprTypmod(node)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function to identify node types that satisfy func_expr_windowless.
|
||||||
|
* If in doubt, "false" is always a safe answer.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
looks_like_function(Node *node)
|
||||||
|
{
|
||||||
|
if (node == NULL)
|
||||||
|
return false; /* probably shouldn't happen */
|
||||||
|
switch (nodeTag(node))
|
||||||
|
{
|
||||||
|
case T_FuncExpr:
|
||||||
|
/* OK, unless it's going to deparse as a cast */
|
||||||
|
return (((FuncExpr *) node)->funcformat == COERCE_EXPLICIT_CALL);
|
||||||
|
case T_NullIfExpr:
|
||||||
|
case T_CoalesceExpr:
|
||||||
|
case T_MinMaxExpr:
|
||||||
|
case T_XmlExpr:
|
||||||
|
/* these are all accepted by func_expr_common_subexpr */
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_oper_expr - Parse back an OpExpr node
|
* get_oper_expr - Parse back an OpExpr node
|
||||||
|
@ -6641,7 +6712,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
|
||||||
if (list_length(rte->functions) == 1 &&
|
if (list_length(rte->functions) == 1 &&
|
||||||
(rtfunc1->funccolnames == NIL || !rte->funcordinality))
|
(rtfunc1->funccolnames == NIL || !rte->funcordinality))
|
||||||
{
|
{
|
||||||
get_rule_expr(rtfunc1->funcexpr, context, true);
|
get_rule_expr_funccall(rtfunc1->funcexpr, context, true);
|
||||||
/* we'll print the coldeflist below, if it has one */
|
/* we'll print the coldeflist below, if it has one */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6704,7 +6775,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
|
||||||
|
|
||||||
if (funcno > 0)
|
if (funcno > 0)
|
||||||
appendStringInfoString(buf, ", ");
|
appendStringInfoString(buf, ", ");
|
||||||
get_rule_expr(rtfunc->funcexpr, context, true);
|
get_rule_expr_funccall(rtfunc->funcexpr, context, true);
|
||||||
if (rtfunc->funccolnames != NIL)
|
if (rtfunc->funccolnames != NIL)
|
||||||
{
|
{
|
||||||
/* Reconstruct the column definition list */
|
/* Reconstruct the column definition list */
|
||||||
|
@ -6894,6 +6965,11 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
|
||||||
if (!PRETTY_PAREN(context))
|
if (!PRETTY_PAREN(context))
|
||||||
appendStringInfoChar(buf, ')');
|
appendStringInfoChar(buf, ')');
|
||||||
}
|
}
|
||||||
|
else if (j->jointype != JOIN_INNER)
|
||||||
|
{
|
||||||
|
/* If we didn't say CROSS JOIN above, we must provide an ON */
|
||||||
|
appendStringInfoString(buf, " ON TRUE");
|
||||||
|
}
|
||||||
|
|
||||||
if (!PRETTY_PAREN(context) || j->alias != NULL)
|
if (!PRETTY_PAREN(context) || j->alias != NULL)
|
||||||
appendStringInfoChar(buf, ')');
|
appendStringInfoChar(buf, ')');
|
||||||
|
@ -7090,13 +7166,17 @@ get_opclass_name(Oid opclass, Oid actual_datatype,
|
||||||
*
|
*
|
||||||
* We strip any top-level FieldStore or assignment ArrayRef nodes that
|
* We strip any top-level FieldStore or assignment ArrayRef nodes that
|
||||||
* appear in the input, printing them as decoration for the base column
|
* appear in the input, printing them as decoration for the base column
|
||||||
* name (which we assume the caller just printed). Return the subexpression
|
* name (which we assume the caller just printed). We might also need to
|
||||||
* that's to be assigned.
|
* strip CoerceToDomain nodes, but only ones that appear above assignment
|
||||||
|
* nodes.
|
||||||
|
*
|
||||||
|
* Returns the subexpression that's to be assigned.
|
||||||
*/
|
*/
|
||||||
static Node *
|
static Node *
|
||||||
processIndirection(Node *node, deparse_context *context)
|
processIndirection(Node *node, deparse_context *context)
|
||||||
{
|
{
|
||||||
StringInfo buf = context->buf;
|
StringInfo buf = context->buf;
|
||||||
|
CoerceToDomain *cdomain = NULL;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -7144,10 +7224,28 @@ processIndirection(Node *node, deparse_context *context)
|
||||||
*/
|
*/
|
||||||
node = (Node *) aref->refassgnexpr;
|
node = (Node *) aref->refassgnexpr;
|
||||||
}
|
}
|
||||||
|
else if (IsA(node, CoerceToDomain))
|
||||||
|
{
|
||||||
|
cdomain = (CoerceToDomain *) node;
|
||||||
|
/* If it's an explicit domain coercion, we're done */
|
||||||
|
if (cdomain->coercionformat != COERCE_IMPLICIT_CAST)
|
||||||
|
break;
|
||||||
|
/* Tentatively descend past the CoerceToDomain */
|
||||||
|
node = (Node *) cdomain->arg;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we descended past a CoerceToDomain whose argument turned out not to
|
||||||
|
* be a FieldStore or array assignment, back up to the CoerceToDomain.
|
||||||
|
* (This is not enough to be fully correct if there are nested implicit
|
||||||
|
* CoerceToDomains, but such cases shouldn't ever occur.)
|
||||||
|
*/
|
||||||
|
if (cdomain && node == (Node *) cdomain->arg)
|
||||||
|
node = (Node *) cdomain;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue