diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-12-28 18:54:01 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-12-28 18:54:01 +0000 |
commit | 95b07bc7f5010233f52f9d11da74e2e5b653b0a7 (patch) | |
tree | 48f5858bf4eca1bfb316ef02bb959ca85f568e0a /src/backend/utils/adt/array_userfuncs.c | |
parent | 38e9348282e9d078487147ba8a85aebec54e3a08 (diff) | |
download | postgresql-95b07bc7f5010233f52f9d11da74e2e5b653b0a7.tar.gz postgresql-95b07bc7f5010233f52f9d11da74e2e5b653b0a7.zip |
Support window functions a la SQL:2008.
Hitoshi Harada, with some kibitzing from Heikki and Tom.
Diffstat (limited to 'src/backend/utils/adt/array_userfuncs.c')
-rw-r--r-- | src/backend/utils/adt/array_userfuncs.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c index 4c147f0021d..1401b29359f 100644 --- a/src/backend/utils/adt/array_userfuncs.c +++ b/src/backend/utils/adt/array_userfuncs.c @@ -6,7 +6,7 @@ * Copyright (c) 2003-2008, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.26 2008/11/14 02:09:51 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.27 2008/12/28 18:53:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -475,6 +475,7 @@ Datum array_agg_transfn(PG_FUNCTION_ARGS) { Oid arg1_typeid = get_fn_expr_argtype(fcinfo->flinfo, 1); + MemoryContext aggcontext; ArrayBuildState *state; Datum elem; @@ -483,8 +484,16 @@ array_agg_transfn(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine input data type"))); - /* cannot be called directly because of internal-type argument */ - Assert(fcinfo->context && IsA(fcinfo->context, AggState)); + if (fcinfo->context && IsA(fcinfo->context, AggState)) + aggcontext = ((AggState *) fcinfo->context)->aggcontext; + else if (fcinfo->context && IsA(fcinfo->context, WindowAggState)) + aggcontext = ((WindowAggState *) fcinfo->context)->wincontext; + else + { + /* cannot be called directly because of internal-type argument */ + elog(ERROR, "array_agg_transfn called in non-aggregate context"); + aggcontext = NULL; /* keep compiler quiet */ + } state = PG_ARGISNULL(0) ? NULL : (ArrayBuildState *) PG_GETARG_POINTER(0); elem = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1); @@ -492,7 +501,7 @@ array_agg_transfn(PG_FUNCTION_ARGS) elem, PG_ARGISNULL(1), arg1_typeid, - ((AggState *) fcinfo->context)->aggcontext); + aggcontext); /* * The transition type for array_agg() is declared to be "internal", @@ -506,14 +515,28 @@ array_agg_transfn(PG_FUNCTION_ARGS) Datum array_agg_finalfn(PG_FUNCTION_ARGS) { + Datum result; ArrayBuildState *state; + int dims[1]; + int lbs[1]; /* cannot be called directly because of internal-type argument */ - Assert(fcinfo->context && IsA(fcinfo->context, AggState)); + Assert(fcinfo->context && + (IsA(fcinfo->context, AggState) || + IsA(fcinfo->context, WindowAggState))); if (PG_ARGISNULL(0)) PG_RETURN_NULL(); /* returns null iff no input values */ state = (ArrayBuildState *) PG_GETARG_POINTER(0); - PG_RETURN_ARRAYTYPE_P(makeArrayResult(state, CurrentMemoryContext)); + + dims[0] = state->nelems; + lbs[0] = 1; + + /* Release working state if regular aggregate, but not if window agg */ + result = makeMdArrayResult(state, 1, dims, lbs, + CurrentMemoryContext, + IsA(fcinfo->context, AggState)); + + PG_RETURN_DATUM(result); } |