Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * execScan.c
4 : : * This code provides support for generalized relation scans. ExecScan
5 : : * is passed a node and a pointer to a function to "do the right thing"
6 : : * and return a tuple from the relation. ExecScan then does the tedious
7 : : * stuff - checking the qualification and projecting the tuple
8 : : * appropriately.
9 : : *
10 : : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
11 : : * Portions Copyright (c) 1994, Regents of the University of California
12 : : *
13 : : *
14 : : * IDENTIFICATION
15 : : * src/backend/executor/execScan.c
16 : : *
17 : : *-------------------------------------------------------------------------
18 : : */
19 : : #include "postgres.h"
20 : :
21 : : #include "executor/executor.h"
22 : : #include "executor/execScan.h"
23 : : #include "miscadmin.h"
24 : :
25 : : /* ----------------------------------------------------------------
26 : : * ExecScan
27 : : *
28 : : * Scans the relation using the 'access method' indicated and
29 : : * returns the next qualifying tuple.
30 : : * The access method returns the next tuple and ExecScan() is
31 : : * responsible for checking the tuple returned against the qual-clause.
32 : : *
33 : : * A 'recheck method' must also be provided that can check an
34 : : * arbitrary tuple of the relation against any qual conditions
35 : : * that are implemented internal to the access method.
36 : : *
37 : : * Conditions:
38 : : * -- the "cursor" maintained by the AMI is positioned at the tuple
39 : : * returned previously.
40 : : *
41 : : * Initial States:
42 : : * -- the relation indicated is opened for scanning so that the
43 : : * "cursor" is positioned before the first qualifying tuple.
44 : : * ----------------------------------------------------------------
45 : : */
46 : : TupleTableSlot *
8065 bruce@momjian.us 47 :CBC 15080684 : ExecScan(ScanState *node,
48 : : ExecScanAccessMtd accessMtd, /* function returning a tuple */
49 : : ExecScanRecheckMtd recheckMtd)
50 : : {
51 : : EPQState *epqstate;
52 : : ExprState *qual;
53 : : ProjectionInfo *projInfo;
54 : :
228 amitlan@postgresql.o 55 : 15080684 : epqstate = node->ps.state->es_epq_active;
8311 tgl@sss.pgh.pa.us 56 : 15080684 : qual = node->ps.qual;
8251 57 : 15080684 : projInfo = node->ps.ps_ProjInfo;
58 : :
228 amitlan@postgresql.o 59 : 15080684 : return ExecScanExtended(node,
60 : : accessMtd,
61 : : recheckMtd,
62 : : epqstate,
63 : : qual,
64 : : projInfo);
65 : : }
66 : :
67 : : /*
68 : : * ExecAssignScanProjectionInfo
69 : : * Set up projection info for a scan node, if necessary.
70 : : *
71 : : * We can avoid a projection step if the requested tlist exactly matches
72 : : * the underlying tuple type. If so, we just set ps_ProjInfo to NULL.
73 : : * Note that this case occurs not only for simple "SELECT * FROM ...", but
74 : : * also in most cases where there are joins or other processing nodes above
75 : : * the scan node, because the planner will preferentially generate a matching
76 : : * tlist.
77 : : *
78 : : * The scan slot's descriptor must have been set already.
79 : : */
80 : : void
8065 bruce@momjian.us 81 : 253844 : ExecAssignScanProjectionInfo(ScanState *node)
82 : : {
8069 83 : 253844 : Scan *scan = (Scan *) node->ps.plan;
2842 rhaas@postgresql.org 84 : 253844 : TupleDesc tupdesc = node->ss_ScanTupleSlot->tts_tupleDescriptor;
85 : :
86 : 253844 : ExecConditionalAssignProjectionInfo(&node->ps, tupdesc, scan->scanrelid);
3772 tgl@sss.pgh.pa.us 87 : 253844 : }
88 : :
89 : : /*
90 : : * ExecAssignScanProjectionInfoWithVarno
91 : : * As above, but caller can specify varno expected in Vars in the tlist.
92 : : */
93 : : void
1452 94 : 8831 : ExecAssignScanProjectionInfoWithVarno(ScanState *node, int varno)
95 : : {
2842 rhaas@postgresql.org 96 : 8831 : TupleDesc tupdesc = node->ss_ScanTupleSlot->tts_tupleDescriptor;
97 : :
98 : 8831 : ExecConditionalAssignProjectionInfo(&node->ps, tupdesc, varno);
8251 tgl@sss.pgh.pa.us 99 : 8831 : }
100 : :
101 : : /*
102 : : * ExecScanReScan
103 : : *
104 : : * This must be called within the ReScan function of any plan node type
105 : : * that uses ExecScan().
106 : : */
107 : : void
5794 108 : 1060181 : ExecScanReScan(ScanState *node)
109 : : {
110 : 1060181 : EState *estate = node->ps.state;
111 : :
112 : : /*
113 : : * We must clear the scan tuple so that observers (e.g., execCurrent.c)
114 : : * can tell that this plan node is not positioned on a tuple.
115 : : */
2540 116 : 1060181 : ExecClearTuple(node->ss_ScanTupleSlot);
117 : :
118 : : /*
119 : : * Rescan EvalPlanQual tuple(s) if we're inside an EvalPlanQual recheck.
120 : : * But don't lose the "blocked" status of blocked target relations.
121 : : */
2193 andres@anarazel.de 122 [ + + ]: 1060181 : if (estate->es_epq_active != NULL)
123 : : {
124 : 180 : EPQState *epqstate = estate->es_epq_active;
5794 tgl@sss.pgh.pa.us 125 : 180 : Index scanrelid = ((Scan *) node->ps.plan)->scanrelid;
126 : :
3560 rhaas@postgresql.org 127 [ + - ]: 180 : if (scanrelid > 0)
841 tgl@sss.pgh.pa.us 128 : 180 : epqstate->relsubs_done[scanrelid - 1] =
129 : 180 : epqstate->relsubs_blocked[scanrelid - 1];
130 : : else
131 : : {
132 : : Bitmapset *relids;
3560 rhaas@postgresql.org 133 :UBC 0 : int rtindex = -1;
134 : :
135 : : /*
136 : : * If an FDW or custom scan provider has replaced the join with a
137 : : * scan, there are multiple RTIs; reset the epqScanDone flag for
138 : : * all of them.
139 : : */
140 [ # # ]: 0 : if (IsA(node->ps.plan, ForeignScan))
950 tgl@sss.pgh.pa.us 141 : 0 : relids = ((ForeignScan *) node->ps.plan)->fs_base_relids;
3560 rhaas@postgresql.org 142 [ # # ]: 0 : else if (IsA(node->ps.plan, CustomScan))
143 : 0 : relids = ((CustomScan *) node->ps.plan)->custom_relids;
144 : : else
145 [ # # ]: 0 : elog(ERROR, "unexpected scan node: %d",
146 : : (int) nodeTag(node->ps.plan));
147 : :
148 [ # # ]: 0 : while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
149 : : {
150 [ # # ]: 0 : Assert(rtindex > 0);
841 tgl@sss.pgh.pa.us 151 : 0 : epqstate->relsubs_done[rtindex - 1] =
152 : 0 : epqstate->relsubs_blocked[rtindex - 1];
153 : : }
154 : : }
155 : : }
5794 tgl@sss.pgh.pa.us 156 :CBC 1060181 : }
|