]> granicus.if.org Git - postgresql/blobdiff - src/backend/executor/nodeGroup.c
Make some small planner API cleanups.
[postgresql] / src / backend / executor / nodeGroup.c
index f1cdbaa4e6731b6163c0575f41ac7dc9b2545653..655084d7b564858b1a447b79be6905acd9352bf6 100644 (file)
@@ -3,7 +3,7 @@
  * nodeGroup.c
  *       Routines to handle group nodes (used for queries with GROUP BY clause).
  *
- * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
@@ -25,6 +25,7 @@
 #include "executor/executor.h"
 #include "executor/nodeGroup.h"
 #include "miscadmin.h"
+#include "utils/memutils.h"
 
 
 /*
@@ -37,8 +38,6 @@ ExecGroup(PlanState *pstate)
 {
        GroupState *node = castNode(GroupState, pstate);
        ExprContext *econtext;
-       int                     numCols;
-       AttrNumber *grpColIdx;
        TupleTableSlot *firsttupleslot;
        TupleTableSlot *outerslot;
 
@@ -50,8 +49,6 @@ ExecGroup(PlanState *pstate)
        if (node->grp_done)
                return NULL;
        econtext = node->ss.ps.ps_ExprContext;
-       numCols = ((Group *) node->ss.ps.plan)->numCols;
-       grpColIdx = ((Group *) node->ss.ps.plan)->grpColIdx;
 
        /*
         * The ScanTupleSlot holds the (copied) first tuple of each group.
@@ -59,7 +56,7 @@ ExecGroup(PlanState *pstate)
        firsttupleslot = node->ss.ss_ScanTupleSlot;
 
        /*
-        * We need not call ResetExprContext here because execTuplesMatch will
+        * We need not call ResetExprContext here because ExecQualAndReset() will
         * reset the per-tuple memory context once per input tuple.
         */
 
@@ -124,10 +121,9 @@ ExecGroup(PlanState *pstate)
                         * Compare with first tuple and see if this tuple is of the same
                         * group.  If so, ignore it and keep scanning.
                         */
-                       if (!execTuplesMatch(firsttupleslot, outerslot,
-                                                                numCols, grpColIdx,
-                                                                node->eqfunctions,
-                                                                econtext->ecxt_per_tuple_memory))
+                       econtext->ecxt_innertuple = firsttupleslot;
+                       econtext->ecxt_outertuple = outerslot;
+                       if (!ExecQualAndReset(node->eqfunction, econtext))
                                break;
                }
 
@@ -166,6 +162,7 @@ GroupState *
 ExecInitGroup(Group *node, EState *estate, int eflags)
 {
        GroupState *grpstate;
+       const TupleTableSlotOps *tts_ops;
 
        /* check for unsupported flags */
        Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -184,40 +181,38 @@ ExecInitGroup(Group *node, EState *estate, int eflags)
         */
        ExecAssignExprContext(estate, &grpstate->ss.ps);
 
-       /*
-        * tuple table initialization
-        */
-       ExecInitScanTupleSlot(estate, &grpstate->ss);
-       ExecInitResultTupleSlot(estate, &grpstate->ss.ps);
-
-       /*
-        * initialize child expressions
-        */
-       grpstate->ss.ps.qual =
-               ExecInitQual(node->plan.qual, (PlanState *) grpstate);
-
        /*
         * initialize child nodes
         */
        outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags);
 
        /*
-        * initialize tuple type.
+        * Initialize scan slot and type.
         */
-       ExecAssignScanTypeFromOuterPlan(&grpstate->ss);
+       tts_ops = ExecGetResultSlotOps(outerPlanState(&grpstate->ss), NULL);
+       ExecCreateScanSlotFromOuterPlan(estate, &grpstate->ss, tts_ops);
 
        /*
-        * Initialize result tuple type and projection info.
+        * Initialize result slot, type and projection.
         */
-       ExecAssignResultTypeFromTL(&grpstate->ss.ps);
+       ExecInitResultTupleSlotTL(&grpstate->ss.ps, &TTSOpsVirtual);
        ExecAssignProjectionInfo(&grpstate->ss.ps, NULL);
 
+       /*
+        * initialize child expressions
+        */
+       grpstate->ss.ps.qual =
+               ExecInitQual(node->plan.qual, (PlanState *) grpstate);
+
        /*
         * Precompute fmgr lookup data for inner loop
         */
-       grpstate->eqfunctions =
-               execTuplesMatchPrepare(node->numCols,
-                                                          node->grpOperators);
+       grpstate->eqfunction =
+               execTuplesMatchPrepare(ExecGetResultType(outerPlanState(grpstate)),
+                                                          node->numCols,
+                                                          node->grpColIdx,
+                                                          node->grpOperators,
+                                                          &grpstate->ss.ps);
 
        return grpstate;
 }