]> granicus.if.org Git - postgresql/blobdiff - src/backend/executor/nodeSamplescan.c
Make some small planner API cleanups.
[postgresql] / src / backend / executor / nodeSamplescan.c
index 9c686a045bd7de8cb7b2a1e985297f4795b1c520..da4a65fd30ad99b65027ece482844f62f8b0ec91 100644 (file)
@@ -3,7 +3,7 @@
  * nodeSamplescan.c
  *       Support routines for sample scans of relations (table sampling).
  *
- * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
@@ -15,6 +15,7 @@
 #include "postgres.h"
 
 #include "access/hash.h"
+#include "access/heapam.h"
 #include "access/relscan.h"
 #include "access/tsmapi.h"
 #include "executor/executor.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
+#include "utils/builtins.h"
 #include "utils/rel.h"
-#include "utils/tqual.h"
 
-static void InitScanRelation(SampleScanState *node, EState *estate, int eflags);
 static TupleTableSlot *SampleNext(SampleScanState *node);
 static void tablesample_init(SampleScanState *scanstate);
 static HeapTuple tablesample_getnext(SampleScanState *scanstate);
@@ -63,10 +63,9 @@ SampleNext(SampleScanState *node)
        slot = node->ss.ss_ScanTupleSlot;
 
        if (tuple)
-               ExecStoreTuple(tuple,   /* tuple to store */
-                                          slot,        /* slot to store in */
-                                          node->ss.ss_currentScanDesc->rs_cbuf,        /* tuple's buffer */
-                                          false);      /* don't pfree this pointer */
+               ExecStoreBufferHeapTuple(tuple, /* tuple to store */
+                                                                slot,  /* slot to store in */
+                                                                node->ss.ss_currentScanDesc->rs_cbuf); /* tuple's buffer */
        else
                ExecClearTuple(slot);
 
@@ -95,43 +94,16 @@ SampleRecheck(SampleScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
-ExecSampleScan(SampleScanState *node)
+static TupleTableSlot *
+ExecSampleScan(PlanState *pstate)
 {
-       return ExecScan((ScanState *) node,
+       SampleScanState *node = castNode(SampleScanState, pstate);
+
+       return ExecScan(&node->ss,
                                        (ExecScanAccessMtd) SampleNext,
                                        (ExecScanRecheckMtd) SampleRecheck);
 }
 
-/* ----------------------------------------------------------------
- *             InitScanRelation
- *
- *             Set up to access the scan relation.
- * ----------------------------------------------------------------
- */
-static void
-InitScanRelation(SampleScanState *node, EState *estate, int eflags)
-{
-       Relation        currentRelation;
-
-       /*
-        * get the relation object id from the relid'th entry in the range table,
-        * open that relation and acquire appropriate lock on it.
-        */
-       currentRelation = ExecOpenScanRelation(estate,
-                                                  ((SampleScan *) node->ss.ps.plan)->scan.scanrelid,
-                                                                                  eflags);
-
-       node->ss.ss_currentRelation = currentRelation;
-
-       /* we won't set up the HeapScanDesc till later */
-       node->ss.ss_currentScanDesc = NULL;
-
-       /* and report the scan tuple slot's rowtype */
-       ExecAssignScanType(&node->ss, RelationGetDescr(currentRelation));
-}
-
-
 /* ----------------------------------------------------------------
  *             ExecInitSampleScan
  * ----------------------------------------------------------------
@@ -152,6 +124,7 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
        scanstate = makeNode(SampleScanState);
        scanstate->ss.ps.plan = (Plan *) node;
        scanstate->ss.ps.state = estate;
+       scanstate->ss.ps.ExecProcNode = ExecSampleScan;
 
        /*
         * Miscellaneous initialization
@@ -161,40 +134,36 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
        ExecAssignExprContext(estate, &scanstate->ss.ps);
 
        /*
-        * initialize child expressions
+        * open the scan relation
         */
-       scanstate->ss.ps.targetlist = (List *)
-               ExecInitExpr((Expr *) node->scan.plan.targetlist,
-                                        (PlanState *) scanstate);
-       scanstate->ss.ps.qual = (List *)
-               ExecInitExpr((Expr *) node->scan.plan.qual,
-                                        (PlanState *) scanstate);
-
-       scanstate->args = (List *)
-               ExecInitExpr((Expr *) tsc->args,
-                                        (PlanState *) scanstate);
-       scanstate->repeatable =
-               ExecInitExpr(tsc->repeatable,
-                                        (PlanState *) scanstate);
+       scanstate->ss.ss_currentRelation =
+               ExecOpenScanRelation(estate,
+                                                        node->scan.scanrelid,
+                                                        eflags);
 
-       /*
-        * tuple table initialization
-        */
-       ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
-       ExecInitScanTupleSlot(estate, &scanstate->ss);
+       /* we won't set up the HeapScanDesc till later */
+       scanstate->ss.ss_currentScanDesc = NULL;
+
+       /* and create slot with appropriate rowtype */
+       ExecInitScanTupleSlot(estate, &scanstate->ss,
+                                                 RelationGetDescr(scanstate->ss.ss_currentRelation),
+                                                 &TTSOpsBufferHeapTuple);
 
        /*
-        * initialize scan relation
+        * Initialize result type and projection.
         */
-       InitScanRelation(scanstate, estate, eflags);
-
-       scanstate->ss.ps.ps_TupFromTlist = false;
+       ExecInitResultTypeTL(&scanstate->ss.ps);
+       ExecAssignScanProjectionInfo(&scanstate->ss);
 
        /*
-        * Initialize result tuple type and projection info.
+        * initialize child expressions
         */
-       ExecAssignResultTypeFromTL(&scanstate->ss.ps);
-       ExecAssignScanProjectionInfo(&scanstate->ss);
+       scanstate->ss.ps.qual =
+               ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+
+       scanstate->args = ExecInitExprList(tsc->args, (PlanState *) scanstate);
+       scanstate->repeatable =
+               ExecInitExpr(tsc->repeatable, (PlanState *) scanstate);
 
        /*
         * If we don't have a REPEATABLE clause, select a random seed.  We want to
@@ -242,7 +211,8 @@ ExecEndSampleScan(SampleScanState *node)
        /*
         * clean out the tuple table
         */
-       ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
+       if (node->ss.ps.ps_ResultTupleSlot)
+               ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
        ExecClearTuple(node->ss.ss_ScanTupleSlot);
 
        /*
@@ -250,11 +220,6 @@ ExecEndSampleScan(SampleScanState *node)
         */
        if (node->ss.ss_currentScanDesc)
                heap_endscan(node->ss.ss_currentScanDesc);
-
-       /*
-        * close the heap relation.
-        */
-       ExecCloseScanRelation(node->ss.ss_currentRelation);
 }
 
 /* ----------------------------------------------------------------
@@ -299,8 +264,7 @@ tablesample_init(SampleScanState *scanstate)
 
                params[i] = ExecEvalExprSwitchContext(argstate,
                                                                                          econtext,
-                                                                                         &isnull,
-                                                                                         NULL);
+                                                                                         &isnull);
                if (isnull)
                        ereport(ERROR,
                                        (errcode(ERRCODE_INVALID_TABLESAMPLE_ARGUMENT),
@@ -312,12 +276,11 @@ tablesample_init(SampleScanState *scanstate)
        {
                datum = ExecEvalExprSwitchContext(scanstate->repeatable,
                                                                                  econtext,
-                                                                                 &isnull,
-                                                                                 NULL);
+                                                                                 &isnull);
                if (isnull)
                        ereport(ERROR,
                                        (errcode(ERRCODE_INVALID_TABLESAMPLE_REPEAT),
-                                errmsg("TABLESAMPLE REPEATABLE parameter cannot be null")));
+                                        errmsg("TABLESAMPLE REPEATABLE parameter cannot be null")));
 
                /*
                 * The REPEATABLE parameter has been coerced to float8 by the parser.
@@ -425,7 +388,7 @@ tablesample_getnext(SampleScanState *scanstate)
        else
        {
                /* continue from previously returned page/tuple */
-               blockno = scan->rs_cblock;              /* current page */
+               blockno = scan->rs_cblock;      /* current page */
        }
 
        /*