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

Commit38e9348

Browse files
committed
Make a couple of small changes to the tuplestore API, for the benefit of the
upcoming window-functions patch. First, tuplestore_trim is now anexported function that must be explicitly invoked by callers atappropriate times, rather than something that tuplestore tries to dobehind the scenes. Second, a read pointer that is marked as allowingbackward scan no longer prevents truncation. This means that a read pointermarked as having BACKWARD but not REWIND capability can only safely readbackwards as far as the oldest other read pointer. (The expected use patternfor this involves having another read pointer that serves as the truncationfencepost.)
1 parentc8b69ed commit38e9348

File tree

3 files changed

+65
-27
lines changed

3 files changed

+65
-27
lines changed

‎src/backend/executor/nodeMaterial.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeMaterial.c,v 1.63 2008/10/01 19:51:49 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeMaterial.c,v 1.64 2008/12/27 17:39:00 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -66,11 +66,11 @@ ExecMaterial(MaterialState *node)
6666
* Allocate a second read pointer to serve as the mark.
6767
* We know it must have index 1, so needn't store that.
6868
*/
69-
intptrn;
69+
intptrno;
7070

71-
ptrn=tuplestore_alloc_read_pointer(tuplestorestate,
72-
node->eflags);
73-
Assert(ptrn==1);
71+
ptrno=tuplestore_alloc_read_pointer(tuplestorestate,
72+
node->eflags);
73+
Assert(ptrno==1);
7474
}
7575
node->tuplestorestate=tuplestorestate;
7676
}
@@ -182,6 +182,16 @@ ExecInitMaterial(Material *node, EState *estate, int eflags)
182182
EXEC_FLAG_BACKWARD |
183183
EXEC_FLAG_MARK));
184184

185+
/*
186+
* Tuplestore's interpretation of the flag bits is subtly different from
187+
* the general executor meaning: it doesn't think BACKWARD necessarily
188+
* means "backwards all the way to start". If told to support BACKWARD we
189+
* must include REWIND in the tuplestore eflags, else tuplestore_trim
190+
* might throw away too much.
191+
*/
192+
if (eflags&EXEC_FLAG_BACKWARD)
193+
matstate->eflags |=EXEC_FLAG_REWIND;
194+
185195
matstate->eof_underlying= false;
186196
matstate->tuplestorestate=NULL;
187197

@@ -278,6 +288,11 @@ ExecMaterialMarkPos(MaterialState *node)
278288
* copy the active read pointer to the mark.
279289
*/
280290
tuplestore_copy_read_pointer(node->tuplestorestate,0,1);
291+
292+
/*
293+
* since we may have advanced the mark, try to truncate the tuplestore.
294+
*/
295+
tuplestore_trim(node->tuplestorestate);
281296
}
282297

283298
/* ----------------------------------------------------------------

‎src/backend/utils/sort/tuplestore.c

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@
3030
* in a format that allows either forward or backward scan. Otherwise, only
3131
* forward scan is allowed. A request for backward scan must be made before
3232
* putting any tuples into the tuplestore. Rewind is normally allowed but
33-
* can be turned off via tuplestore_set_eflags; turning off both backward
34-
* scan and rewind for all read pointers enables truncation of the tuplestore
35-
* at the oldest read point for minimal memory usage.
33+
* can be turned off via tuplestore_set_eflags; turning off rewind for all
34+
* read pointers enables truncation of the tuplestore at the oldest read point
35+
* for minimal memory usage. (The caller must explicitly call tuplestore_trim
36+
* at appropriate times for truncation to actually happen.)
3637
*
3738
* Note: in TSS_WRITEFILE state, the temp file's seek position is the
3839
* current write position, and the write-position variables in the tuplestore
@@ -46,7 +47,7 @@
4647
* Portions Copyright (c) 1994, Regents of the University of California
4748
*
4849
* IDENTIFICATION
49-
* $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.43 2008/10/28 15:51:03 tgl Exp $
50+
* $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.44 2008/12/27 17:39:00 tgl Exp $
5051
*
5152
*-------------------------------------------------------------------------
5253
*/
@@ -101,6 +102,7 @@ struct Tuplestorestate
101102
inteflags;/* capability flags (OR of pointers' flags) */
102103
boolbackward;/* store extra length words in file? */
103104
boolinterXact;/* keep open through transactions? */
105+
booltruncated;/* tuplestore_trim has removed tuples? */
104106
longavailMem;/* remaining memory available, in bytes */
105107
BufFile*myfile;/* underlying file, or NULL if none */
106108

@@ -220,7 +222,6 @@ static Tuplestorestate *tuplestore_begin_common(int eflags,
220222
intmaxKBytes);
221223
staticvoidtuplestore_puttuple_common(Tuplestorestate*state,void*tuple);
222224
staticvoiddumptuples(Tuplestorestate*state);
223-
staticvoidtuplestore_trim(Tuplestorestate*state);
224225
staticunsignedintgetlen(Tuplestorestate*state,booleofOK);
225226
staticvoid*copytup_heap(Tuplestorestate*state,void*tup);
226227
staticvoidwritetup_heap(Tuplestorestate*state,void*tup);
@@ -242,6 +243,7 @@ tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
242243
state->status=TSS_INMEM;
243244
state->eflags=eflags;
244245
state->interXact=interXact;
246+
state->truncated= false;
245247
state->availMem=maxKBytes*1024L;
246248
state->myfile=NULL;
247249

@@ -319,6 +321,10 @@ tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
319321
*EXEC_FLAG_BACKWARDneed backward fetch
320322
* If tuplestore_set_eflags is not called, REWIND is allowed, and BACKWARD
321323
* is set per "randomAccess" in the tuplestore_begin_xxx call.
324+
*
325+
* NOTE: setting BACKWARD without REWIND means the pointer can read backwards,
326+
* but not further than the truncation point (the furthest-back read pointer
327+
* position at the time of the last tuplestore_trim call).
322328
*/
323329
void
324330
tuplestore_set_eflags(Tuplestorestate*state,inteflags)
@@ -397,6 +403,7 @@ tuplestore_clear(Tuplestorestate *state)
397403
}
398404
}
399405
state->status=TSS_INMEM;
406+
state->truncated= false;
400407
state->memtupcount=0;
401408
readptr=state->readptrs;
402409
for (i=0;i<state->readptrcount;readptr++,i++)
@@ -723,12 +730,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
723730
returnNULL;
724731
if (readptr->current<state->memtupcount)
725732
{
726-
/*
727-
* We have another tuple, so return it. Note: in
728-
* principle we could try tuplestore_trim() here after
729-
* advancing current, but this would cost cycles with
730-
* little chance of success, so we don't bother.
731-
*/
733+
/* We have another tuple, so return it */
732734
returnstate->memtuples[readptr->current++];
733735
}
734736
readptr->eof_reached= true;
@@ -738,7 +740,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
738740
{
739741
/*
740742
* if all tuples are fetched already then we return last
741-
* tuple, else-tuple before last returned.
743+
* tuple, else tuple before last returned.
742744
*/
743745
if (readptr->eof_reached)
744746
{
@@ -748,11 +750,17 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
748750
else
749751
{
750752
if (readptr->current <=0)
753+
{
754+
Assert(!state->truncated);
751755
returnNULL;
756+
}
752757
readptr->current--;/* last returned tuple */
753758
}
754759
if (readptr->current <=0)
760+
{
761+
Assert(!state->truncated);
755762
returnNULL;
763+
}
756764
returnstate->memtuples[readptr->current-1];
757765
}
758766
break;
@@ -795,7 +803,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
795803
* Backward.
796804
*
797805
* if all tuples are fetched already then we return last tuple,
798-
* else-tuple before last returned.
806+
* else tuple before last returned.
799807
*
800808
* Back up to fetch previously-returned tuple's ending length
801809
* word. If seek fails, assume we are at start of file.
@@ -805,6 +813,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
805813
{
806814
/* even a failed backwards fetch gets you out of eof state */
807815
readptr->eof_reached= false;
816+
Assert(!state->truncated);
808817
returnNULL;
809818
}
810819
tuplen=getlen(state, false);
@@ -833,6 +842,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
833842
-(long) (tuplen+sizeof(unsignedint)),
834843
SEEK_CUR)!=0)
835844
elog(ERROR,"bogus tuple length in backward scan");
845+
Assert(!state->truncated);
836846
returnNULL;
837847
}
838848
tuplen=getlen(state, false);
@@ -887,7 +897,8 @@ tuplestore_gettupleslot(Tuplestorestate *state, bool forward,
887897
* tuplestore_advance - exported function to adjust position without fetching
888898
*
889899
* We could optimize this case to avoid palloc/pfree overhead, but for the
890-
* moment it doesn't seem worthwhile.
900+
* moment it doesn't seem worthwhile. (XXX this probably needs to be
901+
* reconsidered given the needs of window functions.)
891902
*/
892903
bool
893904
tuplestore_advance(Tuplestorestate*state,boolforward)
@@ -948,6 +959,7 @@ tuplestore_rescan(Tuplestorestate *state)
948959
TSReadPointer*readptr=&state->readptrs[state->activeptr];
949960

950961
Assert(readptr->eflags&EXEC_FLAG_REWIND);
962+
Assert(!state->truncated);
951963

952964
switch (state->status)
953965
{
@@ -1006,10 +1018,8 @@ tuplestore_copy_read_pointer(Tuplestorestate *state,
10061018
switch (state->status)
10071019
{
10081020
caseTSS_INMEM:
1009-
/* We might be able to truncate the tuplestore */
1010-
tuplestore_trim(state);
1011-
break;
10121021
caseTSS_WRITEFILE:
1022+
/* no work */
10131023
break;
10141024
caseTSS_READFILE:
10151025
/*
@@ -1053,19 +1063,27 @@ tuplestore_copy_read_pointer(Tuplestorestate *state,
10531063

10541064
/*
10551065
* tuplestore_trim- remove all no-longer-needed tuples
1066+
*
1067+
* Calling this function authorizes the tuplestore to delete all tuples
1068+
* before the oldest read pointer, if no read pointer is marked as requiring
1069+
* REWIND capability.
1070+
*
1071+
* Note: this is obviously safe if no pointer has BACKWARD capability either.
1072+
* If a pointer is marked as BACKWARD but not REWIND capable, it means that
1073+
* the pointer can be moved backward but not before the oldest other read
1074+
* pointer.
10561075
*/
1057-
staticvoid
1076+
void
10581077
tuplestore_trim(Tuplestorestate*state)
10591078
{
10601079
intoldest;
10611080
intnremove;
10621081
inti;
10631082

10641083
/*
1065-
* We can truncate the tuplestore if neither backward scan nor
1066-
* rewind capability are required by any read pointer.
1084+
* Truncation is disallowed if any read pointer requires rewind capability.
10671085
*/
1068-
if (state->eflags&(EXEC_FLAG_BACKWARD |EXEC_FLAG_REWIND))
1086+
if (state->eflags&EXEC_FLAG_REWIND)
10691087
return;
10701088

10711089
/*
@@ -1125,6 +1143,9 @@ tuplestore_trim(Tuplestorestate *state)
11251143
if (!state->readptrs[i].eof_reached)
11261144
state->readptrs[i].current-=nremove;
11271145
}
1146+
1147+
/* mark tuplestore as truncated (used for Assert crosschecks only) */
1148+
state->truncated= true;
11281149
}
11291150

11301151

‎src/include/utils/tuplestore.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
2525
* Portions Copyright (c) 1994, Regents of the University of California
2626
*
27-
* $PostgreSQL: pgsql/src/include/utils/tuplestore.h,v 1.25 2008/10/04 21:56:55 tgl Exp $
27+
* $PostgreSQL: pgsql/src/include/utils/tuplestore.h,v 1.26 2008/12/27 17:39:00 tgl Exp $
2828
*
2929
*-------------------------------------------------------------------------
3030
*/
@@ -66,6 +66,8 @@ extern void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr);
6666
externvoidtuplestore_copy_read_pointer(Tuplestorestate*state,
6767
intsrcptr,intdestptr);
6868

69+
externvoidtuplestore_trim(Tuplestorestate*state);
70+
6971
externbooltuplestore_gettupleslot(Tuplestorestate*state,boolforward,
7072
TupleTableSlot*slot);
7173
externbooltuplestore_advance(Tuplestorestate*state,boolforward);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp