2727 *
2828 *
2929 * IDENTIFICATION
30- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.130 2000/10/16 17:08:06 momjian Exp $
30+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.131 2000/10/26 21:35:15 tgl Exp $
3131 *
3232 *-------------------------------------------------------------------------
3333 */
@@ -52,11 +52,10 @@ static TupleDesc InitPlan(CmdType operation,
5252EState * estate );
5353static void EndPlan (Plan * plan ,EState * estate );
5454static TupleTableSlot * ExecutePlan (EState * estate ,Plan * plan ,
55- CmdType operation ,
56- int offsetTuples ,
57- int numberTuples ,
58- ScanDirection direction ,
59- DestReceiver * destfunc );
55+ CmdType operation ,
56+ long numberTuples ,
57+ ScanDirection direction ,
58+ DestReceiver * destfunc );
6059static void ExecRetrieve (TupleTableSlot * slot ,
6160DestReceiver * destfunc ,
6261EState * estate );
@@ -153,19 +152,18 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
153152 * EXEC_RETONE: return one tuple but don't 'retrieve' it
154153 * used in postquel function processing
155154 *
155+ *Note: count = 0 is interpreted as "no limit".
156+ *
156157 * ----------------------------------------------------------------
157158 */
158159TupleTableSlot *
159- ExecutorRun (QueryDesc * queryDesc ,EState * estate ,int feature ,
160- Node * limoffset ,Node * limcount )
160+ ExecutorRun (QueryDesc * queryDesc ,EState * estate ,int feature ,long count )
161161{
162162CmdType operation ;
163163Plan * plan ;
164164TupleTableSlot * result ;
165165CommandDest dest ;
166166DestReceiver * destfunc ;
167- int offset = 0 ;
168- int count = 0 ;
169167
170168/*
171169 * sanity checks
@@ -191,111 +189,21 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
191189 */
192190(* destfunc -> setup ) (destfunc , (TupleDesc )NULL );
193191
194- /*
195- * if given get the offset of the LIMIT clause
196- */
197- if (limoffset != NULL )
198- {
199- Const * coffset ;
200- Param * poffset ;
201- ParamListInfo paramLI ;
202- int i ;
203-
204- switch (nodeTag (limoffset ))
205- {
206- case T_Const :
207- coffset = (Const * )limoffset ;
208- offset = (int ) (coffset -> constvalue );
209- break ;
210-
211- case T_Param :
212- poffset = (Param * )limoffset ;
213- paramLI = estate -> es_param_list_info ;
214-
215- if (paramLI == NULL )
216- elog (ERROR ,"parameter for limit offset not in executor state" );
217- for (i = 0 ;paramLI [i ].kind != PARAM_INVALID ;i ++ )
218- {
219- if (paramLI [i ].kind == PARAM_NUM && paramLI [i ].id == poffset -> paramid )
220- break ;
221- }
222- if (paramLI [i ].kind == PARAM_INVALID )
223- elog (ERROR ,"parameter for limit offset not in executor state" );
224- if (paramLI [i ].isnull )
225- elog (ERROR ,"limit offset cannot be NULL value" );
226- offset = (int ) (paramLI [i ].value );
227-
228- break ;
229-
230- default :
231- elog (ERROR ,"unexpected node type %d as limit offset" ,nodeTag (limoffset ));
232- }
233-
234- if (offset < 0 )
235- elog (ERROR ,"limit offset cannot be negative" );
236- }
237-
238- /*
239- * if given get the count of the LIMIT clause
240- */
241- if (limcount != NULL )
242- {
243- Const * ccount ;
244- Param * pcount ;
245- ParamListInfo paramLI ;
246- int i ;
247-
248- switch (nodeTag (limcount ))
249- {
250- case T_Const :
251- ccount = (Const * )limcount ;
252- count = (int ) (ccount -> constvalue );
253- break ;
254-
255- case T_Param :
256- pcount = (Param * )limcount ;
257- paramLI = estate -> es_param_list_info ;
258-
259- if (paramLI == NULL )
260- elog (ERROR ,"parameter for limit count not in executor state" );
261- for (i = 0 ;paramLI [i ].kind != PARAM_INVALID ;i ++ )
262- {
263- if (paramLI [i ].kind == PARAM_NUM && paramLI [i ].id == pcount -> paramid )
264- break ;
265- }
266- if (paramLI [i ].kind == PARAM_INVALID )
267- elog (ERROR ,"parameter for limit count not in executor state" );
268- if (paramLI [i ].isnull )
269- elog (ERROR ,"limit count cannot be NULL value" );
270- count = (int ) (paramLI [i ].value );
271-
272- break ;
273-
274- default :
275- elog (ERROR ,"unexpected node type %d as limit count" ,nodeTag (limcount ));
276- }
277-
278- if (count < 0 )
279- elog (ERROR ,"limit count cannot be negative" );
280- }
281-
282192switch (feature )
283193{
284-
285194case EXEC_RUN :
286195result = ExecutePlan (estate ,
287196plan ,
288197operation ,
289- offset ,
290198count ,
291199ForwardScanDirection ,
292200destfunc );
293201break ;
202+
294203case EXEC_FOR :
295204result = ExecutePlan (estate ,
296205plan ,
297206operation ,
298- offset ,
299207count ,
300208ForwardScanDirection ,
301209destfunc );
@@ -308,7 +216,6 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
308216result = ExecutePlan (estate ,
309217plan ,
310218operation ,
311- offset ,
312219count ,
313220BackwardScanDirection ,
314221destfunc );
@@ -322,14 +229,14 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
322229result = ExecutePlan (estate ,
323230plan ,
324231operation ,
325- 0 ,
326232ONE_TUPLE ,
327233ForwardScanDirection ,
328234destfunc );
329235break ;
236+
330237default :
331- result = NULL ;
332238elog (DEBUG ,"ExecutorRun: Unknown feature %d" ,feature );
239+ result = NULL ;
333240break ;
334241}
335242
@@ -917,33 +824,30 @@ EndPlan(Plan *plan, EState *estate)
917824/* ----------------------------------------------------------------
918825 *ExecutePlan
919826 *
920- *processes the query plan to retrieve 'tupleCount ' tuples in the
827+ *processes the query plan to retrieve 'numberTuples ' tuples in the
921828 *direction specified.
922829 *Retrieves all tuples if tupleCount is 0
923830 *
924- *result is either a slot containinga tuple in the case
831+ *result is either a slot containingthe last tuple in the case
925832 *of a RETRIEVE or NULL otherwise.
926833 *
834+ * Note: the ctid attribute is a 'junk' attribute that is removed before the
835+ * user can see it
927836 * ----------------------------------------------------------------
928837 */
929-
930- /* the ctid attribute is a 'junk' attribute that is removed before the
931- user can see it*/
932-
933838static TupleTableSlot *
934839ExecutePlan (EState * estate ,
935840Plan * plan ,
936841CmdType operation ,
937- int offsetTuples ,
938- int numberTuples ,
842+ long numberTuples ,
939843ScanDirection direction ,
940844DestReceiver * destfunc )
941845{
942846JunkFilter * junkfilter ;
943847TupleTableSlot * slot ;
944848ItemPointer tupleid = NULL ;
945849ItemPointerData tuple_ctid ;
946- int current_tuple_count ;
850+ long current_tuple_count ;
947851TupleTableSlot * result ;
948852
949853/*
@@ -990,17 +894,6 @@ lnext:;
990894break ;
991895}
992896
993- /*
994- * For now we completely execute the plan and skip result tuples
995- * if requested by LIMIT offset. Finally we should try to do it in
996- * deeper levels if possible (during index scan) - Jan
997- */
998- if (offsetTuples > 0 )
999- {
1000- -- offsetTuples ;
1001- continue ;
1002- }
1003-
1004897/*
1005898 * if we have a junk filter, then project a new tuple with the
1006899 * junk removed.
@@ -1152,10 +1045,10 @@ lnext:;
11521045}
11531046
11541047/*
1155- * check our tuple count.. if we'vereturned the proper number
1156- * thenreturn , else loop again and process more tuples..
1048+ * check our tuple count.. if we'veprocessed the proper number
1049+ * thenquit , else loop again and process more tuples..
11571050 */
1158- current_tuple_count += 1 ;
1051+ current_tuple_count ++ ;
11591052if (numberTuples == current_tuple_count )
11601053break ;
11611054}