1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-19 13:42:17 +03:00

Allow nodeSort to perform Datum sorts for byref types

Here we add a new 'copy' parameter to tuplesort_getdatum so that we can
instruct the function not to datumCopy() byref Datums before returning.

Similar to 91e9e89dc, this can provide significant performance
improvements in nodeSort when sorting by a single byref column and the
sort's targetlist contains only that column.

This allows us to re-enable Datum sorts for byref types which was disabled
in 3a5817695 due to a reported memory leak.

Additionally, here we slightly optimize DISTINCT aggregates so that we no
longer perform any datumCopy() when we find the current value not to be
distinct from the previous value.  Previously the code would always take a
copy of the most recent Datum and pfree the previous value, even when the
values were the same.  Testing shows a small but noticeable performance
increase when aggregate transitions are skipped due to the current
transition value being the same as the prior one.

Author: David Rowley
Discussion: https://postgr.es/m/CAApHDvqS6wC5U==k9Hd26E4EQXH3QR67-T4=Q1rQ36NGvjfVSg@mail.gmail.com
Discussion: https://postgr.es/m/CAApHDvqHonfe9G1cVaKeHbDx70R_zCrM3qP2AGXpGrieSKGnhA@mail.gmail.com
This commit is contained in:
David Rowley
2022-10-28 09:25:12 +13:00
parent a5fc46414d
commit d37aa3d358
6 changed files with 57 additions and 32 deletions

View File

@@ -848,9 +848,19 @@ tuplesort_getindextuple(Tuplesortstate *state, bool forward)
* determination of "non-equal tuple" based on simple binary inequality. A
* NULL value will have a zeroed abbreviated value representation, which caller
* may rely on in abbreviated inequality check.
*
* For byref Datums, if copy is true, *val is set to a copy of the Datum
* copied into the caller's memory context, so that it will stay valid
* regardless of future manipulations of the tuplesort's state (up to and
* including deleting the tuplesort). If copy is false, *val will just be
* set to a pointer to the Datum held within the tuplesort, which is more
* efficient, but only safe for callers that are prepared to have any
* subsequent manipulation of the tuplesort's state invalidate slot contents.
* For byval Datums, the value of the 'copy' parameter has no effect.
*/
bool
tuplesort_getdatum(Tuplesortstate *state, bool forward,
tuplesort_getdatum(Tuplesortstate *state, bool forward, bool copy,
Datum *val, bool *isNull, Datum *abbrev)
{
TuplesortPublic *base = TuplesortstateGetPublic(state);
@@ -879,7 +889,11 @@ tuplesort_getdatum(Tuplesortstate *state, bool forward,
else
{
/* use stup.tuple because stup.datum1 may be an abbreviation */
*val = datumCopy(PointerGetDatum(stup.tuple), false, arg->datumTypeLen);
if (copy)
*val = datumCopy(PointerGetDatum(stup.tuple), false,
arg->datumTypeLen);
else
*val = PointerGetDatum(stup.tuple);
*isNull = false;
}