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

Fix things so that array_agg_finalfn does not modify or free its input

ArrayBuildState, per trouble report from Merlin Moncure.  By adopting
this fix, we are essentially deciding that aggregate final-functions
should not modify their inputs ever.  Adjust documentation and comments
to match that conclusion.
This commit is contained in:
Tom Lane
2009-06-20 18:45:28 +00:00
parent 87698ffa8e
commit 82480e28f5
4 changed files with 31 additions and 13 deletions

View File

@@ -6,7 +6,7 @@
* Copyright (c) 2003-2009, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.30 2009/06/11 14:49:03 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.31 2009/06/20 18:45:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -537,10 +537,13 @@ array_agg_finalfn(PG_FUNCTION_ARGS)
dims[0] = state->nelems;
lbs[0] = 1;
/* Release working state if regular aggregate, but not if window agg */
/*
* Make the result. We cannot release the ArrayBuildState because
* sometimes aggregate final functions are re-executed.
*/
result = makeMdArrayResult(state, 1, dims, lbs,
CurrentMemoryContext,
IsA(fcinfo->context, AggState));
false);
PG_RETURN_DATUM(result);
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.157 2009/06/11 14:49:03 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.158 2009/06/20 18:45:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -4179,9 +4179,21 @@ accumArrayResult(ArrayBuildState *astate,
}
}
/* Use datumCopy to ensure pass-by-ref stuff is copied into mcontext */
/*
* Ensure pass-by-ref stuff is copied into mcontext; and detoast it too
* if it's varlena. (You might think that detoasting is not needed here
* because construct_md_array can detoast the array elements later.
* However, we must not let construct_md_array modify the ArrayBuildState
* because that would mean array_agg_finalfn damages its input, which
* is verboten. Also, this way frequently saves one copying step.)
*/
if (!disnull && !astate->typbyval)
dvalue = datumCopy(dvalue, astate->typbyval, astate->typlen);
{
if (astate->typlen == -1)
dvalue = PointerGetDatum(PG_DETOAST_DATUM_COPY(dvalue));
else
dvalue = datumCopy(dvalue, astate->typbyval, astate->typlen);
}
astate->dvalues[astate->nelems] = dvalue;
astate->dnulls[astate->nelems] = disnull;