]> granicus.if.org Git - postgresql/blob - src/backend/executor/execScan.c
Another PGINDENT run that changes variable indenting and case label indenting. Also...
[postgresql] / src / backend / executor / execScan.c
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  * Copyright (c) 1994, Regents of the University of California
11  *
12  *
13  * IDENTIFICATION
14  *        $Header: /cvsroot/pgsql/src/backend/executor/execScan.c,v 1.5 1997/09/08 02:22:34 momjian Exp $
15  *
16  *-------------------------------------------------------------------------
17  */
18
19 #include <sys/types.h>
20 #include <sys/file.h>
21 #include "postgres.h"
22
23 #include "executor/executor.h"
24
25 /* ----------------------------------------------------------------
26  *              ExecScan
27  *
28  *              Scans the relation using the 'access method' indicated and
29  *              returns the next qualifying tuple in the direction specified
30  *              in the global variable ExecDirection.
31  *              The access method returns the next tuple and execScan() is
32  *              responisble for checking the tuple returned against the qual-clause.
33  *
34  *              Conditions:
35  *                -- the "cursor" maintained by the AMI is positioned at the tuple
36  *                       returned previously.
37  *
38  *              Initial States:
39  *                -- the relation indicated is opened for scanning so that the
40  *                       "cursor" is positioned before the first qualifying tuple.
41  *
42  *              May need to put startmmgr  and endmmgr in here.
43  * ----------------------------------------------------------------
44  */
45 TupleTableSlot *
46 ExecScan(Scan * node,
47                  TupleTableSlot * (*accessMtd) ())              /* function returning a
48                                                                                                  * tuple */
49 {
50         CommonScanState *scanstate;
51         EState     *estate;
52         List       *qual;
53         bool            isDone;
54
55         TupleTableSlot *slot;
56         TupleTableSlot *resultSlot;
57         HeapTuple       newTuple;
58
59         ExprContext *econtext;
60         ProjectionInfo *projInfo;
61
62
63         /* ----------------
64          *      initialize misc variables
65          * ----------------
66          */
67         newTuple = NULL;
68         slot = NULL;
69
70         estate = node->plan.state;
71         scanstate = node->scanstate;
72
73         /* ----------------
74          *      get the expression context
75          * ----------------
76          */
77         econtext = scanstate->cstate.cs_ExprContext;
78
79         /* ----------------
80          *      initialize fields in ExprContext which don't change
81          *      in the course of the scan..
82          * ----------------
83          */
84         qual = node->plan.qual;
85         econtext->ecxt_relation = scanstate->css_currentRelation;
86         econtext->ecxt_relid = node->scanrelid;
87
88         if (scanstate->cstate.cs_TupFromTlist)
89         {
90                 projInfo = scanstate->cstate.cs_ProjInfo;
91                 resultSlot = ExecProject(projInfo, &isDone);
92                 if (!isDone)
93                         return resultSlot;
94         }
95
96         /*
97          * get a tuple from the access method loop until we obtain a tuple
98          * which passes the qualification.
99          */
100         for (;;)
101         {
102                 slot = (TupleTableSlot *) (*accessMtd) (node);
103
104                 /* ----------------
105                  *      if the slot returned by the accessMtd contains
106                  *      NULL, then it means there is nothing more to scan
107                  *      so we just return the empty slot.
108                  * ----------------
109                  */
110                 if (TupIsNull(slot))
111                         return slot;
112
113                 /* ----------------
114                  *       place the current tuple into the expr context
115                  * ----------------
116                  */
117                 econtext->ecxt_scantuple = slot;
118
119                 /* ----------------
120                  *      check that the current tuple satisfies the qual-clause
121                  *      if our qualification succeeds then we
122                  *      leave the loop.
123                  * ----------------
124                  */
125
126                 /*
127                  * add a check for non-nil qual here to avoid a function call to
128                  * ExecQual() when the qual is nil
129                  */
130                 if (!qual || ExecQual(qual, econtext) == true)
131                         break;
132         }
133
134         /* ----------------
135          *      form a projection tuple, store it in the result tuple
136          *      slot and return it.
137          * ----------------
138          */
139         projInfo = scanstate->cstate.cs_ProjInfo;
140
141         resultSlot = ExecProject(projInfo, &isDone);
142         scanstate->cstate.cs_TupFromTlist = !isDone;
143
144         return resultSlot;
145 }