Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * nodeNamedtuplestorescan.c
4 : : * routines to handle NamedTuplestoreScan nodes.
5 : : *
6 : : * Portions Copyright (c) 1996-2026, 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"
19 : : #include "executor/nodeNamedtuplestorescan.h"
20 : : #include "utils/queryenvironment.h"
21 : : #include "utils/tuplestore.h"
22 : :
23 : : static TupleTableSlot *NamedTuplestoreScanNext(NamedTuplestoreScanState *node);
24 : :
25 : : /* ----------------------------------------------------------------
26 : : * NamedTuplestoreScanNext
27 : : *
28 : : * This is a workhorse for ExecNamedTuplestoreScan
29 : : * ----------------------------------------------------------------
30 : : */
31 : : static TupleTableSlot *
3322 kgrittn@postgresql.o 32 :CBC 44600 : NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
33 : : {
34 : : TupleTableSlot *slot;
35 : :
36 : : /* We intentionally do not support backward scan. */
37 [ - + ]: 44600 : Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));
38 : :
39 : : /*
40 : : * Get the next tuple from tuplestore. Return NULL if no more tuples.
41 : : */
42 : 44600 : slot = node->ss.ss_ScanTupleSlot;
2989 tgl@sss.pgh.pa.us 43 : 44600 : tuplestore_select_read_pointer(node->relation, node->readptr);
3322 kgrittn@postgresql.o 44 : 44600 : (void) tuplestore_gettupleslot(node->relation, true, false, slot);
45 : 44600 : return slot;
46 : : }
47 : :
48 : : /*
49 : : * NamedTuplestoreScanRecheck -- access method routine to recheck a tuple in
50 : : * EvalPlanQual
51 : : */
52 : : static bool
3322 kgrittn@postgresql.o 53 :UBC 0 : NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot)
54 : : {
55 : : /* nothing to check */
56 : 0 : return true;
57 : : }
58 : :
59 : : /* ----------------------------------------------------------------
60 : : * ExecNamedTuplestoreScan(node)
61 : : *
62 : : * Scans the CTE sequentially and returns the next qualifying tuple.
63 : : * We call the ExecScan() routine and pass it the appropriate
64 : : * access method functions.
65 : : * ----------------------------------------------------------------
66 : : */
67 : : static TupleTableSlot *
3214 andres@anarazel.de 68 :CBC 44600 : ExecNamedTuplestoreScan(PlanState *pstate)
69 : : {
70 : 44600 : NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);
71 : :
3322 kgrittn@postgresql.o 72 : 44600 : return ExecScan(&node->ss,
73 : : (ExecScanAccessMtd) NamedTuplestoreScanNext,
74 : : (ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
75 : : }
76 : :
77 : :
78 : : /* ----------------------------------------------------------------
79 : : * ExecInitNamedTuplestoreScan
80 : : * ----------------------------------------------------------------
81 : : */
82 : : NamedTuplestoreScanState *
83 : 530 : ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
84 : : {
85 : : NamedTuplestoreScanState *scanstate;
86 : : EphemeralNamedRelation enr;
87 : :
88 : : /* check for unsupported flags */
89 [ - + ]: 530 : Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
90 : :
91 : : /*
92 : : * NamedTuplestoreScan should not have any children.
93 : : */
94 [ - + ]: 530 : Assert(outerPlan(node) == NULL);
95 [ - + ]: 530 : Assert(innerPlan(node) == NULL);
96 : :
97 : : /*
98 : : * create new NamedTuplestoreScanState for node
99 : : */
100 : 530 : scanstate = makeNode(NamedTuplestoreScanState);
101 : 530 : scanstate->ss.ps.plan = (Plan *) node;
102 : 530 : scanstate->ss.ps.state = estate;
3214 andres@anarazel.de 103 : 530 : scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;
104 : :
3322 kgrittn@postgresql.o 105 : 530 : enr = get_ENR(estate->es_queryEnv, node->enrname);
106 [ - + ]: 530 : if (!enr)
3322 kgrittn@postgresql.o 107 [ # # ]:UBC 0 : elog(ERROR, "executor could not find named tuplestore \"%s\"",
108 : : node->enrname);
109 : :
3322 kgrittn@postgresql.o 110 [ - + ]:CBC 530 : Assert(enr->reldata);
111 : 530 : scanstate->relation = (Tuplestorestate *) enr->reldata;
112 : 530 : scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
113 : 530 : scanstate->readptr =
3283 rhaas@postgresql.org 114 : 530 : tuplestore_alloc_read_pointer(scanstate->relation, EXEC_FLAG_REWIND);
115 : :
116 : : /*
117 : : * The new read pointer copies its position from read pointer 0, which
118 : : * could be anywhere, so explicitly rewind it.
119 : : */
2989 tgl@sss.pgh.pa.us 120 : 530 : tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr);
3322 kgrittn@postgresql.o 121 : 530 : tuplestore_rescan(scanstate->relation);
122 : :
123 : : /*
124 : : * XXX: Should we add a function to free that read pointer when done?
125 : : *
126 : : * This was attempted, but it did not improve performance or memory usage
127 : : * in any tested cases.
128 : : */
129 : :
130 : : /*
131 : : * Miscellaneous initialization
132 : : *
133 : : * create expression context for node
134 : : */
135 : 530 : ExecAssignExprContext(estate, &scanstate->ss.ps);
136 : :
137 : : /*
138 : : * The scan tuple type is specified for the tuplestore.
139 : : */
2728 andres@anarazel.de 140 : 530 : ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc,
141 : : &TTSOpsMinimalTuple, 0);
142 : :
143 : : /*
144 : : * Initialize result type and projection.
145 : : */
2734 146 : 530 : ExecInitResultTypeTL(&scanstate->ss.ps);
147 : 530 : ExecAssignScanProjectionInfo(&scanstate->ss);
148 : :
149 : : /*
150 : : * initialize child expressions
151 : : */
152 : 530 : scanstate->ss.ps.qual =
153 : 530 : ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
154 : :
3322 kgrittn@postgresql.o 155 : 530 : return scanstate;
156 : : }
157 : :
158 : : /* ----------------------------------------------------------------
159 : : * ExecReScanNamedTuplestoreScan
160 : : *
161 : : * Rescans the relation.
162 : : * ----------------------------------------------------------------
163 : : */
164 : : void
3322 kgrittn@postgresql.o 165 :UBC 0 : ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
166 : : {
167 : 0 : Tuplestorestate *tuplestorestate = node->relation;
168 : :
2734 andres@anarazel.de 169 [ # # ]: 0 : if (node->ss.ps.ps_ResultTupleSlot)
170 : 0 : ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
171 : :
3322 kgrittn@postgresql.o 172 : 0 : ExecScanReScan(&node->ss);
173 : :
174 : : /*
175 : : * Rewind my own pointer.
176 : : */
177 : 0 : tuplestore_select_read_pointer(tuplestorestate, node->readptr);
178 : 0 : tuplestore_rescan(tuplestorestate);
179 : 0 : }
|