PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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-2025, 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"
21
23
24/* ----------------------------------------------------------------
25 * NamedTuplestoreScanNext
26 *
27 * This is a workhorse for ExecNamedTuplestoreScan
28 * ----------------------------------------------------------------
29 */
30static 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 */
51static 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 */
66static 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 */
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 */
163void
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:812
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:224
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:1998
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1942
const TupleTableSlotOps TTSOpsMinimalTuple
Definition: execTuples.c:86
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:485
#define EXEC_FLAG_BACKWARD
Definition: executor.h:68
#define EXEC_FLAG_REWIND
Definition: executor.h:67
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:487
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:486
#define EXEC_FLAG_MARK
Definition: executor.h:69
static TupleTableSlot * ExecNamedTuplestoreScan(PlanState *pstate)
static TupleTableSlot * NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
static bool NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot)
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
NamedTuplestoreScanState * ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
#define makeNode(_type_)
Definition: nodes.h:155
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
#define innerPlan(node)
Definition: plannodes.h:182
#define outerPlan(node)
Definition: plannodes.h:183
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:672
ScanDirection es_direction
Definition: execnodes.h:631
EphemeralNamedRelationMetadataData md
Tuplestorestate * relation
Definition: execnodes.h:2047
ExprState * qual
Definition: execnodes.h:1147
Plan * plan
Definition: execnodes.h:1126
EState * state
Definition: execnodes.h:1128
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1164
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1132
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1576
PlanState ps
Definition: execnodes.h:1573
bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
Definition: tuplestore.c:1130
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:507
void tuplestore_rescan(Tuplestorestate *state)
Definition: tuplestore.c:1285
int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags)
Definition: tuplestore.c:395
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454