Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2f35b4e

Browse files
committed
Re-implement LIMIT/OFFSET as a plan node type, instead of a hack in
ExecutorRun. This allows LIMIT to work in a view. Also, LIMIT in acursor declaration will behave in a reasonable fashion, whereas beforeit was overridden by the FETCH count.
1 parentc9476ba commit2f35b4e

File tree

26 files changed

+572
-232
lines changed

26 files changed

+572
-232
lines changed

‎src/backend/commands/command.c

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.107 2000/10/16 17:08:05 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.108 2000/10/26 21:34:44 tgl Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -111,7 +111,6 @@ PerformPortalFetch(char *name,
111111
intfeature;
112112
QueryDesc*queryDesc;
113113
MemoryContextoldcontext;
114-
Constlimcount;
115114

116115
/* ----------------
117116
*sanity checks
@@ -123,20 +122,6 @@ PerformPortalFetch(char *name,
123122
return;
124123
}
125124

126-
/* ----------------
127-
*Create a const node from the given count value
128-
* ----------------
129-
*/
130-
memset(&limcount,0,sizeof(limcount));
131-
limcount.type=T_Const;
132-
limcount.consttype=INT4OID;
133-
limcount.constlen=sizeof(int4);
134-
limcount.constvalue=Int32GetDatum(count);
135-
limcount.constisnull= false;
136-
limcount.constbyval= true;
137-
limcount.constisset= false;
138-
limcount.constiscast= false;
139-
140125
/* ----------------
141126
*get the portal from the portal name
142127
* ----------------
@@ -156,8 +141,7 @@ PerformPortalFetch(char *name,
156141
oldcontext=MemoryContextSwitchTo(PortalGetHeapMemory(portal));
157142

158143
/* ----------------
159-
*setup "feature" to tell the executor what direction and
160-
*how many tuples to fetch.
144+
*setup "feature" to tell the executor which direction to go in.
161145
* ----------------
162146
*/
163147
if (forward)
@@ -166,7 +150,7 @@ PerformPortalFetch(char *name,
166150
feature=EXEC_BACK;
167151

168152
/* ----------------
169-
*tell the destination to prepare torecieve some tuples
153+
*tell the destination to prepare toreceive some tuples
170154
* ----------------
171155
*/
172156
queryDesc=PortalGetQueryDesc(portal);
@@ -194,8 +178,7 @@ PerformPortalFetch(char *name,
194178
*execute the portal fetch operation
195179
* ----------------
196180
*/
197-
ExecutorRun(queryDesc,PortalGetState(portal),feature,
198-
(Node*)NULL, (Node*)&limcount);
181+
ExecutorRun(queryDesc,PortalGetState(portal),feature, (long)count);
199182

200183
if (dest==None)/* MOVE */
201184
pfree(queryDesc);

‎src/backend/commands/explain.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
66
* Portions Copyright (c) 1994-5, Regents of the University of California
77
*
8-
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.60 2000/10/05 19:11:26 tgl Exp $
8+
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.61 2000/10/26 21:34:44 tgl Exp $
99
*
1010
*/
1111

@@ -217,6 +217,9 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
217217
break;
218218
}
219219
break;
220+
caseT_Limit:
221+
pname="Limit";
222+
break;
220223
caseT_Hash:
221224
pname="Hash";
222225
break;

‎src/backend/executor/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Makefile for executor
55
#
66
# IDENTIFICATION
7-
# $Header: /cvsroot/pgsql/src/backend/executor/Makefile,v 1.15 2000/10/05 19:11:26 tgl Exp $
7+
# $Header: /cvsroot/pgsql/src/backend/executor/Makefile,v 1.16 2000/10/26 21:35:15 tgl Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -17,8 +17,8 @@ OBJS = execAmi.o execFlatten.o execJunk.o execMain.o \
1717
execUtils.o functions.o nodeAppend.o nodeAgg.o nodeHash.o\
1818
nodeHashjoin.o nodeIndexscan.o nodeMaterial.o nodeMergejoin.o\
1919
nodeNestloop.o nodeResult.o nodeSeqscan.o nodeSetOp.o nodeSort.o\
20-
nodeUnique.onodeGroup.ospi.o nodeSubplan.o\
21-
nodeSubqueryscan.o nodeTidscan.o
20+
nodeUnique.onodeLimit.onodeGroup.o nodeSubplan.o\
21+
nodeSubqueryscan.o nodeTidscan.o spi.o
2222

2323
all: SUBSYS.o
2424

‎src/backend/executor/execAmi.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
*$Id: execAmi.c,v 1.53 2000/10/05 19:11:26 tgl Exp $
9+
*$Id: execAmi.c,v 1.54 2000/10/26 21:35:15 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -37,6 +37,7 @@
3737
#include"executor/nodeHashjoin.h"
3838
#include"executor/nodeIndexscan.h"
3939
#include"executor/nodeTidscan.h"
40+
#include"executor/nodeLimit.h"
4041
#include"executor/nodeMaterial.h"
4142
#include"executor/nodeMergejoin.h"
4243
#include"executor/nodeNestloop.h"
@@ -350,6 +351,10 @@ ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
350351
ExecReScanSetOp((SetOp*)node,exprCtxt,parent);
351352
break;
352353

354+
caseT_Limit:
355+
ExecReScanLimit((Limit*)node,exprCtxt,parent);
356+
break;
357+
353358
caseT_Sort:
354359
ExecReScanSort((Sort*)node,exprCtxt,parent);
355360
break;

‎src/backend/executor/execMain.c

Lines changed: 20 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
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,
5252
EState*estate);
5353
staticvoidEndPlan(Plan*plan,EState*estate);
5454
staticTupleTableSlot*ExecutePlan(EState*estate,Plan*plan,
55-
CmdTypeoperation,
56-
intoffsetTuples,
57-
intnumberTuples,
58-
ScanDirectiondirection,
59-
DestReceiver*destfunc);
55+
CmdTypeoperation,
56+
longnumberTuples,
57+
ScanDirectiondirection,
58+
DestReceiver*destfunc);
6059
staticvoidExecRetrieve(TupleTableSlot*slot,
6160
DestReceiver*destfunc,
6261
EState*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
*/
158159
TupleTableSlot*
159-
ExecutorRun(QueryDesc*queryDesc,EState*estate,intfeature,
160-
Node*limoffset,Node*limcount)
160+
ExecutorRun(QueryDesc*queryDesc,EState*estate,intfeature,longcount)
161161
{
162162
CmdTypeoperation;
163163
Plan*plan;
164164
TupleTableSlot*result;
165165
CommandDestdest;
166166
DestReceiver*destfunc;
167-
intoffset=0;
168-
intcount=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-
ParamListInfoparamLI;
202-
inti;
203-
204-
switch (nodeTag(limoffset))
205-
{
206-
caseT_Const:
207-
coffset= (Const*)limoffset;
208-
offset= (int) (coffset->constvalue);
209-
break;
210-
211-
caseT_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-
ParamListInfoparamLI;
246-
inti;
247-
248-
switch (nodeTag(limcount))
249-
{
250-
caseT_Const:
251-
ccount= (Const*)limcount;
252-
count= (int) (ccount->constvalue);
253-
break;
254-
255-
caseT_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-
282192
switch (feature)
283193
{
284-
285194
caseEXEC_RUN:
286195
result=ExecutePlan(estate,
287196
plan,
288197
operation,
289-
offset,
290198
count,
291199
ForwardScanDirection,
292200
destfunc);
293201
break;
202+
294203
caseEXEC_FOR:
295204
result=ExecutePlan(estate,
296205
plan,
297206
operation,
298-
offset,
299207
count,
300208
ForwardScanDirection,
301209
destfunc);
@@ -308,7 +216,6 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
308216
result=ExecutePlan(estate,
309217
plan,
310218
operation,
311-
offset,
312219
count,
313220
BackwardScanDirection,
314221
destfunc);
@@ -322,14 +229,14 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
322229
result=ExecutePlan(estate,
323230
plan,
324231
operation,
325-
0,
326232
ONE_TUPLE,
327233
ForwardScanDirection,
328234
destfunc);
329235
break;
236+
330237
default:
331-
result=NULL;
332238
elog(DEBUG,"ExecutorRun: Unknown feature %d",feature);
239+
result=NULL;
333240
break;
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-
933838
staticTupleTableSlot*
934839
ExecutePlan(EState*estate,
935840
Plan*plan,
936841
CmdTypeoperation,
937-
intoffsetTuples,
938-
intnumberTuples,
842+
longnumberTuples,
939843
ScanDirectiondirection,
940844
DestReceiver*destfunc)
941845
{
942846
JunkFilter*junkfilter;
943847
TupleTableSlot*slot;
944848
ItemPointertupleid=NULL;
945849
ItemPointerDatatuple_ctid;
946-
intcurrent_tuple_count;
850+
longcurrent_tuple_count;
947851
TupleTableSlot*result;
948852

949853
/*
@@ -990,17 +894,6 @@ lnext:;
990894
break;
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++;
11591052
if (numberTuples==current_tuple_count)
11601053
break;
11611054
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp