1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-25 21:42:33 +03:00

Optimize various aggregate deserialization functions, take 2

f0efa5aec added initReadOnlyStringInfo to allow a StringInfo to be
initialized from an existing buffer and also relaxed the requirement
that a StringInfo's buffer must be NUL terminated at data[len].  Now
that we have that, there's no need for these aggregate deserial
functions to use appendBinaryStringInfo() as that rather wastefully
palloc'd a new buffer and memcpy'd in the bytea's buffer.  Instead, we can
just use the bytea's buffer and point the StringInfo directly to that
using the new initializer function.

In Amdahl's law, this speeds up the serial portion of parallel
aggregates and makes sum(numeric), avg(numeric), var_pop(numeric),
var_samp(numeric), variance(numeric), stddev_pop(numeric),
stddev_samp(numeric), stddev(numeric), array_agg(anyarray),
string_agg(text) and string_agg(bytea) scale better in parallel queries.

Author: David Rowley
Discussion: https://postgr.es/m/CAApHDvr%3De-YOigriSHHm324a40HPqcUhSp6pWWgjz5WwegR%3DcQ%40mail.gmail.com
This commit is contained in:
David Rowley 2023-10-27 10:41:55 +13:00
parent 26f988212e
commit 0c882a2988
3 changed files with 28 additions and 42 deletions

View File

@ -723,12 +723,11 @@ array_agg_deserialize(PG_FUNCTION_ARGS)
sstate = PG_GETARG_BYTEA_PP(0); sstate = PG_GETARG_BYTEA_PP(0);
/* /*
* Copy the bytea into a StringInfo so that we can "receive" it using the * Initialize a StringInfo so that we can "receive" it using the standard
* standard recv-function infrastructure. * recv-function infrastructure.
*/ */
initStringInfo(&buf); initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
appendBinaryStringInfo(&buf, VARSIZE_ANY_EXHDR(sstate));
VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
/* element_type */ /* element_type */
element_type = pq_getmsgint(&buf, 4); element_type = pq_getmsgint(&buf, 4);
@ -815,7 +814,6 @@ array_agg_deserialize(PG_FUNCTION_ARGS)
} }
pq_getmsgend(&buf); pq_getmsgend(&buf);
pfree(buf.data);
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
} }
@ -1124,12 +1122,11 @@ array_agg_array_deserialize(PG_FUNCTION_ARGS)
sstate = PG_GETARG_BYTEA_PP(0); sstate = PG_GETARG_BYTEA_PP(0);
/* /*
* Copy the bytea into a StringInfo so that we can "receive" it using the * Initialize a StringInfo so that we can "receive" it using the standard
* standard recv-function infrastructure. * recv-function infrastructure.
*/ */
initStringInfo(&buf); initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
appendBinaryStringInfo(&buf, VARSIZE_ANY_EXHDR(sstate));
VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
/* element_type */ /* element_type */
element_type = pq_getmsgint(&buf, 4); element_type = pq_getmsgint(&buf, 4);
@ -1187,7 +1184,6 @@ array_agg_array_deserialize(PG_FUNCTION_ARGS)
memcpy(result->lbs, temp, sizeof(result->lbs)); memcpy(result->lbs, temp, sizeof(result->lbs));
pq_getmsgend(&buf); pq_getmsgend(&buf);
pfree(buf.data);
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
} }

View File

@ -5190,12 +5190,11 @@ numeric_avg_deserialize(PG_FUNCTION_ARGS)
init_var(&tmp_var); init_var(&tmp_var);
/* /*
* Copy the bytea into a StringInfo so that we can "receive" it using the * Initialize a StringInfo so that we can "receive" it using the standard
* standard recv-function infrastructure. * recv-function infrastructure.
*/ */
initStringInfo(&buf); initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
appendBinaryStringInfo(&buf, VARSIZE_ANY_EXHDR(sstate));
VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
result = makeNumericAggStateCurrentContext(false); result = makeNumericAggStateCurrentContext(false);
@ -5222,7 +5221,6 @@ numeric_avg_deserialize(PG_FUNCTION_ARGS)
result->nInfcount = pq_getmsgint64(&buf); result->nInfcount = pq_getmsgint64(&buf);
pq_getmsgend(&buf); pq_getmsgend(&buf);
pfree(buf.data);
free_var(&tmp_var); free_var(&tmp_var);
@ -5306,12 +5304,11 @@ numeric_deserialize(PG_FUNCTION_ARGS)
init_var(&tmp_var); init_var(&tmp_var);
/* /*
* Copy the bytea into a StringInfo so that we can "receive" it using the * Initialize a StringInfo so that we can "receive" it using the standard
* standard recv-function infrastructure. * recv-function infrastructure.
*/ */
initStringInfo(&buf); initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
appendBinaryStringInfo(&buf, VARSIZE_ANY_EXHDR(sstate));
VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
result = makeNumericAggStateCurrentContext(false); result = makeNumericAggStateCurrentContext(false);
@ -5342,7 +5339,6 @@ numeric_deserialize(PG_FUNCTION_ARGS)
result->nInfcount = pq_getmsgint64(&buf); result->nInfcount = pq_getmsgint64(&buf);
pq_getmsgend(&buf); pq_getmsgend(&buf);
pfree(buf.data);
free_var(&tmp_var); free_var(&tmp_var);
@ -5677,12 +5673,11 @@ numeric_poly_deserialize(PG_FUNCTION_ARGS)
init_var(&tmp_var); init_var(&tmp_var);
/* /*
* Copy the bytea into a StringInfo so that we can "receive" it using the * Initialize a StringInfo so that we can "receive" it using the standard
* standard recv-function infrastructure. * recv-function infrastructure.
*/ */
initStringInfo(&buf); initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
appendBinaryStringInfo(&buf, VARSIZE_ANY_EXHDR(sstate));
VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
result = makePolyNumAggStateCurrentContext(false); result = makePolyNumAggStateCurrentContext(false);
@ -5706,7 +5701,6 @@ numeric_poly_deserialize(PG_FUNCTION_ARGS)
#endif #endif
pq_getmsgend(&buf); pq_getmsgend(&buf);
pfree(buf.data);
free_var(&tmp_var); free_var(&tmp_var);
@ -5868,12 +5862,11 @@ int8_avg_deserialize(PG_FUNCTION_ARGS)
init_var(&tmp_var); init_var(&tmp_var);
/* /*
* Copy the bytea into a StringInfo so that we can "receive" it using the * Initialize a StringInfo so that we can "receive" it using the standard
* standard recv-function infrastructure. * recv-function infrastructure.
*/ */
initStringInfo(&buf); initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
appendBinaryStringInfo(&buf, VARSIZE_ANY_EXHDR(sstate));
VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
result = makePolyNumAggStateCurrentContext(false); result = makePolyNumAggStateCurrentContext(false);
@ -5889,7 +5882,6 @@ int8_avg_deserialize(PG_FUNCTION_ARGS)
#endif #endif
pq_getmsgend(&buf); pq_getmsgend(&buf);
pfree(buf.data);
free_var(&tmp_var); free_var(&tmp_var);

View File

@ -5289,12 +5289,11 @@ string_agg_deserialize(PG_FUNCTION_ARGS)
sstate = PG_GETARG_BYTEA_PP(0); sstate = PG_GETARG_BYTEA_PP(0);
/* /*
* Copy the bytea into a StringInfo so that we can "receive" it using the * Initialize a StringInfo so that we can "receive" it using the standard
* standard recv-function infrastructure. * recv-function infrastructure.
*/ */
initStringInfo(&buf); initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
appendBinaryStringInfo(&buf, VARSIZE_ANY_EXHDR(sstate));
VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
result = makeStringAggState(fcinfo); result = makeStringAggState(fcinfo);
@ -5307,7 +5306,6 @@ string_agg_deserialize(PG_FUNCTION_ARGS)
appendBinaryStringInfo(result, data, datalen); appendBinaryStringInfo(result, data, datalen);
pq_getmsgend(&buf); pq_getmsgend(&buf);
pfree(buf.data);
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
} }