diff options
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index dd748acffdf..c1d860ceffd 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -2520,7 +2520,43 @@ deparse_context_for(const char *aliasname, Oid relid) } /* - * deparse_context_for_planstate - Build deparse context for a plan + * deparse_context_for_plan_rtable - Build deparse context for a plan's rtable + * + * When deparsing an expression in a Plan tree, we use the plan's rangetable + * to resolve names of simple Vars. The initialization of column names for + * this is rather expensive if the rangetable is large, and it'll be the same + * for every expression in the Plan tree; so we do it just once and re-use + * the result of this function for each expression. (Note that the result + * is not usable until set_deparse_context_planstate() is applied to it.) + * + * In addition to the plan's rangetable list, pass the per-RTE alias names + * assigned by a previous call to select_rtable_names_for_explain. + */ +List * +deparse_context_for_plan_rtable(List *rtable, List *rtable_names) +{ + deparse_namespace *dpns; + + dpns = (deparse_namespace *) palloc0(sizeof(deparse_namespace)); + + /* Initialize fields that stay the same across the whole plan tree */ + dpns->rtable = rtable; + dpns->rtable_names = rtable_names; + dpns->ctes = NIL; + + /* + * Set up column name aliases. We will get rather bogus results for join + * RTEs, but that doesn't matter because plan trees don't contain any join + * alias Vars. + */ + set_simple_column_names(dpns); + + /* Return a one-deep namespace stack */ + return list_make1(dpns); +} + +/* + * set_deparse_context_planstate - Specify Plan node containing expression * * When deparsing an expression in a Plan tree, we might have to resolve * OUTER_VAR, INNER_VAR, or INDEX_VAR references. To do this, the caller must @@ -2533,43 +2569,34 @@ deparse_context_for(const char *aliasname, Oid relid) * fields, which won't contain INDEX_VAR Vars.) * * Note: planstate really ought to be declared as "PlanState *", but we use - * "Node *" to avoid having to include execnodes.h in builtins.h. + * "Node *" to avoid having to include execnodes.h in ruleutils.h. * * The ancestors list is a list of the PlanState's parent PlanStates, the * most-closely-nested first. This is needed to resolve PARAM_EXEC Params. * Note we assume that all the PlanStates share the same rtable. * - * The plan's rangetable list must also be passed, along with the per-RTE - * alias names assigned by a previous call to select_rtable_names_for_explain. - * (We use the rangetable to resolve simple Vars, but the plan inputs are - * necessary for Vars with special varnos.) + * Once this function has been called, deparse_expression() can be called on + * subsidiary expression(s) of the specified PlanState node. To deparse + * expressions of a different Plan node in the same Plan tree, re-call this + * function to identify the new parent Plan node. + * + * The result is the same List passed in; this is a notational convenience. */ List * -deparse_context_for_planstate(Node *planstate, List *ancestors, - List *rtable, List *rtable_names) +set_deparse_context_planstate(List *dpcontext, + Node *planstate, List *ancestors) { deparse_namespace *dpns; - dpns = (deparse_namespace *) palloc0(sizeof(deparse_namespace)); - - /* Initialize fields that stay the same across the whole plan tree */ - dpns->rtable = rtable; - dpns->rtable_names = rtable_names; - dpns->ctes = NIL; - - /* - * Set up column name aliases. We will get rather bogus results for join - * RTEs, but that doesn't matter because plan trees don't contain any join - * alias Vars. - */ - set_simple_column_names(dpns); + /* Should always have one-entry namespace list for Plan deparsing */ + Assert(list_length(dpcontext) == 1); + dpns = (deparse_namespace *) linitial(dpcontext); /* Set our attention on the specific plan node passed in */ set_deparse_planstate(dpns, (PlanState *) planstate); dpns->ancestors = ancestors; - /* Return a one-deep namespace stack */ - return list_make1(dpns); + return dpcontext; } /* |