]> granicus.if.org Git - postgresql/blobdiff - src/backend/optimizer/plan/setrefs.c
Add a Gather executor node.
[postgresql] / src / backend / optimizer / plan / setrefs.c
index 517409d28a07d7133186e22b6846f5ad3f24fbd9..b1cede2ef0d20e3c5d984c09797e9c8fc11c70ba 100644 (file)
@@ -140,7 +140,6 @@ static bool fix_opfuncids_walker(Node *node, void *context);
 static bool extract_query_dependencies_walker(Node *node,
                                                                  PlannerInfo *context);
 
-
 /*****************************************************************************
  *
  *             SUBPLAN REFERENCES
@@ -175,6 +174,8 @@ static bool extract_query_dependencies_walker(Node *node,
  * Currently, relations and user-defined functions are the only types of
  * objects that are explicitly tracked this way.
  *
+ * 7. We assign every plan node in the tree a unique ID.
+ *
  * We also perform one final optimization step, which is to delete
  * SubqueryScan plan nodes that aren't doing anything useful (ie, have
  * no qual and a no-op targetlist).  The reason for doing this last is that
@@ -373,10 +374,10 @@ flatten_rtes_walker(Node *node, PlannerGlobal *glob)
  *
  * In the flat rangetable, we zero out substructure pointers that are not
  * needed by the executor; this reduces the storage space and copying cost
- * for cached plans.  We keep only the alias and eref Alias fields, which are
- * needed by EXPLAIN, and the selectedCols, insertedCols and updatedCols
- * bitmaps, which are needed for executor-startup permissions checking and for
- * trigger event checking.
+ * for cached plans.  We keep only the ctename, alias and eref Alias fields,
+ * which are needed by EXPLAIN, and the selectedCols, insertedCols and
+ * updatedCols bitmaps, which are needed for executor-startup permissions
+ * checking and for trigger event checking.
  */
 static void
 add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte)
@@ -388,6 +389,7 @@ add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte)
        memcpy(newrte, rte, sizeof(RangeTblEntry));
 
        /* zap unneeded sub-structure */
+       newrte->tablesample = NULL;
        newrte->subquery = NULL;
        newrte->joinaliasvars = NIL;
        newrte->functions = NIL;
@@ -396,6 +398,7 @@ add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte)
        newrte->ctecoltypes = NIL;
        newrte->ctecoltypmods = NIL;
        newrte->ctecolcollations = NIL;
+       newrte->securityQuals = NIL;
 
        glob->finalrtable = lappend(glob->finalrtable, newrte);
 
@@ -435,6 +438,9 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
        if (plan == NULL)
                return NULL;
 
+       /* Assign this node a unique ID. */
+       plan->plan_node_id = root->glob->lastPlanNodeId++;
+
        /*
         * Plan-type-specific fixes
         */
@@ -451,6 +457,19 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
                                        fix_scan_list(root, splan->plan.qual, rtoffset);
                        }
                        break;
+               case T_SampleScan:
+                       {
+                               SampleScan *splan = (SampleScan *) plan;
+
+                               splan->scan.scanrelid += rtoffset;
+                               splan->scan.plan.targetlist =
+                                       fix_scan_list(root, splan->scan.plan.targetlist, rtoffset);
+                               splan->scan.plan.qual =
+                                       fix_scan_list(root, splan->scan.plan.qual, rtoffset);
+                               splan->tablesample = (TableSampleClause *)
+                                       fix_scan_expr(root, (Node *) splan->tablesample, rtoffset);
+                       }
+                       break;
                case T_IndexScan:
                        {
                                IndexScan  *splan = (IndexScan *) plan;
@@ -588,6 +607,7 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
                case T_Sort:
                case T_Unique:
                case T_SetOp:
+               case T_Gather:
 
                        /*
                         * These plan types don't actually bother to evaluate their
@@ -645,6 +665,8 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
                        }
                        break;
                case T_Agg:
+                       set_upper_references(root, plan, rtoffset);
+                       break;
                case T_Group:
                        set_upper_references(root, plan, rtoffset);
                        break;
@@ -764,6 +786,8 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
                                                                          linitial_int(splan->resultRelations),
                                                                          rtoffset);
 
+                                       pfree(itlist);
+
                                        splan->exclRelTlist =
                                                fix_scan_list(root, splan->exclRelTlist, rtoffset);
                                }
@@ -1081,7 +1105,7 @@ set_foreignscan_references(PlannerInfo *root,
 
        if (fscan->fdw_scan_tlist != NIL || fscan->scan.scanrelid == 0)
        {
-               /* Adjust tlist, qual, fdw_exprs to reference custom scan tuple */
+               /* Adjust tlist, qual, fdw_exprs to reference foreign scan tuple */
                indexed_tlist *itlist = build_tlist_index(fscan->fdw_scan_tlist);
 
                fscan->scan.plan.targetlist = (List *)
@@ -1139,6 +1163,8 @@ set_customscan_references(PlannerInfo *root,
                                                  CustomScan *cscan,
                                                  int rtoffset)
 {
+       ListCell   *lc;
+
        /* Adjust scanrelid if it's valid */
        if (cscan->scan.scanrelid > 0)
                cscan->scan.scanrelid += rtoffset;
@@ -1182,6 +1208,12 @@ set_customscan_references(PlannerInfo *root,
                        fix_scan_list(root, cscan->custom_exprs, rtoffset);
        }
 
+       /* Adjust child plan-nodes recursively, if needed */
+       foreach(lc, cscan->custom_plans)
+       {
+               lfirst(lc) = set_plan_refs(root, (Plan *) lfirst(lc), rtoffset);
+       }
+
        /* Adjust custom_relids if needed */
        if (rtoffset > 0)
        {
@@ -1217,7 +1249,8 @@ copyVar(Var *var)
  * This is code that is common to all variants of expression-fixing.
  * We must look up operator opcode info for OpExpr and related nodes,
  * add OIDs from regclass Const nodes into root->glob->relationOids, and
- * add catalog TIDs for user-defined functions into root->glob->invalItems.
+ * add PlanInvalItems for user-defined functions into root->glob->invalItems.
+ * We also fill in column index lists for GROUPING() expressions.
  *
  * We assume it's okay to update opcode info in-place.  So this could possibly
  * scribble on the planner's input data structures, but it's OK.
@@ -1281,6 +1314,31 @@ fix_expr_common(PlannerInfo *root, Node *node)
                                lappend_oid(root->glob->relationOids,
                                                        DatumGetObjectId(con->constvalue));
        }
+       else if (IsA(node, GroupingFunc))
+       {
+               GroupingFunc *g = (GroupingFunc *) node;
+               AttrNumber *grouping_map = root->grouping_map;
+
+               /* If there are no grouping sets, we don't need this. */
+
+               Assert(grouping_map || g->cols == NIL);
+
+               if (grouping_map)
+               {
+                       ListCell   *lc;
+                       List       *cols = NIL;
+
+                       foreach(lc, g->refs)
+                       {
+                               cols = lappend_int(cols, grouping_map[lfirst_int(lc)]);
+                       }
+
+                       Assert(!g->cols || equal(cols, g->cols));
+
+                       if (!g->cols)
+                               g->cols = cols;
+               }
+       }
 }
 
 /*
@@ -1414,7 +1472,7 @@ fix_scan_expr_walker(Node *node, fix_scan_expr_context *context)
  *       subplans, by setting the varnos to OUTER_VAR or INNER_VAR and setting
  *       attno values to the result domain number of either the corresponding
  *       outer or inner join tuple item.  Also perform opcode lookup for these
- *       expressions. and add regclass OIDs to root->glob->relationOids.
+ *       expressions, and add regclass OIDs to root->glob->relationOids.
  */
 static void
 set_join_references(PlannerInfo *root, Join *join, int rtoffset)
@@ -2175,6 +2233,7 @@ set_returning_clause_references(PlannerInfo *root,
        return rlist;
 }
 
+
 /*****************************************************************************
  *                                     OPERATOR REGPROC LOOKUP
  *****************************************************************************/