]> granicus.if.org Git - postgresql/commitdiff
Split QTW_EXAMINE_RTES flag into QTW_EXAMINE_RTES_BEFORE/_AFTER.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 25 Jan 2019 22:09:45 +0000 (17:09 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 25 Jan 2019 22:09:45 +0000 (17:09 -0500)
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

src/backend/nodes/nodeFuncs.c
src/backend/optimizer/plan/setrefs.c
src/backend/rewrite/rewriteManip.c
src/include/nodes/nodeFuncs.h

index 19b65f681d12924628cc65d90b41814ef0f2b5e2..a806d51edcd748cc1d3c2cd4be35d25a7dc726e6 100644 (file)
@@ -2255,7 +2255,7 @@ expression_tree_walker(Node *node,
  * 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
  * 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.)
  */
 bool
@@ -2314,8 +2314,12 @@ range_table_walker(List *rtable,
        {
                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))
                                return true;
 
@@ -2355,6 +2359,10 @@ range_table_walker(List *rtable,
 
                if (walker(rte->securityQuals, context))
                        return true;
+
+               if (flags & QTW_EXAMINE_RTES_AFTER)
+                       if (walker(rte, context))
+                               return true;
        }
        return false;
 }
index 5d363edab80979ab14a83ed95cb42cf69c1e4eaa..6bd3b2d1ac14fd226f70e87238b2acbdc2bca9f6 100644 (file)
@@ -340,7 +340,7 @@ flatten_unplanned_rtes(PlannerGlobal *glob, RangeTblEntry *rte)
        (void) query_tree_walker(rte->subquery,
                                                         flatten_rtes_walker,
                                                         (void *) glob,
-                                                        QTW_EXAMINE_RTES);
+                                                        QTW_EXAMINE_RTES_BEFORE);
 }
 
 static bool
@@ -363,7 +363,7 @@ flatten_rtes_walker(Node *node, PlannerGlobal *glob)
                return query_tree_walker((Query *) node,
                                                                 flatten_rtes_walker,
                                                                 (void *) glob,
-                                                                QTW_EXAMINE_RTES);
+                                                                QTW_EXAMINE_RTES_BEFORE);
        }
        return expression_tree_walker(node, flatten_rtes_walker,
                                                                  (void *) glob);
index acbe669294d8d5a7046cd69ee505dbd039c732be..fd7a751c9a80cb102671066740223b2bbe2b937e 100644 (file)
@@ -761,7 +761,7 @@ IncrementVarSublevelsUp_walker(Node *node,
                result = query_tree_walker((Query *) node,
                                                                   IncrementVarSublevelsUp_walker,
                                                                   (void *) context,
-                                                                  QTW_EXAMINE_RTES);
+                                                                  QTW_EXAMINE_RTES_BEFORE);
                context->min_sublevels_up--;
                return result;
        }
@@ -785,7 +785,7 @@ IncrementVarSublevelsUp(Node *node, int delta_sublevels_up,
        query_or_expression_tree_walker(node,
                                                                        IncrementVarSublevelsUp_walker,
                                                                        (void *) &context,
-                                                                       QTW_EXAMINE_RTES);
+                                                                       QTW_EXAMINE_RTES_BEFORE);
 }
 
 /*
@@ -804,7 +804,7 @@ IncrementVarSublevelsUp_rtable(List *rtable, int delta_sublevels_up,
        range_table_walker(rtable,
                                           IncrementVarSublevelsUp_walker,
                                           (void *) &context,
-                                          QTW_EXAMINE_RTES);
+                                          QTW_EXAMINE_RTES_BEFORE);
 }
 
 
index 7739600db26e55628778d93d1e2a3833d90954d9..a9f76bbb330a3a271363be317fd8caea3e09fe7d 100644 (file)
 #define QTW_IGNORE_RC_SUBQUERIES       0x03    /* both of above */
 #define QTW_IGNORE_JOINALIASES         0x04    /* JOIN alias var lists */
 #define QTW_IGNORE_RANGE_TABLE         0x08    /* skip rangetable entirely */
-#define QTW_EXAMINE_RTES                       0x10    /* examine RTEs */
-#define QTW_DONT_COPY_QUERY                    0x20    /* do not copy top Query */
+#define QTW_EXAMINE_RTES_BEFORE                0x10    /* examine RTE nodes before their
+                                                                                        * 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 */
 typedef bool (*check_function_callback) (Oid func_id, void *context);