mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
In array_agg(), don't create a new context for every group.
Previously, each new array created a new memory context that started out at 8kB. This is incredibly wasteful when there are lots of small groups of just a few elements each. Change initArrayResult() and friends to accept a "subcontext" argument to indicate whether the caller wants the ArrayBuildState allocated in a new subcontext or not. If not, it can no longer be released separately from the rest of the memory context. Fixes bug report by Frank van Vugt on 2013-10-19. Tomas Vondra. Reviewed by Ali Akbar, Tom Lane, and me.
This commit is contained in:
@ -520,8 +520,13 @@ array_agg_transfn(PG_FUNCTION_ARGS)
|
||||
elog(ERROR, "array_agg_transfn called in non-aggregate context");
|
||||
}
|
||||
|
||||
state = PG_ARGISNULL(0) ? NULL : (ArrayBuildState *) PG_GETARG_POINTER(0);
|
||||
if (PG_ARGISNULL(0))
|
||||
state = initArrayResult(arg1_typeid, aggcontext, false);
|
||||
else
|
||||
state = (ArrayBuildState *) PG_GETARG_POINTER(0);
|
||||
|
||||
elem = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
|
||||
|
||||
state = accumArrayResult(state,
|
||||
elem,
|
||||
PG_ARGISNULL(1),
|
||||
@ -595,7 +600,12 @@ array_agg_array_transfn(PG_FUNCTION_ARGS)
|
||||
elog(ERROR, "array_agg_array_transfn called in non-aggregate context");
|
||||
}
|
||||
|
||||
state = PG_ARGISNULL(0) ? NULL : (ArrayBuildStateArr *) PG_GETARG_POINTER(0);
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
state = initArrayResultArr(arg1_typeid, InvalidOid, aggcontext, false);
|
||||
else
|
||||
state = (ArrayBuildStateArr *) PG_GETARG_POINTER(0);
|
||||
|
||||
state = accumArrayResultArr(state,
|
||||
PG_GETARG_DATUM(1),
|
||||
PG_ARGISNULL(1),
|
||||
|
Reference in New Issue
Block a user