PostgreSQL Source Code git master
Loading...
Searching...
No Matches
nodeSamplescan.c File Reference
#include "postgres.h"
#include "access/relscan.h"
#include "access/tableam.h"
#include "access/tsmapi.h"
#include "common/pg_prng.h"
#include "executor/executor.h"
#include "executor/nodeSamplescan.h"
#include "utils/fmgrprotos.h"
#include "utils/rel.h"
Include dependency graph for nodeSamplescan.c:

Go to the source code of this file.

Functions

static TupleTableSlotSampleNext (SampleScanState *node)
 
static void tablesample_init (SampleScanState *scanstate)
 
static TupleTableSlottablesample_getnext (SampleScanState *scanstate)
 
static bool SampleRecheck (SampleScanState *node, TupleTableSlot *slot)
 
static TupleTableSlotExecSampleScan (PlanState *pstate)
 
SampleScanStateExecInitSampleScan (SampleScan *node, EState *estate, int eflags)
 
void ExecEndSampleScan (SampleScanState *node)
 
void ExecReScanSampleScan (SampleScanState *node)
 

Function Documentation

◆ ExecEndSampleScan()

void ExecEndSampleScan ( SampleScanState node)

Definition at line 180 of file nodeSamplescan.c.

181{
182 /*
183 * Tell sampling function that we finished the scan.
184 */
185 if (node->tsmroutine->EndSampleScan)
186 node->tsmroutine->EndSampleScan(node);
187
188 /*
189 * close heap scan
190 */
191 if (node->ss.ss_currentScanDesc)
193}
struct TsmRoutine * tsmroutine
Definition execnodes.h:1659
struct TableScanDescData * ss_currentScanDesc
Definition execnodes.h:1635
EndSampleScan_function EndSampleScan
Definition tsmapi.h:75
static void table_endscan(TableScanDesc scan)
Definition tableam.h:1004

References TsmRoutine::EndSampleScan, SampleScanState::ss, ScanState::ss_currentScanDesc, table_endscan(), and SampleScanState::tsmroutine.

Referenced by ExecEndNode().

◆ ExecInitSampleScan()

SampleScanState * ExecInitSampleScan ( SampleScan node,
EState estate,
int  eflags 
)

Definition at line 93 of file nodeSamplescan.c.

94{
98
99 Assert(outerPlan(node) == NULL);
100 Assert(innerPlan(node) == NULL);
101
102 /*
103 * create state structure
104 */
106 scanstate->ss.ps.plan = (Plan *) node;
107 scanstate->ss.ps.state = estate;
108 scanstate->ss.ps.ExecProcNode = ExecSampleScan;
109
110 /*
111 * Miscellaneous initialization
112 *
113 * create expression context for node
114 */
115 ExecAssignExprContext(estate, &scanstate->ss.ps);
116
117 /*
118 * open the scan relation
119 */
120 scanstate->ss.ss_currentRelation =
122 node->scan.scanrelid,
123 eflags);
124
125 /* we won't set up the HeapScanDesc till later */
126 scanstate->ss.ss_currentScanDesc = NULL;
127
128 /* and create slot with appropriate rowtype */
129 ExecInitScanTupleSlot(estate, &scanstate->ss,
130 RelationGetDescr(scanstate->ss.ss_currentRelation),
131 table_slot_callbacks(scanstate->ss.ss_currentRelation),
133
134 /*
135 * Initialize result type and projection.
136 */
139
140 /*
141 * initialize child expressions
142 */
143 scanstate->ss.ps.qual =
144 ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
145
147 scanstate->repeatable =
148 ExecInitExpr(tsc->repeatable, (PlanState *) scanstate);
149
150 /*
151 * If we don't have a REPEATABLE clause, select a random seed. We want to
152 * do this just once, since the seed shouldn't change over rescans.
153 */
154 if (tsc->repeatable == NULL)
156
157 /*
158 * Finally, initialize the TABLESAMPLE method handler.
159 */
160 tsm = GetTsmRoutine(tsc->tsmhandler);
161 scanstate->tsmroutine = tsm;
162 scanstate->tsm_state = NULL;
163
164 if (tsm->InitSampleScan)
165 tsm->InitSampleScan(scanstate, eflags);
166
167 /* We'll do BeginSampleScan later; we can't evaluate params yet */
168 scanstate->begun = false;
169
170 return scanstate;
171}
#define Assert(condition)
Definition c.h:945
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition execExpr.c:143
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition execExpr.c:250
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition execExpr.c:356
void ExecAssignScanProjectionInfo(ScanState *node)
Definition execScan.c:81
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops, uint16 flags)
void ExecInitResultTypeTL(PlanState *planstate)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition execUtils.c:490
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition execUtils.c:747
static TupleTableSlot * ExecSampleScan(PlanState *pstate)
#define makeNode(_type_)
Definition nodes.h:161
uint32 pg_prng_uint32(pg_prng_state *state)
Definition pg_prng.c:227
pg_prng_state pg_global_prng_state
Definition pg_prng.c:34
#define innerPlan(node)
Definition plannodes.h:264
#define outerPlan(node)
Definition plannodes.h:265
static int fb(int x)
#define RelationGetDescr(relation)
Definition rel.h:540
struct TableSampleClause * tablesample
Definition plannodes.h:560
Index scanrelid
Definition plannodes.h:540
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition tableam.c:59
TsmRoutine * GetTsmRoutine(Oid tsmhandler)
Definition tablesample.c:27
#define TTS_FLAG_OBEYS_NOT_NULL_CONSTRAINTS
Definition tuptable.h:102

References Assert, ExecAssignExprContext(), ExecAssignScanProjectionInfo(), ExecInitExpr(), ExecInitExprList(), ExecInitQual(), ExecInitResultTypeTL(), ExecInitScanTupleSlot(), ExecOpenScanRelation(), ExecSampleScan(), fb(), GetTsmRoutine(), innerPlan, makeNode, outerPlan, pg_global_prng_state, pg_prng_uint32(), RelationGetDescr, SampleScan::scan, Scan::scanrelid, table_slot_callbacks(), SampleScan::tablesample, and TTS_FLAG_OBEYS_NOT_NULL_CONSTRAINTS.

Referenced by ExecInitNode().

◆ ExecReScanSampleScan()

void ExecReScanSampleScan ( SampleScanState node)

Definition at line 203 of file nodeSamplescan.c.

204{
205 /* Remember we need to do BeginSampleScan again (if we did it at all) */
206 node->begun = false;
207 node->done = false;
208 node->haveblock = false;
209 node->donetuples = 0;
210
211 ExecScanReScan(&node->ss);
212}
void ExecScanReScan(ScanState *node)
Definition execScan.c:108

References SampleScanState::begun, SampleScanState::done, SampleScanState::donetuples, ExecScanReScan(), SampleScanState::haveblock, and SampleScanState::ss.

Referenced by ExecReScan().

◆ ExecSampleScan()

static TupleTableSlot * ExecSampleScan ( PlanState pstate)
static

Definition at line 79 of file nodeSamplescan.c.

80{
82
83 return ExecScan(&node->ss,
86}
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition execScan.c:47
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition executor.h:583
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition executor.h:582
static TupleTableSlot * SampleNext(SampleScanState *node)
static bool SampleRecheck(SampleScanState *node, TupleTableSlot *slot)
#define castNode(_type_, nodeptr)
Definition nodes.h:182

References castNode, ExecScan(), SampleNext(), SampleRecheck(), and SampleScanState::ss.

Referenced by ExecInitSampleScan().

◆ SampleNext()

static TupleTableSlot * SampleNext ( SampleScanState node)
static

Definition at line 42 of file nodeSamplescan.c.

43{
44 /*
45 * if this is first call within a scan, initialize
46 */
47 if (!node->begun)
48 tablesample_init(node);
49
50 /*
51 * get the next tuple, and store it in our result slot
52 */
53 return tablesample_getnext(node);
54}
static void tablesample_init(SampleScanState *scanstate)
static TupleTableSlot * tablesample_getnext(SampleScanState *scanstate)

References SampleScanState::begun, tablesample_getnext(), and tablesample_init().

Referenced by ExecSampleScan().

◆ SampleRecheck()

static bool SampleRecheck ( SampleScanState node,
TupleTableSlot slot 
)
static

Definition at line 60 of file nodeSamplescan.c.

61{
62 /*
63 * No need to recheck for SampleScan, since like SeqScan we don't pass any
64 * checkable keys to heap_beginscan.
65 */
66 return true;
67}

Referenced by ExecSampleScan().

◆ tablesample_getnext()

static TupleTableSlot * tablesample_getnext ( SampleScanState scanstate)
static

Definition at line 321 of file nodeSamplescan.c.

322{
323 TableScanDesc scan = scanstate->ss.ss_currentScanDesc;
324 TupleTableSlot *slot = scanstate->ss.ss_ScanTupleSlot;
325
326 ExecClearTuple(slot);
327
328 if (scanstate->done)
329 return NULL;
330
331 for (;;)
332 {
333 if (!scanstate->haveblock)
334 {
336 {
337 scanstate->haveblock = false;
338 scanstate->done = true;
339
340 /* exhausted relation */
341 return NULL;
342 }
343
344 scanstate->haveblock = true;
345 }
346
347 if (!table_scan_sample_next_tuple(scan, scanstate, slot))
348 {
349 /*
350 * If we get here, it means we've exhausted the items on this page
351 * and it's time to move to the next.
352 */
353 scanstate->haveblock = false;
354 continue;
355 }
356
357 /* Found visible tuple, return it. */
358 break;
359 }
360
361 scanstate->donetuples++;
362
363 return slot;
364}
static bool table_scan_sample_next_block(TableScanDesc scan, SampleScanState *scanstate)
Definition tableam.h:1978
static bool table_scan_sample_next_tuple(TableScanDesc scan, SampleScanState *scanstate, TupleTableSlot *slot)
Definition tableam.h:1993
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:476

References ExecClearTuple(), fb(), table_scan_sample_next_block(), and table_scan_sample_next_tuple().

Referenced by SampleNext().

◆ tablesample_init()

static void tablesample_init ( SampleScanState scanstate)
static

Definition at line 219 of file nodeSamplescan.c.

220{
221 TsmRoutine *tsm = scanstate->tsmroutine;
222 ExprContext *econtext = scanstate->ss.ps.ps_ExprContext;
223 Datum *params;
224 Datum datum;
225 bool isnull;
226 uint32 seed;
227 bool allow_sync;
228 int i;
229 ListCell *arg;
230
231 scanstate->donetuples = 0;
232 params = palloc_array(Datum, list_length(scanstate->args));
233
234 i = 0;
235 foreach(arg, scanstate->args)
236 {
238
240 econtext,
241 &isnull);
242 if (isnull)
245 errmsg("TABLESAMPLE parameter cannot be null")));
246 i++;
247 }
248
249 if (scanstate->repeatable)
250 {
251 datum = ExecEvalExprSwitchContext(scanstate->repeatable,
252 econtext,
253 &isnull);
254 if (isnull)
257 errmsg("TABLESAMPLE REPEATABLE parameter cannot be null")));
258
259 /*
260 * The REPEATABLE parameter has been coerced to float8 by the parser.
261 * The reason for using float8 at the SQL level is that it will
262 * produce unsurprising results both for users used to databases that
263 * accept only integers in the REPEATABLE clause and for those who
264 * might expect that REPEATABLE works like setseed() (a float in the
265 * range from -1 to 1).
266 *
267 * We use hashfloat8() to convert the supplied value into a suitable
268 * seed. For regression-testing purposes, that has the convenient
269 * property that REPEATABLE(0) gives a machine-independent result.
270 */
272 }
273 else
274 {
275 /* Use the seed selected by ExecInitSampleScan */
276 seed = scanstate->seed;
277 }
278
279 /* Set default values for params that BeginSampleScan can adjust */
280 scanstate->use_bulkread = true;
281 scanstate->use_pagemode = true;
282
283 /* Let tablesample method do its thing */
284 tsm->BeginSampleScan(scanstate,
285 params,
286 list_length(scanstate->args),
287 seed);
288
289 /* We'll use syncscan if there's no NextSampleBlock function */
290 allow_sync = (tsm->NextSampleBlock == NULL);
291
292 /* Now we can create or reset the HeapScanDesc */
293 if (scanstate->ss.ss_currentScanDesc == NULL)
294 {
295 scanstate->ss.ss_currentScanDesc =
296 table_beginscan_sampling(scanstate->ss.ss_currentRelation,
297 scanstate->ss.ps.state->es_snapshot,
298 0, NULL,
299 scanstate->use_bulkread,
301 scanstate->use_pagemode);
302 }
303 else
304 {
305 table_rescan_set_params(scanstate->ss.ss_currentScanDesc, NULL,
306 scanstate->use_bulkread,
308 scanstate->use_pagemode);
309 }
310
311 pfree(params);
312
313 /* And we're initialized. */
314 scanstate->begun = true;
315}
uint32_t uint32
Definition c.h:618
Datum arg
Definition elog.c:1322
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition executor.h:439
#define palloc_array(type, count)
Definition fe_memutils.h:76
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
Datum hashfloat8(PG_FUNCTION_ARGS)
Definition hashfunc.c:194
int i
Definition isn.c:77
void pfree(void *pointer)
Definition mcxt.c:1616
static char * errmsg
#define lfirst(lc)
Definition pg_list.h:172
static int list_length(const List *l)
Definition pg_list.h:152
static uint32 DatumGetUInt32(Datum X)
Definition postgres.h:222
uint64_t Datum
Definition postgres.h:70
static void table_rescan_set_params(TableScanDesc scan, ScanKeyData *key, bool allow_strat, bool allow_sync, bool allow_pagemode)
Definition tableam.h:1027
static TableScanDesc table_beginscan_sampling(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, bool allow_strat, bool allow_sync, bool allow_pagemode)
Definition tableam.h:957

References arg, DatumGetUInt32(), DirectFunctionCall1, ereport, errcode(), errmsg, ERROR, ExecEvalExprSwitchContext(), fb(), hashfloat8(), i, lfirst, list_length(), palloc_array, pfree(), table_beginscan_sampling(), and table_rescan_set_params().

Referenced by SampleNext().