Commit 18c0da88 authored by Tom Lane's avatar Tom Lane

Split QTW_EXAMINE_RTES flag into QTW_EXAMINE_RTES_BEFORE/_AFTER.

This change allows callers of query_tree_walker() to choose whether
to visit an RTE before or after visiting the contents of the RTE
(i.e., prefix or postfix tree order).  All existing users of
QTW_EXAMINE_RTES want the QTW_EXAMINE_RTES_BEFORE behavior, but
an upcoming patch will want QTW_EXAMINE_RTES_AFTER, and it seems
like a potentially useful change on its own.

Andreas Karlsson (extracted from CTE inlining patch)

Discussion: https://postgr.es/m/8810.1542402910@sss.pgh.pa.us
parent ff750ce2
...@@ -2255,7 +2255,7 @@ expression_tree_walker(Node *node, ...@@ -2255,7 +2255,7 @@ expression_tree_walker(Node *node,
* Some callers want to suppress visitation of certain items in the sub-Query, * Some callers want to suppress visitation of certain items in the sub-Query,
* typically because they need to process them specially, or don't actually * typically because they need to process them specially, or don't actually
* want to recurse into subqueries. This is supported by the flags argument, * want to recurse into subqueries. This is supported by the flags argument,
* which is the bitwise OR of flag values to suppress visitation of * which is the bitwise OR of flag values to add or suppress visitation of
* indicated items. (More flag bits may be added as needed.) * indicated items. (More flag bits may be added as needed.)
*/ */
bool bool
...@@ -2314,8 +2314,12 @@ range_table_walker(List *rtable, ...@@ -2314,8 +2314,12 @@ range_table_walker(List *rtable,
{ {
RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt); RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
/* For historical reasons, visiting RTEs is not the default */ /*
if (flags & QTW_EXAMINE_RTES) * Walkers might need to examine the RTE node itself either before or
* after visiting its contents (or, conceivably, both). Note that if
* you specify neither flag, the walker won't visit the RTE at all.
*/
if (flags & QTW_EXAMINE_RTES_BEFORE)
if (walker(rte, context)) if (walker(rte, context))
return true; return true;
...@@ -2355,6 +2359,10 @@ range_table_walker(List *rtable, ...@@ -2355,6 +2359,10 @@ range_table_walker(List *rtable,
if (walker(rte->securityQuals, context)) if (walker(rte->securityQuals, context))
return true; return true;
if (flags & QTW_EXAMINE_RTES_AFTER)
if (walker(rte, context))
return true;
} }
return false; return false;
} }
......
...@@ -340,7 +340,7 @@ flatten_unplanned_rtes(PlannerGlobal *glob, RangeTblEntry *rte) ...@@ -340,7 +340,7 @@ flatten_unplanned_rtes(PlannerGlobal *glob, RangeTblEntry *rte)
(void) query_tree_walker(rte->subquery, (void) query_tree_walker(rte->subquery,
flatten_rtes_walker, flatten_rtes_walker,
(void *) glob, (void *) glob,
QTW_EXAMINE_RTES); QTW_EXAMINE_RTES_BEFORE);
} }
static bool static bool
...@@ -363,7 +363,7 @@ flatten_rtes_walker(Node *node, PlannerGlobal *glob) ...@@ -363,7 +363,7 @@ flatten_rtes_walker(Node *node, PlannerGlobal *glob)
return query_tree_walker((Query *) node, return query_tree_walker((Query *) node,
flatten_rtes_walker, flatten_rtes_walker,
(void *) glob, (void *) glob,
QTW_EXAMINE_RTES); QTW_EXAMINE_RTES_BEFORE);
} }
return expression_tree_walker(node, flatten_rtes_walker, return expression_tree_walker(node, flatten_rtes_walker,
(void *) glob); (void *) glob);
......
...@@ -761,7 +761,7 @@ IncrementVarSublevelsUp_walker(Node *node, ...@@ -761,7 +761,7 @@ IncrementVarSublevelsUp_walker(Node *node,
result = query_tree_walker((Query *) node, result = query_tree_walker((Query *) node,
IncrementVarSublevelsUp_walker, IncrementVarSublevelsUp_walker,
(void *) context, (void *) context,
QTW_EXAMINE_RTES); QTW_EXAMINE_RTES_BEFORE);
context->min_sublevels_up--; context->min_sublevels_up--;
return result; return result;
} }
...@@ -785,7 +785,7 @@ IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, ...@@ -785,7 +785,7 @@ IncrementVarSublevelsUp(Node *node, int delta_sublevels_up,
query_or_expression_tree_walker(node, query_or_expression_tree_walker(node,
IncrementVarSublevelsUp_walker, IncrementVarSublevelsUp_walker,
(void *) &context, (void *) &context,
QTW_EXAMINE_RTES); QTW_EXAMINE_RTES_BEFORE);
} }
/* /*
...@@ -804,7 +804,7 @@ IncrementVarSublevelsUp_rtable(List *rtable, int delta_sublevels_up, ...@@ -804,7 +804,7 @@ IncrementVarSublevelsUp_rtable(List *rtable, int delta_sublevels_up,
range_table_walker(rtable, range_table_walker(rtable,
IncrementVarSublevelsUp_walker, IncrementVarSublevelsUp_walker,
(void *) &context, (void *) &context,
QTW_EXAMINE_RTES); QTW_EXAMINE_RTES_BEFORE);
} }
......
...@@ -22,8 +22,11 @@ ...@@ -22,8 +22,11 @@
#define QTW_IGNORE_RC_SUBQUERIES 0x03 /* both of above */ #define QTW_IGNORE_RC_SUBQUERIES 0x03 /* both of above */
#define QTW_IGNORE_JOINALIASES 0x04 /* JOIN alias var lists */ #define QTW_IGNORE_JOINALIASES 0x04 /* JOIN alias var lists */
#define QTW_IGNORE_RANGE_TABLE 0x08 /* skip rangetable entirely */ #define QTW_IGNORE_RANGE_TABLE 0x08 /* skip rangetable entirely */
#define QTW_EXAMINE_RTES 0x10 /* examine RTEs */ #define QTW_EXAMINE_RTES_BEFORE 0x10 /* examine RTE nodes before their
#define QTW_DONT_COPY_QUERY 0x20 /* do not copy top Query */ * contents */
#define QTW_EXAMINE_RTES_AFTER 0x20 /* examine RTE nodes after their
* contents */
#define QTW_DONT_COPY_QUERY 0x40 /* do not copy top Query */
/* callback function for check_functions_in_node */ /* callback function for check_functions_in_node */
typedef bool (*check_function_callback) (Oid func_id, void *context); typedef bool (*check_function_callback) (Oid func_id, void *context);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment