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

Commit78efd5c

Browse files
committed
Extend abbreviated key infrastructure to datum tuplesorts.
Andrew Gierth, reviewed by Peter Geoghegan and by me.
1 parent0bb8528 commit78efd5c

File tree

3 files changed

+101
-41
lines changed

3 files changed

+101
-41
lines changed

‎src/backend/executor/nodeAgg.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,6 @@ initialize_aggregates(AggState *aggstate,
363363
* We use a plain Datum sorter when there's a single input column;
364364
* otherwise sort the full tuple. (See comments for
365365
* process_ordered_aggregate_single.)
366-
*
367-
* In the future, we should consider forcing the
368-
* tuplesort_begin_heap() case when the abbreviated key
369-
* optimization can thereby be used, even when numInputs is 1.
370366
*/
371367
peraggstate->sortstate=
372368
(peraggstate->numInputs==1) ?

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,6 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
268268

269269
/*
270270
* Initialize tuplesort object.
271-
*
272-
* In the future, we should consider forcing the tuplesort_begin_heap()
273-
* case when the abbreviated key optimization can thereby be used, even
274-
* when !use_tuples.
275271
*/
276272
if (use_tuples)
277273
osastate->sortstate=tuplesort_begin_heap(qstate->tupdesc,

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

Lines changed: 101 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,18 @@ booloptimize_bounded_sort = true;
147147
* case where the first key determines the comparison result. Note that
148148
* for a pass-by-reference datatype, datum1 points into the "tuple" storage.
149149
*
150+
* There is one special case: when the sort support infrastructure provides an
151+
* "abbreviated key" representation, where the key is (typically) a pass by
152+
* value proxy for a pass by reference type. In this case, the abbreviated key
153+
* is stored in datum1 in place of the actual first key column.
154+
*
150155
* When sorting single Datums, the data value is represented directly by
151-
* datum1/isnull1. If the datatype is pass-by-reference and isnull1 is false,
152-
*then datum1 points to a separately palloc'd data value that is also pointed
153-
*to by the "tuple" pointer;otherwise "tuple" is NULL.There is one special
154-
*case: when the sort support infrastructure provides an"abbreviated key"
155-
*representation, where the keyis(typically) a pass by value proxy for a
156-
*pass byreferencetype.
156+
* datum1/isnull1 for pass by value types (or null values). If the datatype is
157+
*pass-by-reference and isnull1 is false, then "tuple" points to a separately
158+
*palloc'd data value,otherwise "tuple" is NULL.The value of datum1 is then
159+
*either the same pointer as "tuple", or is an abbreviated key value as
160+
*described above. Accordingly, "tuple"isalways used in preference to
161+
*datum1 as the authoritative value for pass-by-referencecases.
157162
*
158163
* While building initial runs, tupindex holds the tuple's run number. During
159164
* merge passes, we re-use it to hold the input tape number that each tuple in
@@ -901,30 +906,36 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
901906
state->copytup=copytup_datum;
902907
state->writetup=writetup_datum;
903908
state->readtup=readtup_datum;
909+
state->abbrevNext=10;
904910

905911
state->datumType=datumType;
906912

907-
/* Prepare SortSupport data */
908-
state->onlyKey= (SortSupport)palloc0(sizeof(SortSupportData));
909-
910-
state->onlyKey->ssup_cxt=CurrentMemoryContext;
911-
state->onlyKey->ssup_collation=sortCollation;
912-
state->onlyKey->ssup_nulls_first=nullsFirstFlag;
913-
/*
914-
* Conversion to abbreviated representation infeasible in the Datum case.
915-
* It must be possible to subsequently fetch original datum values within
916-
* tuplesort_getdatum(), which would require special-case preservation of
917-
* original values.
918-
*/
919-
state->onlyKey->abbreviate= false;
920-
921-
PrepareSortSupportFromOrderingOp(sortOperator,state->onlyKey);
922-
923913
/* lookup necessary attributes of the datum type */
924914
get_typlenbyval(datumType,&typlen,&typbyval);
925915
state->datumTypeLen=typlen;
926916
state->datumTypeByVal=typbyval;
927917

918+
/* Prepare SortSupport data */
919+
state->sortKeys= (SortSupport)palloc0(sizeof(SortSupportData));
920+
921+
state->sortKeys->ssup_cxt=CurrentMemoryContext;
922+
state->sortKeys->ssup_collation=sortCollation;
923+
state->sortKeys->ssup_nulls_first=nullsFirstFlag;
924+
925+
/* abbreviation is possible here only for by-reference types */
926+
state->sortKeys->abbreviate= !typbyval;
927+
928+
PrepareSortSupportFromOrderingOp(sortOperator,state->sortKeys);
929+
930+
/*
931+
* The "onlyKey" optimization cannot be used with abbreviated keys, since
932+
* tie-breaker comparisons may be required. Typically, the optimization is
933+
* only of value to pass-by-value types anyway, whereas abbreviated keys
934+
* are typically only of value to pass-by-reference types.
935+
*/
936+
if (!state->sortKeys->abbrev_converter)
937+
state->onlyKey=state->sortKeys;
938+
928939
MemoryContextSwitchTo(oldcontext);
929940

930941
returnstate;
@@ -1307,9 +1318,17 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
13071318
SortTuplestup;
13081319

13091320
/*
1310-
* If it's a pass-by-reference value, copy it into memory we control, and
1311-
* decrease availMem. Then call the common code.
1321+
* Pass-by-value types or null values are just stored directly in
1322+
* stup.datum1 (and stup.tuple is not used and set to NULL).
1323+
*
1324+
* Non-null pass-by-reference values need to be copied into memory we
1325+
* control, and possibly abbreviated. The copied value is pointed to by
1326+
* stup.tuple and is treated as the canonical copy (e.g. to return via
1327+
* tuplesort_getdatum or when writing to tape); stup.datum1 gets the
1328+
* abbreviated value if abbreviation is happening, otherwise it's identical
1329+
* to stup.tuple.
13121330
*/
1331+
13131332
if (isNull||state->datumTypeByVal)
13141333
{
13151334
stup.datum1=val;
@@ -1318,10 +1337,44 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
13181337
}
13191338
else
13201339
{
1321-
stup.datum1=datumCopy(val, false,state->datumTypeLen);
1340+
Datumoriginal=datumCopy(val, false,state->datumTypeLen);
1341+
13221342
stup.isnull1= false;
1323-
stup.tuple=DatumGetPointer(stup.datum1);
1343+
stup.tuple=DatumGetPointer(original);
13241344
USEMEM(state,GetMemoryChunkSpace(stup.tuple));
1345+
1346+
if (!state->sortKeys->abbrev_converter)
1347+
{
1348+
stup.datum1=original;
1349+
}
1350+
elseif (!consider_abort_common(state))
1351+
{
1352+
/* Store abbreviated key representation */
1353+
stup.datum1=state->sortKeys->abbrev_converter(original,
1354+
state->sortKeys);
1355+
}
1356+
else
1357+
{
1358+
/* Abort abbreviation */
1359+
inti;
1360+
1361+
stup.datum1=original;
1362+
1363+
/*
1364+
* Set state to be consistent with never trying abbreviation.
1365+
*
1366+
* Alter datum1 representation in already-copied tuples, so as to
1367+
* ensure a consistent representation (current tuple was just handled).
1368+
* Note that we rely on all tuples copied so far actually being
1369+
* contained within memtuples array.
1370+
*/
1371+
for (i=0;i<state->memtupcount;i++)
1372+
{
1373+
SortTuple*mtup=&state->memtuples[i];
1374+
1375+
mtup->datum1=PointerGetDatum(mtup->tuple);
1376+
}
1377+
}
13251378
}
13261379

13271380
puttuple_common(state,&stup);
@@ -1886,10 +1939,12 @@ tuplesort_getdatum(Tuplesortstate *state, bool forward,
18861939
}
18871940
else
18881941
{
1942+
/* use stup.tuple because stup.datum1 may be an abbreviation */
1943+
18891944
if (should_free)
1890-
*val=stup.datum1;
1945+
*val=PointerGetDatum(stup.tuple);
18911946
else
1892-
*val=datumCopy(stup.datum1, false,state->datumTypeLen);
1947+
*val=datumCopy(PointerGetDatum(stup.tuple), false,state->datumTypeLen);
18931948
*isNull= false;
18941949
}
18951950

@@ -3715,9 +3770,22 @@ readtup_index(Tuplesortstate *state, SortTuple *stup,
37153770
staticint
37163771
comparetup_datum(constSortTuple*a,constSortTuple*b,Tuplesortstate*state)
37173772
{
3718-
returnApplySortComparator(a->datum1,a->isnull1,
3719-
b->datum1,b->isnull1,
3720-
state->onlyKey);
3773+
intcompare;
3774+
3775+
compare=ApplySortComparator(a->datum1,a->isnull1,
3776+
b->datum1,b->isnull1,
3777+
state->sortKeys);
3778+
if (compare!=0)
3779+
returncompare;
3780+
3781+
/* if we have abbreviations, then "tuple" has the original value */
3782+
3783+
if (state->sortKeys->abbrev_converter)
3784+
compare=ApplySortAbbrevFullComparator(PointerGetDatum(a->tuple),a->isnull1,
3785+
PointerGetDatum(b->tuple),b->isnull1,
3786+
state->sortKeys);
3787+
3788+
returncompare;
37213789
}
37223790

37233791
staticvoid
@@ -3746,8 +3814,8 @@ writetup_datum(Tuplesortstate *state, int tapenum, SortTuple *stup)
37463814
}
37473815
else
37483816
{
3749-
waddr=DatumGetPointer(stup->datum1);
3750-
tuplen=datumGetSize(stup->datum1, false,state->datumTypeLen);
3817+
waddr=stup->tuple;
3818+
tuplen=datumGetSize(PointerGetDatum(stup->tuple), false,state->datumTypeLen);
37513819
Assert(tuplen!=0);
37523820
}
37533821

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp