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);