mirror of https://github.com/citusdata/citus.git
Adds find_recursive_union to ruleutils_15.c
Relevant PG commit: 3f50b82639637c9908afa2087de7588450aa866bboolean_node
parent
697129b058
commit
c5650a06e4
|
@ -341,6 +341,8 @@ static void identify_join_columns(JoinExpr *j, RangeTblEntry *jrte,
|
|||
deparse_columns *colinfo);
|
||||
static char *get_rtable_name(int rtindex, deparse_context *context);
|
||||
static void set_deparse_plan(deparse_namespace *dpns, Plan *plan);
|
||||
static Plan *find_recursive_union(deparse_namespace *dpns,
|
||||
WorkTableScan *wtscan);
|
||||
static void push_child_plan(deparse_namespace *dpns, Plan *plan,
|
||||
deparse_namespace *save_dpns);
|
||||
static void pop_child_plan(deparse_namespace *dpns,
|
||||
|
@ -1779,6 +1781,9 @@ set_deparse_plan(deparse_namespace *dpns, Plan *plan)
|
|||
* For a SubqueryScan, pretend the subplan is INNER referent. (We don't
|
||||
* use OUTER because that could someday conflict with the normal meaning.)
|
||||
* Likewise, for a CteScan, pretend the subquery's plan is INNER referent.
|
||||
* For a WorkTableScan, locate the parent RecursiveUnion plan node and use
|
||||
* that as INNER referent.
|
||||
*
|
||||
* For ON CONFLICT .. UPDATE we just need the inner tlist to point to the
|
||||
* excluded expression's tlist. (Similar to the SubqueryScan we don't want
|
||||
* to reuse OUTER, it's used for RETURNING in some modify table cases,
|
||||
|
@ -1789,6 +1794,9 @@ set_deparse_plan(deparse_namespace *dpns, Plan *plan)
|
|||
else if (IsA(plan, CteScan))
|
||||
dpns->inner_plan = list_nth(dpns->subplans,
|
||||
((CteScan *) plan)->ctePlanId - 1);
|
||||
else if (IsA(plan, WorkTableScan))
|
||||
dpns->inner_plan = find_recursive_union(dpns,
|
||||
(WorkTableScan *) plan);
|
||||
else if (IsA(plan, ModifyTable))
|
||||
dpns->inner_plan = plan;
|
||||
else
|
||||
|
@ -1812,6 +1820,29 @@ set_deparse_plan(deparse_namespace *dpns, Plan *plan)
|
|||
dpns->index_tlist = NIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the ancestor plan node that is the RecursiveUnion generating
|
||||
* the WorkTableScan's work table. We can match on wtParam, since that
|
||||
* should be unique within the plan tree.
|
||||
*/
|
||||
static Plan *
|
||||
find_recursive_union(deparse_namespace *dpns, WorkTableScan *wtscan)
|
||||
{
|
||||
ListCell *lc;
|
||||
|
||||
foreach(lc, dpns->ancestors)
|
||||
{
|
||||
Plan *ancestor = (Plan *) lfirst(lc);
|
||||
|
||||
if (IsA(ancestor, RecursiveUnion) &&
|
||||
((RecursiveUnion *) ancestor)->wtParam == wtscan->wtParam)
|
||||
return ancestor;
|
||||
}
|
||||
elog(ERROR, "could not find RecursiveUnion for WorkTableScan with wtParam %d",
|
||||
wtscan->wtParam);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* push_child_plan: temporarily transfer deparsing attention to a child plan
|
||||
*
|
||||
|
@ -4448,9 +4479,12 @@ get_name_for_var_field(Var *var, int fieldno,
|
|||
{
|
||||
/*
|
||||
* We're deparsing a Plan tree so we don't have a CTE
|
||||
* list. But the only place we'd see a Var directly
|
||||
* referencing a CTE RTE is in a CteScan plan node, and we
|
||||
* can look into the subplan's tlist instead.
|
||||
* list. But the only places we'd see a Var directly
|
||||
* referencing a CTE RTE are in CteScan or WorkTableScan
|
||||
* plan nodes. For those cases, set_deparse_plan arranged
|
||||
* for dpns->inner_plan to be the plan node that emits the
|
||||
* CTE or RecursiveUnion result, and we can look at its
|
||||
* tlist instead.
|
||||
*/
|
||||
TargetEntry *tle;
|
||||
deparse_namespace save_dpns;
|
||||
|
|
Loading…
Reference in New Issue