PostgreSQL Source Code  git master
nodeNamedtuplestorescan.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * nodeNamedtuplestorescan.c
4  * routines to handle NamedTuplestoreScan nodes.
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/executor/nodeNamedtuplestorescan.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres.h"
17 
18 #include "executor/executor.h"
20 #include "utils/queryenvironment.h"
21 
23 
24 /* ----------------------------------------------------------------
25  * NamedTuplestoreScanNext
26  *
27  * This is a workhorse for ExecNamedTuplestoreScan
28  * ----------------------------------------------------------------
29  */
30 static TupleTableSlot *
32 {
33  TupleTableSlot *slot;
34 
35  /* We intentionally do not support backward scan. */
37 
38  /*
39  * Get the next tuple from tuplestore. Return NULL if no more tuples.
40  */
41  slot = node->ss.ss_ScanTupleSlot;
43  (void) tuplestore_gettupleslot(node->relation, true, false, slot);
44  return slot;
45 }
46 
47 /*
48  * NamedTuplestoreScanRecheck -- access method routine to recheck a tuple in
49  * EvalPlanQual
50  */
51 static bool
53 {
54  /* nothing to check */
55  return true;
56 }
57 
58 /* ----------------------------------------------------------------
59  * ExecNamedTuplestoreScan(node)
60  *
61  * Scans the CTE sequentially and returns the next qualifying tuple.
62  * We call the ExecScan() routine and pass it the appropriate
63  * access method functions.
64  * ----------------------------------------------------------------
65  */
66 static TupleTableSlot *
68 {
70 
71  return ExecScan(&node->ss,
74 }
75 
76 
77 /* ----------------------------------------------------------------
78  * ExecInitNamedTuplestoreScan
79  * ----------------------------------------------------------------
80  */
83 {
84  NamedTuplestoreScanState *scanstate;
86 
87  /* check for unsupported flags */
88  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
89 
90  /*
91  * NamedTuplestoreScan should not have any children.
92  */
93  Assert(outerPlan(node) == NULL);
94  Assert(innerPlan(node) == NULL);
95 
96  /*
97  * create new NamedTuplestoreScanState for node
98  */
100  scanstate->ss.ps.plan = (Plan *) node;
101  scanstate->ss.ps.state = estate;
103 
104  enr = get_ENR(estate->es_queryEnv, node->enrname);
105  if (!enr)
106  elog(ERROR, "executor could not find named tuplestore \"%s\"",
107  node->enrname);
108 
109  Assert(enr->reldata);
110  scanstate->relation = (Tuplestorestate *) enr->reldata;
111  scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
112  scanstate->readptr =
114 
115  /*
116  * The new read pointer copies its position from read pointer 0, which
117  * could be anywhere, so explicitly rewind it.
118  */
119  tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr);
120  tuplestore_rescan(scanstate->relation);
121 
122  /*
123  * XXX: Should we add a function to free that read pointer when done?
124  *
125  * This was attempted, but it did not improve performance or memory usage
126  * in any tested cases.
127  */
128 
129  /*
130  * Miscellaneous initialization
131  *
132  * create expression context for node
133  */
134  ExecAssignExprContext(estate, &scanstate->ss.ps);
135 
136  /*
137  * The scan tuple type is specified for the tuplestore.
138  */
139  ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc,
141 
142  /*
143  * Initialize result type and projection.
144  */
145  ExecInitResultTypeTL(&scanstate->ss.ps);
146  ExecAssignScanProjectionInfo(&scanstate->ss);
147 
148  /*
149  * initialize child expressions
150  */
151  scanstate->ss.ps.qual =
152  ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
153 
154  return scanstate;
155 }
156 
157 /* ----------------------------------------------------------------
158  * ExecReScanNamedTuplestoreScan
159  *
160  * Rescans the relation.
161  * ----------------------------------------------------------------
162  */
163 void
165 {
166  Tuplestorestate *tuplestorestate = node->relation;
167 
168  if (node->ss.ps.ps_ResultTupleSlot)
170 
171  ExecScanReScan(&node->ss);
172 
173  /*
174  * Rewind my own pointer.
175  */
176  tuplestore_select_read_pointer(tuplestorestate, node->readptr);
177  tuplestore_rescan(tuplestorestate);
178 }
#define Assert(condition)
Definition: c.h:858
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:220
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:156
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:270
void ExecScanReScan(ScanState *node)
Definition: execScan.c:297
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1898
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1842
const TupleTableSlotOps TTSOpsMinimalTuple
Definition: execTuples.c:86
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:483
#define EXEC_FLAG_BACKWARD
Definition: executor.h:68
#define EXEC_FLAG_REWIND
Definition: executor.h:67
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:473
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:474
#define EXEC_FLAG_MARK
Definition: executor.h:69
static TupleTableSlot * ExecNamedTuplestoreScan(PlanState *pstate)
NamedTuplestoreScanState * ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
static TupleTableSlot * NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
static bool NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot)
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
#define makeNode(_type_)
Definition: nodes.h:155
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
#define innerPlan(node)
Definition: plannodes.h:181
#define outerPlan(node)
Definition: plannodes.h:182
TupleDesc ENRMetadataGetTupDesc(EphemeralNamedRelationMetadata enrmd)
EphemeralNamedRelation get_ENR(QueryEnvironment *queryEnv, const char *name)
#define ScanDirectionIsForward(direction)
Definition: sdir.h:64
QueryEnvironment * es_queryEnv
Definition: execnodes.h:664
ScanDirection es_direction
Definition: execnodes.h:623
EphemeralNamedRelationMetadataData md
Tuplestorestate * relation
Definition: execnodes.h:2013
ExprState * qual
Definition: execnodes.h:1138
Plan * plan
Definition: execnodes.h:1117
EState * state
Definition: execnodes.h:1119
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1155
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1123
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1567
PlanState ps
Definition: execnodes.h:1564
bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
Definition: tuplestore.c:1078
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:473
void tuplestore_rescan(Tuplestorestate *state)
Definition: tuplestore.c:1233
int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags)
Definition: tuplestore.c:383
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454