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-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"
19 : : #include "executor/nodeNamedtuplestorescan.h"
20 : : #include "utils/queryenvironment.h"
21 : :
22 : : static TupleTableSlot *NamedTuplestoreScanNext(NamedTuplestoreScanState *node);
23 : :
24 : : /* ----------------------------------------------------------------
25 : : * NamedTuplestoreScanNext
26 : : *
27 : : * This is a workhorse for ExecNamedTuplestoreScan
28 : : * ----------------------------------------------------------------
29 : : */
30 : : static TupleTableSlot *
2571 kgrittn@postgresql.o 31 :CBC 33306 : NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
32 : : {
33 : : TupleTableSlot *slot;
34 : :
35 : : /* We intentionally do not support backward scan. */
36 [ - + ]: 33306 : Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));
37 : :
38 : : /*
39 : : * Get the next tuple from tuplestore. Return NULL if no more tuples.
40 : : */
41 : 33306 : slot = node->ss.ss_ScanTupleSlot;
2238 tgl@sss.pgh.pa.us 42 : 33306 : tuplestore_select_read_pointer(node->relation, node->readptr);
2571 kgrittn@postgresql.o 43 : 33306 : (void) tuplestore_gettupleslot(node->relation, true, false, slot);
44 : 33306 : return slot;
45 : : }
46 : :
47 : : /*
48 : : * NamedTuplestoreScanRecheck -- access method routine to recheck a tuple in
49 : : * EvalPlanQual
50 : : */
51 : : static bool
2571 kgrittn@postgresql.o 52 :UBC 0 : NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot)
53 : : {
54 : : /* nothing to check */
55 : 0 : 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 *
2463 andres@anarazel.de 67 :CBC 33306 : ExecNamedTuplestoreScan(PlanState *pstate)
68 : : {
69 : 33306 : NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);
70 : :
2571 kgrittn@postgresql.o 71 : 33306 : return ExecScan(&node->ss,
72 : : (ExecScanAccessMtd) NamedTuplestoreScanNext,
73 : : (ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
74 : : }
75 : :
76 : :
77 : : /* ----------------------------------------------------------------
78 : : * ExecInitNamedTuplestoreScan
79 : : * ----------------------------------------------------------------
80 : : */
81 : : NamedTuplestoreScanState *
82 : 330 : ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
83 : : {
84 : : NamedTuplestoreScanState *scanstate;
85 : : EphemeralNamedRelation enr;
86 : :
87 : : /* check for unsupported flags */
88 [ - + ]: 330 : Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
89 : :
90 : : /*
91 : : * NamedTuplestoreScan should not have any children.
92 : : */
93 [ - + ]: 330 : Assert(outerPlan(node) == NULL);
94 [ - + ]: 330 : Assert(innerPlan(node) == NULL);
95 : :
96 : : /*
97 : : * create new NamedTuplestoreScanState for node
98 : : */
99 : 330 : scanstate = makeNode(NamedTuplestoreScanState);
100 : 330 : scanstate->ss.ps.plan = (Plan *) node;
101 : 330 : scanstate->ss.ps.state = estate;
2463 andres@anarazel.de 102 : 330 : scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;
103 : :
2571 kgrittn@postgresql.o 104 : 330 : enr = get_ENR(estate->es_queryEnv, node->enrname);
105 [ - + ]: 330 : if (!enr)
2571 kgrittn@postgresql.o 106 [ # # ]:UBC 0 : elog(ERROR, "executor could not find named tuplestore \"%s\"",
107 : : node->enrname);
108 : :
2571 kgrittn@postgresql.o 109 [ - + ]:CBC 330 : Assert(enr->reldata);
110 : 330 : scanstate->relation = (Tuplestorestate *) enr->reldata;
111 : 330 : scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
112 : 330 : scanstate->readptr =
2532 rhaas@postgresql.org 113 : 330 : tuplestore_alloc_read_pointer(scanstate->relation, EXEC_FLAG_REWIND);
114 : :
115 : : /*
116 : : * The new read pointer copies its position from read pointer 0, which
117 : : * could be anywhere, so explicitly rewind it.
118 : : */
2238 tgl@sss.pgh.pa.us 119 : 330 : tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr);
2571 kgrittn@postgresql.o 120 : 330 : 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 : 330 : ExecAssignExprContext(estate, &scanstate->ss.ps);
135 : :
136 : : /*
137 : : * The scan tuple type is specified for the tuplestore.
138 : : */
1977 andres@anarazel.de 139 : 330 : ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc,
140 : : &TTSOpsMinimalTuple);
141 : :
142 : : /*
143 : : * Initialize result type and projection.
144 : : */
1983 145 : 330 : ExecInitResultTypeTL(&scanstate->ss.ps);
146 : 330 : ExecAssignScanProjectionInfo(&scanstate->ss);
147 : :
148 : : /*
149 : : * initialize child expressions
150 : : */
151 : 330 : scanstate->ss.ps.qual =
152 : 330 : ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
153 : :
2571 kgrittn@postgresql.o 154 : 330 : return scanstate;
155 : : }
156 : :
157 : : /* ----------------------------------------------------------------
158 : : * ExecReScanNamedTuplestoreScan
159 : : *
160 : : * Rescans the relation.
161 : : * ----------------------------------------------------------------
162 : : */
163 : : void
2571 kgrittn@postgresql.o 164 :UBC 0 : ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
165 : : {
166 : 0 : Tuplestorestate *tuplestorestate = node->relation;
167 : :
1983 andres@anarazel.de 168 [ # # ]: 0 : if (node->ss.ps.ps_ResultTupleSlot)
169 : 0 : ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
170 : :
2571 kgrittn@postgresql.o 171 : 0 : ExecScanReScan(&node->ss);
172 : :
173 : : /*
174 : : * Rewind my own pointer.
175 : : */
176 : 0 : tuplestore_select_read_pointer(tuplestorestate, node->readptr);
177 : 0 : tuplestore_rescan(tuplestorestate);
178 : 0 : }
|