1 /*-------------------------------------------------------------------------
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
10 * Copyright (c) 1994, Regents of the University of California
14 * $Header: /cvsroot/pgsql/src/backend/executor/execScan.c,v 1.5 1997/09/08 02:22:34 momjian Exp $
16 *-------------------------------------------------------------------------
19 #include <sys/types.h>
23 #include "executor/executor.h"
25 /* ----------------------------------------------------------------
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.
35 * -- the "cursor" maintained by the AMI is positioned at the tuple
36 * returned previously.
39 * -- the relation indicated is opened for scanning so that the
40 * "cursor" is positioned before the first qualifying tuple.
42 * May need to put startmmgr and endmmgr in here.
43 * ----------------------------------------------------------------
47 TupleTableSlot * (*accessMtd) ()) /* function returning a
50 CommonScanState *scanstate;
56 TupleTableSlot *resultSlot;
59 ExprContext *econtext;
60 ProjectionInfo *projInfo;
64 * initialize misc variables
70 estate = node->plan.state;
71 scanstate = node->scanstate;
74 * get the expression context
77 econtext = scanstate->cstate.cs_ExprContext;
80 * initialize fields in ExprContext which don't change
81 * in the course of the scan..
84 qual = node->plan.qual;
85 econtext->ecxt_relation = scanstate->css_currentRelation;
86 econtext->ecxt_relid = node->scanrelid;
88 if (scanstate->cstate.cs_TupFromTlist)
90 projInfo = scanstate->cstate.cs_ProjInfo;
91 resultSlot = ExecProject(projInfo, &isDone);
97 * get a tuple from the access method loop until we obtain a tuple
98 * which passes the qualification.
102 slot = (TupleTableSlot *) (*accessMtd) (node);
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.
114 * place the current tuple into the expr context
117 econtext->ecxt_scantuple = slot;
120 * check that the current tuple satisfies the qual-clause
121 * if our qualification succeeds then we
127 * add a check for non-nil qual here to avoid a function call to
128 * ExecQual() when the qual is nil
130 if (!qual || ExecQual(qual, econtext) == true)
135 * form a projection tuple, store it in the result tuple
136 * slot and return it.
139 projInfo = scanstate->cstate.cs_ProjInfo;
141 resultSlot = ExecProject(projInfo, &isDone);
142 scanstate->cstate.cs_TupFromTlist = !isDone;