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

Commitfa117ee

Browse files
committed
Allow avoiding tuple copy within tuplesort_gettupleslot().
Add a "copy" argument to make it optional to receive a copy of callertuple that is safe to use following a subsequent manipulating oftuplesort's state. This is a performance optimization. Most existingtuplesort_gettupleslot() callers are made to opt out of copying.Existing callers that happen to rely on the validity of tuple memorybeyond subsequent manipulations of the tuplesort request their owncopy.This brings tuplesort_gettupleslot() in line withtuplestore_gettupleslot(). In the future, a "copy"tuplesort_getdatum() argument may be added, that similarly allowscallers to opt out of receiving their own copy of tuple.In passing, clarify assumptions that callers of other tuplesort fetchroutines may make about tuple memory validity, per gripe from TomLane.Author: Peter GeogheganDiscussion: CAM3SWZQWZZ_N=DmmL7tKy_OUjGH_5mN=N=A6h7kHyyDvEhg2DA@mail.gmail.com
1 parentaf8a94d commitfa117ee

File tree

5 files changed

+30
-19
lines changed

5 files changed

+30
-19
lines changed

‎src/backend/executor/nodeAgg.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,9 @@ initialize_phase(AggState *aggstate, int newphase)
666666
* Fetch a tuple from either the outer plan (for phase 1) or from the sorter
667667
* populated by the previous phase. Copy it to the sorter for the next phase
668668
* if any.
669+
*
670+
* Callers cannot rely on memory for tuple in returned slot remaining valid
671+
* past any subsequently fetched tuple.
669672
*/
670673
staticTupleTableSlot*
671674
fetch_input_tuple(AggState*aggstate)
@@ -674,8 +677,8 @@ fetch_input_tuple(AggState *aggstate)
674677

675678
if (aggstate->sort_in)
676679
{
677-
if (!tuplesort_gettupleslot(aggstate->sort_in, true,aggstate->sort_slot,
678-
NULL))
680+
if (!tuplesort_gettupleslot(aggstate->sort_in, true,false,
681+
aggstate->sort_slot,NULL))
679682
returnNULL;
680683
slot=aggstate->sort_slot;
681684
}
@@ -1409,7 +1412,7 @@ process_ordered_aggregate_multi(AggState *aggstate,
14091412
ExecClearTuple(slot2);
14101413

14111414
while (tuplesort_gettupleslot(pertrans->sortstates[aggstate->current_set],
1412-
true,slot1,&newAbbrevVal))
1415+
true,true,slot1,&newAbbrevVal))
14131416
{
14141417
/*
14151418
* Extract the first numTransInputs columns as datums to pass to the

‎src/backend/executor/nodeSort.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,13 @@ ExecSort(SortState *node)
132132

133133
/*
134134
* Get the first or next tuple from tuplesort. Returns NULL if no more
135-
* tuples.
135+
* tuples. Note that we only rely on slot tuple remaining valid until the
136+
* next fetch from the tuplesort.
136137
*/
137138
slot=node->ss.ps.ps_ResultTupleSlot;
138139
(void)tuplesort_gettupleslot(tuplesortstate,
139140
ScanDirectionIsForward(dir),
140-
slot,NULL);
141+
false,slot,NULL);
141142
returnslot;
142143
}
143144

‎src/backend/utils/adt/orderedsetaggs.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,7 @@ hypothetical_rank_common(FunctionCallInfo fcinfo, int flag,
11901190
tuplesort_performsort(osastate->sortstate);
11911191

11921192
/* iterate till we find the hypothetical row */
1193-
while (tuplesort_gettupleslot(osastate->sortstate, true,slot,NULL))
1193+
while (tuplesort_gettupleslot(osastate->sortstate, true,true,slot,NULL))
11941194
{
11951195
boolisnull;
11961196
Datumd=slot_getattr(slot,nargs+1,&isnull);
@@ -1353,7 +1353,8 @@ hypothetical_dense_rank_final(PG_FUNCTION_ARGS)
13531353
slot2=extraslot;
13541354

13551355
/* iterate till we find the hypothetical row */
1356-
while (tuplesort_gettupleslot(osastate->sortstate, true,slot,&abbrevVal))
1356+
while (tuplesort_gettupleslot(osastate->sortstate, true, true,slot,
1357+
&abbrevVal))
13571358
{
13581359
boolisnull;
13591360
Datumd=slot_getattr(slot,nargs+1,&isnull);

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

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,7 +1852,8 @@ tuplesort_performsort(Tuplesortstate *state)
18521852
* Internal routine to fetch the next tuple in either forward or back
18531853
* direction into *stup. Returns FALSE if no more tuples.
18541854
* Returned tuple belongs to tuplesort memory context, and must not be freed
1855-
* by caller. Caller should not use tuple following next call here.
1855+
* by caller. Note that fetched tuple is stored in memory that may be
1856+
* recycled by any future fetch.
18561857
*/
18571858
staticbool
18581859
tuplesort_gettuple_common(Tuplesortstate*state,boolforward,
@@ -2101,12 +2102,15 @@ tuplesort_gettuple_common(Tuplesortstate *state, bool forward,
21012102
* NULL value in leading attribute will set abbreviated value to zeroed
21022103
* representation, which caller may rely on in abbreviated inequality check.
21032104
*
2104-
* The slot receives a copied tuple (sometimes allocated in caller memory
2105-
* context) that will stay valid regardless of future manipulations of the
2106-
* tuplesort's state.
2105+
* If copy is true, the slot receives a copied tuple that'll that will stay
2106+
* valid regardless of future manipulations of the tuplesort's state. Memory
2107+
* is owned by the caller. If copy is false, the slot will just receive a
2108+
* pointer to a tuple held within the tuplesort, which is more efficient, but
2109+
* only safe for callers that are prepared to have any subsequent manipulation
2110+
* of the tuplesort's state invalidate slot contents.
21072111
*/
21082112
bool
2109-
tuplesort_gettupleslot(Tuplesortstate*state,boolforward,
2113+
tuplesort_gettupleslot(Tuplesortstate*state,boolforward,boolcopy,
21102114
TupleTableSlot*slot,Datum*abbrev)
21112115
{
21122116
MemoryContextoldcontext=MemoryContextSwitchTo(state->sortcontext);
@@ -2123,8 +2127,10 @@ tuplesort_gettupleslot(Tuplesortstate *state, bool forward,
21232127
if (state->sortKeys->abbrev_converter&&abbrev)
21242128
*abbrev=stup.datum1;
21252129

2126-
stup.tuple=heap_copy_minimal_tuple((MinimalTuple)stup.tuple);
2127-
ExecStoreMinimalTuple((MinimalTuple)stup.tuple,slot, true);
2130+
if (copy)
2131+
stup.tuple=heap_copy_minimal_tuple((MinimalTuple)stup.tuple);
2132+
2133+
ExecStoreMinimalTuple((MinimalTuple)stup.tuple,slot,copy);
21282134
return true;
21292135
}
21302136
else
@@ -2137,8 +2143,8 @@ tuplesort_gettupleslot(Tuplesortstate *state, bool forward,
21372143
/*
21382144
* Fetch the next tuple in either forward or back direction.
21392145
* Returns NULL if no more tuples. Returned tuple belongs to tuplesort memory
2140-
* context, and must not be freed by caller. Callershould notuse tuple
2141-
*following next call here.
2146+
* context, and must not be freed by caller. Callermay notrely on tuple
2147+
*remaining valid after any further manipulation of tuplesort.
21422148
*/
21432149
HeapTuple
21442150
tuplesort_getheaptuple(Tuplesortstate*state,boolforward)
@@ -2157,8 +2163,8 @@ tuplesort_getheaptuple(Tuplesortstate *state, bool forward)
21572163
/*
21582164
* Fetch the next index tuple in either forward or back direction.
21592165
* Returns NULL if no more tuples. Returned tuple belongs to tuplesort memory
2160-
* context, and must not be freed by caller. Callershould notuse tuple
2161-
*following next call here.
2166+
* context, and must not be freed by caller. Callermay notrely on tuple
2167+
*remaining valid after any further manipulation of tuplesort.
21622168
*/
21632169
IndexTuple
21642170
tuplesort_getindextuple(Tuplesortstate*state,boolforward)

‎src/include/utils/tuplesort.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ extern void tuplesort_putdatum(Tuplesortstate *state, Datum val,
9595
externvoidtuplesort_performsort(Tuplesortstate*state);
9696

9797
externbooltuplesort_gettupleslot(Tuplesortstate*state,boolforward,
98-
TupleTableSlot*slot,Datum*abbrev);
98+
boolcopy,TupleTableSlot*slot,Datum*abbrev);
9999
externHeapTupletuplesort_getheaptuple(Tuplesortstate*state,boolforward);
100100
externIndexTupletuplesort_getindextuple(Tuplesortstate*state,boolforward);
101101
externbooltuplesort_getdatum(Tuplesortstate*state,boolforward,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp