Update ruleutils_13.c with postgres ruleutils

Some manual updates are done for ruleutils_13 based on the difference
between pg12 ruleutils and pg13 ruleutils.
pull/3900/head
Sait Talha Nisanci 2020-05-28 12:26:31 +03:00
parent 30549dc0e2
commit 8ce8683ac4
1 changed files with 215 additions and 111 deletions

View File

@ -132,7 +132,8 @@ typedef struct
int64 shardid; /* a distributed table's shardid, if positive */
ParseExprKind special_exprkind; /* set only for exprkinds needing special
* handling */
Bitmapset *appendparents;
Bitmapset *appendparents; /* if not null, map child Vars of these relids
* back to the parent rel */
} deparse_context;
/*
@ -167,20 +168,26 @@ typedef struct
List *rtable; /* List of RangeTblEntry nodes */
List *rtable_names; /* Parallel list of names for RTEs */
List *rtable_columns; /* Parallel list of deparse_columns structs */
List *subplans; /* List of Plan trees for SubPlans */
List *ctes; /* List of CommonTableExpr nodes */
AppendRelInfo **appendrels; /* Array of AppendRelInfo nodes, or NULL */
/* 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 */
/* Remaining fields are used only when deparsing a Plan tree: */
PlanState *planstate; /* immediate parent of current expression */
Plan *plan; /* immediate parent of current expression */
List *ancestors; /* ancestors of planstate */
PlanState *outer_planstate; /* outer subplan state, or NULL if none */
PlanState *inner_planstate; /* inner subplan state, or NULL if none */
Plan *outer_plan; /* outer subnode, or NULL if none */
Plan *inner_plan; /* inner subnode, or NULL if none */
List *outer_tlist; /* referent for OUTER_VAR Vars */
List *inner_tlist; /* referent for INNER_VAR Vars */
List *index_tlist; /* referent for INDEX_VAR Vars */
} deparse_namespace;
/* Callback signature for resolve_special_varno() */
typedef void (*rsv_callback) (Node *node, deparse_context *context,
void *callback_arg);
/*
* Per-relation data about column alias names.
*
@ -333,8 +340,8 @@ static void identify_join_columns(JoinExpr *j, RangeTblEntry *jrte,
static void flatten_join_using_qual(Node *qual,
List **leftvars, List **rightvars);
static char *get_rtable_name(int rtindex, deparse_context *context);
static void set_deparse_planstate(deparse_namespace *dpns, PlanState *ps);
static void push_child_plan(deparse_namespace *dpns, PlanState *ps,
static void set_deparse_plan(deparse_namespace *dpns, Plan *plan);
static void push_child_plan(deparse_namespace *dpns, Plan *plan,
deparse_namespace *save_dpns);
static void pop_child_plan(deparse_namespace *dpns,
deparse_namespace *save_dpns);
@ -380,10 +387,9 @@ static void get_rule_windowspec(WindowClause *wc, List *targetList,
static char *get_variable(Var *var, int levelsup, bool istoplevel,
deparse_context *context);
static void get_special_variable(Node *node, deparse_context *context,
void *private);
void *callback_arg);
static void resolve_special_varno(Node *node, deparse_context *context,
void *private,
void (*callback) (Node *, deparse_context *, void *));
rsv_callback callback, void *callback_arg);
static Node *find_param_referent(Param *param, deparse_context *context,
deparse_namespace **dpns_p, ListCell **ancestor_cell_p);
static void get_parameter(Param *param, deparse_context *context);
@ -405,7 +411,7 @@ static void get_func_expr(FuncExpr *expr, deparse_context *context,
static void get_agg_expr(Aggref *aggref, deparse_context *context,
Aggref *original_aggref);
static void get_agg_combine_expr(Node *node, deparse_context *context,
void *private);
void *callback_arg);
static void get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context);
static void get_coercion_expr(Node *arg, deparse_context *context,
Oid resulttype, int32 resulttypmod,
@ -672,7 +678,9 @@ set_deparse_for_query(deparse_namespace *dpns, Query *query,
/* Initialize *dpns and fill rtable/ctes links */
memset(dpns, 0, sizeof(deparse_namespace));
dpns->rtable = query->rtable;
dpns->subplans = NIL;
dpns->ctes = query->cteList;
dpns->appendrels = NULL;
/* Assign a unique relation alias to each RTE */
set_rtable_names(dpns, parent_namespaces, NULL);
@ -1710,19 +1718,19 @@ get_rtable_name(int rtindex, deparse_context *context)
}
/*
* set_deparse_planstate: set up deparse_namespace to parse subexpressions
* of a given PlanState node
* set_deparse_plan: set up deparse_namespace to parse subexpressions
* of a given Plan node
*
* This sets the planstate, outer_planstate, inner_planstate, outer_tlist,
* This sets the plan, outer_planstate, inner_planstate, outer_tlist,
* inner_tlist, and index_tlist fields. Caller is responsible for adjusting
* the ancestors list if necessary. Note that the rtable and ctes fields do
* not need to change when shifting attention to different plan nodes in a
* single plan tree.
*/
static void
set_deparse_planstate(deparse_namespace *dpns, PlanState *ps)
set_deparse_plan(deparse_namespace *dpns, Plan *plan)
{
dpns->planstate = ps;
dpns->plan = plan;
/*
* We special-case Append and MergeAppend to pretend that the first child
@ -1732,17 +1740,17 @@ set_deparse_planstate(deparse_namespace *dpns, PlanState *ps)
* first child plan is the OUTER referent; this is to support RETURNING
* lists containing references to non-target relations.
*/
if (IsA(ps, AppendState))
dpns->outer_planstate = ((AppendState *) ps)->appendplans[0];
else if (IsA(ps, MergeAppendState))
dpns->outer_planstate = ((MergeAppendState *) ps)->mergeplans[0];
else if (IsA(ps, ModifyTableState))
dpns->outer_planstate = ((ModifyTableState *) ps)->mt_plans[0];
if (IsA(plan, Append))
dpns->outer_plan = linitial(((Append *) plan)->appendplans);
else if (IsA(plan, MergeAppend))
dpns->outer_plan = linitial(((MergeAppend *) plan)->mergeplans);
else if (IsA(plan, ModifyTable))
dpns->outer_plan = linitial(((ModifyTable *) plan)->plans);
else
dpns->outer_planstate = outerPlanState(ps);
dpns->outer_plan = outerPlan(plan);
if (dpns->outer_planstate)
dpns->outer_tlist = dpns->outer_planstate->plan->targetlist;
if (dpns->outer_plan)
dpns->outer_tlist = dpns->outer_plan->targetlist;
else
dpns->outer_tlist = NIL;
@ -1755,29 +1763,30 @@ set_deparse_planstate(deparse_namespace *dpns, PlanState *ps)
* to reuse OUTER, it's used for RETURNING in some modify table cases,
* although not INSERT .. CONFLICT).
*/
if (IsA(ps, SubqueryScanState))
dpns->inner_planstate = ((SubqueryScanState *) ps)->subplan;
else if (IsA(ps, CteScanState))
dpns->inner_planstate = ((CteScanState *) ps)->cteplanstate;
else if (IsA(ps, ModifyTableState))
dpns->inner_planstate = ps;
if (IsA(plan, SubqueryScan))
dpns->inner_plan = ((SubqueryScan *) plan)->subplan;
else if (IsA(plan, CteScan))
dpns->inner_plan = list_nth(dpns->subplans,
((CteScan *) plan)->ctePlanId - 1);
else if (IsA(plan, ModifyTable))
dpns->inner_plan = plan;
else
dpns->inner_planstate = innerPlanState(ps);
dpns->inner_plan = innerPlan(plan);
if (IsA(ps, ModifyTableState))
dpns->inner_tlist = ((ModifyTableState *) ps)->mt_excludedtlist;
else if (dpns->inner_planstate)
dpns->inner_tlist = dpns->inner_planstate->plan->targetlist;
if (IsA(plan, ModifyTable))
dpns->inner_tlist = ((ModifyTable *) plan)->exclRelTlist;
else if (dpns->inner_plan)
dpns->inner_tlist = dpns->inner_plan->targetlist;
else
dpns->inner_tlist = NIL;
/* Set up referent for INDEX_VAR Vars, if needed */
if (IsA(ps->plan, IndexOnlyScan))
dpns->index_tlist = ((IndexOnlyScan *) ps->plan)->indextlist;
else if (IsA(ps->plan, ForeignScan))
dpns->index_tlist = ((ForeignScan *) ps->plan)->fdw_scan_tlist;
else if (IsA(ps->plan, CustomScan))
dpns->index_tlist = ((CustomScan *) ps->plan)->custom_scan_tlist;
if (IsA(plan, IndexOnlyScan))
dpns->index_tlist = ((IndexOnlyScan *) plan)->indextlist;
else if (IsA(plan, ForeignScan))
dpns->index_tlist = ((ForeignScan *) plan)->fdw_scan_tlist;
else if (IsA(plan, CustomScan))
dpns->index_tlist = ((CustomScan *) plan)->custom_scan_tlist;
else
dpns->index_tlist = NIL;
}
@ -1795,17 +1804,17 @@ set_deparse_planstate(deparse_namespace *dpns, PlanState *ps)
* previous state for pop_child_plan.
*/
static void
push_child_plan(deparse_namespace *dpns, PlanState *ps,
push_child_plan(deparse_namespace *dpns, Plan *plan,
deparse_namespace *save_dpns)
{
/* Save state for restoration later */
*save_dpns = *dpns;
/* Link current plan node into ancestors list */
dpns->ancestors = lcons(dpns->planstate, dpns->ancestors);
dpns->ancestors = lcons(dpns->plan, dpns->ancestors);
/* Set attention on selected child */
set_deparse_planstate(dpns, ps);
set_deparse_plan(dpns, plan);
}
/*
@ -1960,6 +1969,7 @@ get_query_def_extended(Query *query, StringInfo buf, List *parentnamespace,
context.wrapColumn = wrapColumn;
context.indentLevel = startIndent;
context.special_exprkind = EXPR_KIND_NONE;
context.appendparents = NULL;
context.distrelid = distrelid;
context.shardid = shardid;
@ -2246,10 +2256,11 @@ get_select_query_def(Query *query, deparse_context *context,
* if so, return the VALUES RTE. Otherwise return NULL.
*/
static RangeTblEntry *
get_simple_values_rte(Query *query)
get_simple_values_rte(Query *query, TupleDesc resultDesc)
{
RangeTblEntry *result = NULL;
ListCell *lc;
int colno;
/*
* We want to return true even if the Query also contains OLD or NEW rule
@ -2286,14 +2297,24 @@ get_simple_values_rte(Query *query)
if (list_length(query->targetList) != list_length(result->eref->colnames))
return NULL; /* this probably cannot happen */
colno = 0;
forboth(lc, query->targetList, lcn, result->eref->colnames)
{
TargetEntry *tle = (TargetEntry *) lfirst(lc);
char *cname = strVal(lfirst(lcn));
char *colname;
if (tle->resjunk)
return NULL; /* this probably cannot happen */
if (tle->resname == NULL || strcmp(tle->resname, cname) != 0)
/* compute name that get_target_list would use for column */
colno++;
if (resultDesc && colno <= resultDesc->natts)
colname = NameStr(TupleDescAttr(resultDesc, colno - 1)->attname);
else
colname = tle->resname;
/* does it match the VALUES RTE? */
if (colname == NULL || strcmp(colname, cname) != 0)
return NULL; /* column name has been changed */
}
}
@ -2321,7 +2342,7 @@ get_basic_select_query(Query *query, deparse_context *context,
* VALUES part. This reverses what transformValuesClause() did at parse
* time.
*/
values_rte = get_simple_values_rte(query);
values_rte = get_simple_values_rte(query, resultDesc);
if (values_rte)
{
get_values_def(values_rte->values_lists, context);
@ -3644,15 +3665,62 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
*/
if (var->varno >= 1 && var->varno <= list_length(dpns->rtable))
{
rte = rt_fetch(var->varno, dpns->rtable);
refname = (char *) list_nth(dpns->rtable_names, var->varno - 1);
colinfo = deparse_columns_fetch(var->varno, dpns);
attnum = var->varattno;
Index varno = var->varno;
AttrNumber varattno = var->varattno;
/*
* We might have been asked to map child Vars to some parent relation.
*/
if (context->appendparents && dpns->appendrels)
{
Index pvarno = varno;
AttrNumber pvarattno = varattno;
AppendRelInfo *appinfo = dpns->appendrels[pvarno];
bool found = false;
/* Only map up to inheritance parents, not UNION ALL appendrels */
while (appinfo &&
rt_fetch(appinfo->parent_relid,
dpns->rtable)->rtekind == RTE_RELATION)
{
found = false;
if (pvarattno > 0) /* system columns stay as-is */
{
if (pvarattno > appinfo->num_child_cols)
break; /* safety check */
pvarattno = appinfo->parent_colnos[pvarattno - 1];
if (pvarattno == 0)
break; /* Var is local to child */
}
pvarno = appinfo->parent_relid;
found = true;
/* If the parent is itself a child, continue up. */
Assert(pvarno > 0 && pvarno <= list_length(dpns->rtable));
appinfo = dpns->appendrels[pvarno];
}
/*
* If we found an ancestral rel, and that rel is included in
* appendparents, print that column not the original one.
*/
if (found && bms_is_member(pvarno, context->appendparents))
{
varno = pvarno;
varattno = pvarattno;
}
}
rte = rt_fetch(varno, dpns->rtable);
refname = (char *) list_nth(dpns->rtable_names, varno - 1);
colinfo = deparse_columns_fetch(varno, dpns);
attnum = varattno;
}
else
{
resolve_special_varno((Node *) var, context, NULL,
get_special_variable);
resolve_special_varno((Node *) var, context, get_special_variable,
NULL);
return NULL;
}
@ -3665,22 +3733,22 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
* no alias. So in that case, drill down to the subplan and print the
* contents of the referenced tlist item. This works because in a plan
* tree, such Vars can only occur in a SubqueryScan or CteScan node, and
* we'll have set dpns->inner_planstate to reference the child plan node.
* we'll have set dpns->inner_plan to reference the child plan node.
*/
if ((rte->rtekind == RTE_SUBQUERY || rte->rtekind == RTE_CTE) &&
attnum > list_length(rte->eref->colnames) &&
dpns->inner_planstate)
dpns->inner_plan)
{
TargetEntry *tle;
deparse_namespace save_dpns;
tle = get_tle_by_resno(dpns->inner_tlist, var->varattno);
tle = get_tle_by_resno(dpns->inner_tlist, attnum);
if (!tle)
elog(ERROR, "invalid attnum %d for relation \"%s\"",
var->varattno, rte->eref->aliasname);
attnum, rte->eref->aliasname);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
/*
* Force parentheses because our caller probably assumed a Var is a
@ -3796,13 +3864,13 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
* get_rule_expr.
*/
static void
get_special_variable(Node *node, deparse_context *context, void *private)
get_special_variable(Node *node, deparse_context *context, void *callback_arg)
{
StringInfo buf = context->buf;
/*
* Force parentheses because our caller probably assumed a Var is a simple
* expression.
* For a non-Var referent, force parentheses because our caller probably
* assumed a Var is a simple expression.
*/
if (!IsA(node, Var))
appendStringInfoChar(buf, '(');
@ -3817,16 +3885,18 @@ get_special_variable(Node *node, deparse_context *context, void *private)
* invoke the callback provided.
*/
static void
resolve_special_varno(Node *node, deparse_context *context, void *private,
void (*callback) (Node *, deparse_context *, void *))
resolve_special_varno(Node *node, deparse_context *context, rsv_callback callback, void *callback_arg)
{
Var *var;
deparse_namespace *dpns;
/* This function is recursive, so let's be paranoid. */
check_stack_depth();
/* If it's not a Var, invoke the callback. */
if (!IsA(node, Var))
{
callback(node, context, private);
(*callback) (node, context, callback_arg);
return;
}
@ -3842,14 +3912,30 @@ resolve_special_varno(Node *node, deparse_context *context, void *private,
{
TargetEntry *tle;
deparse_namespace save_dpns;
Bitmapset *save_appendparents;
tle = get_tle_by_resno(dpns->outer_tlist, var->varattno);
if (!tle)
elog(ERROR, "bogus varattno for OUTER_VAR var: %d", var->varattno);
push_child_plan(dpns, dpns->outer_planstate, &save_dpns);
resolve_special_varno((Node *) tle->expr, context, private, callback);
/* If we're descending to the first child of an Append or MergeAppend,
* update appendparents. This will affect deparsing of all Vars
* appearing within the eventually-resolved subexpression.
*/
save_appendparents = context->appendparents;
if (IsA(dpns->plan, Append))
context->appendparents = bms_union(context->appendparents,
((Append *) dpns->plan)->apprelids);
else if (IsA(dpns->plan, MergeAppend))
context->appendparents = bms_union(context->appendparents,
((MergeAppend *) dpns->plan)->apprelids);
push_child_plan(dpns, dpns->outer_plan, &save_dpns);
resolve_special_varno((Node *) tle->expr, context,
callback, callback_arg);
pop_child_plan(dpns, &save_dpns);
context->appendparents = save_appendparents;
return;
}
else if (var->varno == INNER_VAR && dpns->inner_tlist)
@ -3861,8 +3947,8 @@ resolve_special_varno(Node *node, deparse_context *context, void *private,
if (!tle)
elog(ERROR, "bogus varattno for INNER_VAR var: %d", var->varattno);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
resolve_special_varno((Node *) tle->expr, context, private, callback);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
resolve_special_varno((Node *) tle->expr, context, callback, callback_arg);
pop_child_plan(dpns, &save_dpns);
return;
}
@ -3874,14 +3960,14 @@ resolve_special_varno(Node *node, deparse_context *context, void *private,
if (!tle)
elog(ERROR, "bogus varattno for INDEX_VAR var: %d", var->varattno);
resolve_special_varno((Node *) tle->expr, context, private, callback);
resolve_special_varno((Node *) tle->expr, context, callback, callback_arg);
return;
}
else if (var->varno < 1 || var->varno > list_length(dpns->rtable))
elog(ERROR, "bogus varno: %d", var->varno);
/* Not special. Just invoke the callback. */
callback(node, context, private);
(*callback) (node, context, callback_arg);
}
/*
@ -3989,7 +4075,7 @@ get_name_for_var_field(Var *var, int fieldno,
elog(ERROR, "bogus varattno for OUTER_VAR var: %d", var->varattno);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->outer_planstate, &save_dpns);
push_child_plan(dpns, dpns->outer_plan, &save_dpns);
result = get_name_for_var_field((Var *) tle->expr, fieldno,
levelsup, context);
@ -4008,7 +4094,7 @@ get_name_for_var_field(Var *var, int fieldno,
elog(ERROR, "bogus varattno for INNER_VAR var: %d", var->varattno);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
result = get_name_for_var_field((Var *) tle->expr, fieldno,
levelsup, context);
@ -4118,7 +4204,7 @@ get_name_for_var_field(Var *var, int fieldno,
deparse_namespace save_dpns;
const char *result;
if (!dpns->inner_planstate)
if (!dpns->inner_plan)
elog(ERROR, "failed to find plan for subquery %s",
rte->eref->aliasname);
tle = get_tle_by_resno(dpns->inner_tlist, attnum);
@ -4126,7 +4212,7 @@ get_name_for_var_field(Var *var, int fieldno,
elog(ERROR, "bogus varattno for subquery var: %d",
attnum);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
result = get_name_for_var_field((Var *) tle->expr, fieldno,
levelsup, context);
@ -4236,7 +4322,7 @@ get_name_for_var_field(Var *var, int fieldno,
deparse_namespace save_dpns;
const char *result;
if (!dpns->inner_planstate)
if (!dpns->inner_plan)
elog(ERROR, "failed to find plan for CTE %s",
rte->eref->aliasname);
tle = get_tle_by_resno(dpns->inner_tlist, attnum);
@ -4244,7 +4330,7 @@ get_name_for_var_field(Var *var, int fieldno,
elog(ERROR, "bogus varattno for subquery var: %d",
attnum);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
result = get_name_for_var_field((Var *) tle->expr, fieldno,
levelsup, context);
@ -4285,22 +4371,22 @@ find_param_referent(Param *param, deparse_context *context,
/*
* If it's a PARAM_EXEC parameter, look for a matching NestLoopParam or
* SubPlan argument. This will necessarily be in some ancestor of the
* current expression's PlanState.
* current expression's Plan.
*/
if (param->paramkind == PARAM_EXEC)
{
deparse_namespace *dpns;
PlanState *child_ps;
Plan *child_plan;
bool in_same_plan_level;
ListCell *lc;
dpns = (deparse_namespace *) linitial(context->namespaces);
child_ps = dpns->planstate;
child_plan = dpns->plan;
in_same_plan_level = true;
foreach(lc, dpns->ancestors)
{
PlanState *ps = (PlanState *) lfirst(lc);
Node *ancestor = (Node *) lfirst(lc);
ListCell *lc2;
/*
@ -4308,11 +4394,11 @@ find_param_referent(Param *param, deparse_context *context,
* we've crawled up out of a subplan, this couldn't possibly be
* the right match.
*/
if (IsA(ps, NestLoopState) &&
child_ps == innerPlanState(ps) &&
if (IsA(ancestor, NestLoop) &&
child_plan == innerPlan(ancestor) &&
in_same_plan_level)
{
NestLoop *nl = (NestLoop *) ps->plan;
NestLoop *nl = (NestLoop *) ancestor;
foreach(lc2, nl->nestParams)
{
@ -4331,16 +4417,12 @@ find_param_referent(Param *param, deparse_context *context,
/*
* Check to see if we're crawling up from a subplan.
*/
foreach(lc2, ps->subPlan)
if(IsA(ancestor, SubPlan))
{
SubPlanState *sstate = (SubPlanState *) lfirst(lc2);
SubPlan *subplan = sstate->subplan;
SubPlan *subplan = (SubPlan *) ancestor;
ListCell *lc3;
ListCell *lc4;
if (child_ps != sstate->planstate)
continue;
/* Matched subplan, so check its arguments */
forboth(lc3, subplan->parParam, lc4, subplan->args)
{
@ -4349,41 +4431,61 @@ find_param_referent(Param *param, deparse_context *context,
if (paramid == param->paramid)
{
/* Found a match, so return it */
*dpns_p = dpns;
*ancestor_cell_p = lc;
return arg;
/*
* Found a match, so return it. But, since Vars in
* the arg are to be evaluated in the surrounding
* context, we have to point to the next ancestor item
* that is *not* a SubPlan.
*/
ListCell *rest;
for_each_cell(rest, dpns->ancestors,
lnext(dpns->ancestors, lc))
{
Node *ancestor2 = (Node *) lfirst(rest);
if (!IsA(ancestor2, SubPlan))
{
*dpns_p = dpns;
*ancestor_cell_p = rest;
return arg;
}
}
elog(ERROR, "SubPlan cannot be outermost ancestor");
}
}
/* Keep looking, but we are emerging from a subplan. */
/* We have emerged from a subplan. */
in_same_plan_level = false;
break;
/* SubPlan isn't a kind of Plan, so skip the rest */
continue;
}
/*
* Likewise check to see if we're emerging from an initplan.
* Initplans never have any parParams, so no need to search that
* list, but we need to know if we should reset
* Check to see if we're emerging from an initplan of the current
* ancestor plan. Initplans never have any parParams, so no need
* to search that list, but we need to know if we should reset
* in_same_plan_level.
*/
foreach(lc2, ps->initPlan)
foreach(lc2, ((Plan *) ancestor)->initPlan)
{
SubPlanState *sstate = (SubPlanState *) lfirst(lc2);
SubPlan *subplan = castNode(SubPlan, lfirst(lc2));
if (child_ps != sstate->planstate)
if (child_plan != (Plan *) list_nth(dpns->subplans,
subplan->plan_id - 1))
continue;
/* No parameters to be had here. */
Assert(sstate->subplan->parParam == NIL);
Assert(subplan->parParam == NIL);
/* Keep looking, but we are emerging from an initplan. */
/* We have emerged from an initplan. */
in_same_plan_level = false;
break;
}
/* No luck, crawl up to next ancestor */
child_ps = ps;
child_plan = (Plan *) ancestor;
}
}
@ -6247,11 +6349,13 @@ get_agg_expr(Aggref *aggref, deparse_context *context,
*/
if (DO_AGGSPLIT_COMBINE(aggref->aggsplit))
{
TargetEntry *tle = linitial_node(TargetEntry, aggref->args);
TargetEntry *tle;
Assert(list_length(aggref->args) == 1);
resolve_special_varno((Node *) tle->expr, context, original_aggref,
get_agg_combine_expr);
tle = linitial_node(TargetEntry, aggref->args);
resolve_special_varno((Node *) tle->expr, context,
get_agg_combine_expr, original_aggref);
return;
}
@ -6336,10 +6440,10 @@ get_agg_expr(Aggref *aggref, deparse_context *context,
* Aggref and then calls this.
*/
static void
get_agg_combine_expr(Node *node, deparse_context *context, void *private)
get_agg_combine_expr(Node *node, deparse_context *context, void *callback_arg)
{
Aggref *aggref;
Aggref *original_aggref = private;
Aggref *original_aggref = callback_arg;
if (!IsA(node, Aggref))
elog(ERROR, "combining Aggref does not point to an Aggref");
@ -7102,7 +7206,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
List *args = ((FuncExpr *) rtfunc->funcexpr)->args;
allargs = list_concat(allargs, list_copy(args));
allargs = list_concat(allargs, args);
}
appendStringInfoString(buf, "UNNEST(");
@ -7628,7 +7732,7 @@ printSubscripts(SubscriptingRef *sbsref, deparse_context *context)
/* If subexpression is NULL, get_rule_expr prints nothing */
get_rule_expr((Node *) lfirst(lowlist_item), context, false);
appendStringInfoChar(buf, ':');
lowlist_item = lnext(sbsref->refupperindexpr, lowlist_item);
lowlist_item = lnext(sbsref->reflowerindexpr, lowlist_item);
}
/* If subexpression is NULL, get_rule_expr prints nothing */
get_rule_expr((Node *) lfirst(uplist_item), context, false);