mirror of https://github.com/citusdata/citus.git
Add OLD/NEW support to RETURNING in DML queries.
80feb727c869cc0b2e12bd1543bafa449be9c8e2m3hm3t/pg18_dev_relation_oid_0
parent
3dccc99d70
commit
85ffb3ff7d
|
@ -172,6 +172,8 @@ typedef struct
|
|||
List *subplans; /* List of Plan trees for SubPlans */
|
||||
List *ctes; /* List of CommonTableExpr nodes */
|
||||
AppendRelInfo **appendrels; /* Array of AppendRelInfo nodes, or NULL */
|
||||
char *ret_old_alias; /* alias for OLD in RETURNING list */
|
||||
char *ret_new_alias; /* alias for NEW in RETURNING list */
|
||||
/* Workspace for column alias assignment: */
|
||||
bool unique_using; /* Are we making USING names globally unique */
|
||||
List *using_names; /* List of assigned names for USING columns */
|
||||
|
@ -375,6 +377,7 @@ static void get_merge_query_def(Query *query, deparse_context *context);
|
|||
static void get_utility_query_def(Query *query, deparse_context *context);
|
||||
static void get_basic_select_query(Query *query, deparse_context *context);
|
||||
static void get_target_list(List *targetList, deparse_context *context);
|
||||
static void get_returning_clause(Query *query, deparse_context *context);
|
||||
static void get_setop_query(Node *setOp, Query *query,
|
||||
deparse_context *context);
|
||||
static Node *get_rule_sortgroupclause(Index ref, List *tlist,
|
||||
|
@ -852,6 +855,8 @@ set_deparse_for_query(deparse_namespace *dpns, Query *query,
|
|||
dpns->subplans = NIL;
|
||||
dpns->ctes = query->cteList;
|
||||
dpns->appendrels = NULL;
|
||||
dpns->ret_old_alias = query->returningOldAlias;
|
||||
dpns->ret_new_alias = query->returningNewAlias;
|
||||
|
||||
/* Assign a unique relation alias to each RTE */
|
||||
set_rtable_names(dpns, parent_namespaces, NULL);
|
||||
|
@ -2795,6 +2800,45 @@ get_target_list(List *targetList, deparse_context *context)
|
|||
pfree(targetbuf.data);
|
||||
}
|
||||
|
||||
static void
|
||||
get_returning_clause(Query *query, deparse_context *context)
|
||||
{
|
||||
StringInfo buf = context->buf;
|
||||
|
||||
if (query->returningList)
|
||||
{
|
||||
bool have_with = false;
|
||||
|
||||
appendContextKeyword(context, " RETURNING",
|
||||
-PRETTYINDENT_STD, PRETTYINDENT_STD, 1);
|
||||
|
||||
/* Add WITH (OLD/NEW) options, if they're not the defaults */
|
||||
if (query->returningOldAlias && strcmp(query->returningOldAlias, "old") != 0)
|
||||
{
|
||||
appendStringInfo(buf, " WITH (OLD AS %s",
|
||||
quote_identifier(query->returningOldAlias));
|
||||
have_with = true;
|
||||
}
|
||||
if (query->returningNewAlias && strcmp(query->returningNewAlias, "new") != 0)
|
||||
{
|
||||
if (have_with)
|
||||
appendStringInfo(buf, ", NEW AS %s",
|
||||
quote_identifier(query->returningNewAlias));
|
||||
else
|
||||
{
|
||||
appendStringInfo(buf, " WITH (NEW AS %s",
|
||||
quote_identifier(query->returningNewAlias));
|
||||
have_with = true;
|
||||
}
|
||||
}
|
||||
if (have_with)
|
||||
appendStringInfoChar(buf, ')');
|
||||
|
||||
/* Add the returning expressions themselves */
|
||||
get_target_list(query->returningList, context);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_setop_query(Node *setOp, Query *query, deparse_context *context)
|
||||
{
|
||||
|
@ -3447,9 +3491,7 @@ get_insert_query_def(Query *query, deparse_context *context)
|
|||
/* Add RETURNING if present */
|
||||
if (query->returningList)
|
||||
{
|
||||
appendContextKeyword(context, " RETURNING",
|
||||
-PRETTYINDENT_STD, PRETTYINDENT_STD, 1);
|
||||
get_target_list(query->returningList, context);
|
||||
get_returning_clause(query, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3525,9 +3567,7 @@ get_update_query_def(Query *query, deparse_context *context)
|
|||
/* Add RETURNING if present */
|
||||
if (query->returningList)
|
||||
{
|
||||
appendContextKeyword(context, " RETURNING",
|
||||
-PRETTYINDENT_STD, PRETTYINDENT_STD, 1);
|
||||
get_target_list(query->returningList, context);
|
||||
get_returning_clause(query, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3749,9 +3789,7 @@ get_delete_query_def(Query *query, deparse_context *context)
|
|||
/* Add RETURNING if present */
|
||||
if (query->returningList)
|
||||
{
|
||||
appendContextKeyword(context, " RETURNING",
|
||||
-PRETTYINDENT_STD, PRETTYINDENT_STD, 1);
|
||||
get_target_list(query->returningList, context);
|
||||
get_returning_clause(query, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4125,7 +4163,15 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
|
|||
}
|
||||
|
||||
rte = rt_fetch(varno, dpns->rtable);
|
||||
refname = (char *) list_nth(dpns->rtable_names, varno - 1);
|
||||
|
||||
/* might be returning old/new column value */
|
||||
if (var->varreturningtype == VAR_RETURNING_OLD)
|
||||
refname = dpns->ret_old_alias;
|
||||
else if (var->varreturningtype == VAR_RETURNING_NEW)
|
||||
refname = dpns->ret_new_alias;
|
||||
else
|
||||
refname = (char *) list_nth(dpns->rtable_names, varno - 1);
|
||||
|
||||
colinfo = deparse_columns_fetch(varno, dpns);
|
||||
attnum = varattno;
|
||||
}
|
||||
|
@ -4244,7 +4290,8 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
|
|||
attname = get_rte_attribute_name(rte, attnum);
|
||||
}
|
||||
|
||||
need_prefix = (context->varprefix || attname == NULL);
|
||||
need_prefix = (context->varprefix || attname == NULL ||
|
||||
var->varreturningtype != VAR_RETURNING_DEFAULT);
|
||||
/*
|
||||
* If we're considering a plain Var in an ORDER BY (but not GROUP BY)
|
||||
* clause, we may need to add a table-name prefix to prevent
|
||||
|
@ -5342,6 +5389,9 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
|||
case T_ConvertRowtypeExpr:
|
||||
return isSimpleNode((Node *) ((ConvertRowtypeExpr *) node)->arg,
|
||||
node, prettyFlags);
|
||||
case T_ReturningExpr:
|
||||
return isSimpleNode((Node *) ((ReturningExpr *) node)->retexpr,
|
||||
node, prettyFlags);
|
||||
|
||||
case T_OpExpr:
|
||||
{
|
||||
|
@ -6825,6 +6875,20 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||
}
|
||||
break;
|
||||
|
||||
case T_ReturningExpr:
|
||||
{
|
||||
ReturningExpr *retExpr = (ReturningExpr *) node;
|
||||
|
||||
/*
|
||||
* We cannot see a ReturningExpr in rule deparsing, only while
|
||||
* EXPLAINing a query plan (ReturningExpr nodes are only ever
|
||||
* adding during query rewriting). Just display the expression
|
||||
* returned (an expanded view column).
|
||||
*/
|
||||
get_rule_expr((Node *) retExpr->retexpr, context, showimplicit);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_PartitionBoundSpec:
|
||||
{
|
||||
PartitionBoundSpec *spec = (PartitionBoundSpec *) node;
|
||||
|
|
Loading…
Reference in New Issue