*** a/doc/src/sgml/catalogs.sgml --- b/doc/src/sgml/catalogs.sgml *************** *** 373,378 **** --- 373,384 ---- Data type of the aggregate function's internal transition (state) data + aggtransspace + int4 + + Approximation for the average size of the aggregate function's internal transition (state) data + + agginitval text *** a/doc/src/sgml/ref/create_aggregate.sgml --- b/doc/src/sgml/ref/create_aggregate.sgml *************** *** 24,29 **** PostgreSQL documentation --- 24,30 ---- CREATE AGGREGATE name ( input_data_type [ , ... ] ) ( SFUNC = sfunc, STYPE = state_data_type + [ , SSPACE = state_data_size ] [ , FINALFUNC = ffunc ] [ , INITCOND = initial_condition ] [ , SORTOP = sort_operator ] *************** *** 35,40 **** CREATE AGGREGATE name ( --- 36,42 ---- BASETYPE = base_type, SFUNC = sfunc, STYPE = state_data_type + [ , SSPACE = state_data_size ] [ , FINALFUNC = ffunc ] [ , INITCOND = initial_condition ] [ , SORTOP = sort_operator ] *************** *** 241,246 **** SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; --- 243,260 ---- + state_data_size + + + Approximate average size (in bytes) of aggregate's state value. + Planner uses this value to approximate the memory required for + the aggregation. If this value is not provided, a default value is + used based on state_data_type. + + + + + ffunc *** a/src/backend/catalog/pg_aggregate.c --- b/src/backend/catalog/pg_aggregate.c *************** *** 51,56 **** AggregateCreate(const char *aggName, --- 51,57 ---- List *aggfinalfnName, List *aggsortopName, Oid aggTransType, + int32 aggTransSpace, const char *agginitval) { Relation aggdesc; *************** *** 269,274 **** AggregateCreate(const char *aggName, --- 270,276 ---- values[Anum_pg_aggregate_aggfinalfn - 1] = ObjectIdGetDatum(finalfn); values[Anum_pg_aggregate_aggsortop - 1] = ObjectIdGetDatum(sortop); values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType); + values[Anum_pg_aggregate_aggtransspace - 1] = Int32GetDatum(aggTransSpace); if (agginitval) values[Anum_pg_aggregate_agginitval - 1] = CStringGetTextDatum(agginitval); else *** a/src/backend/commands/aggregatecmds.c --- b/src/backend/commands/aggregatecmds.c *************** *** 62,67 **** DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) --- 62,68 ---- Oid *aggArgTypes; int numArgs; Oid transTypeId; + int32 transSpace = 0; char transTypeType; ListCell *pl; *************** *** 96,101 **** DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) --- 97,104 ---- transType = defGetTypeName(defel); else if (pg_strcasecmp(defel->defname, "stype1") == 0) transType = defGetTypeName(defel); + else if (pg_strcasecmp(defel->defname, "sspace") == 0) + transSpace = defGetInt32(defel); else if (pg_strcasecmp(defel->defname, "initcond") == 0) initval = defGetString(defel); else if (pg_strcasecmp(defel->defname, "initcond1") == 0) *************** *** 225,229 **** DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) --- 228,233 ---- finalfuncName, /* final function name */ sortoperatorName, /* sort operator name */ transTypeId, /* transition data type */ + transSpace, /* transition space */ initval); /* initial condition */ } *** a/src/backend/commands/define.c --- b/src/backend/commands/define.c *************** *** 165,170 **** defGetBoolean(DefElem *def) --- 165,194 ---- } /* + * Extract an int32 value from a DefElem. + */ + int32 + defGetInt32(DefElem *def) + { + if (def->arg == NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("%s requires an integer value", + def->defname))); + switch (nodeTag(def->arg)) + { + case T_Integer: + return (int32) intVal(def->arg); + default: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("%s requires an integer value", + def->defname))); + } + return 0; /* keep compiler quiet */ + } + + /* * Extract an int64 value from a DefElem. */ int64 *** a/src/backend/optimizer/util/clauses.c --- b/src/backend/optimizer/util/clauses.c *************** *** 461,466 **** count_agg_clauses_walker(Node *node, count_agg_clauses_context *context) --- 461,467 ---- Oid aggtransfn; Oid aggfinalfn; Oid aggtranstype; + int32 aggtransspace; QualCost argcosts; Oid *inputTypes; int numArguments; *************** *** 478,483 **** count_agg_clauses_walker(Node *node, count_agg_clauses_context *context) --- 479,485 ---- aggtransfn = aggform->aggtransfn; aggfinalfn = aggform->aggfinalfn; aggtranstype = aggform->aggtranstype; + aggtransspace = aggform->aggtransspace; ReleaseSysCache(aggTuple); /* count it */ *************** *** 524,536 **** count_agg_clauses_walker(Node *node, count_agg_clauses_context *context) pfree(declaredArgTypes); } /* * If the transition type is pass-by-value then it doesn't add * anything to the required size of the hashtable. If it is * pass-by-reference then we have to add the estimated size of the * value itself, plus palloc overhead. */ ! if (!get_typbyval(aggtranstype)) { int32 aggtranstypmod; int32 avgwidth; --- 526,546 ---- pfree(declaredArgTypes); } + /* + * If approximate average space used by aggregate transition value is + * specified in pg_aggregate, then use it for transitionSpace. + */ + if (aggtransspace > 0) + { + costs->transitionSpace += aggtransspace; + } /* * If the transition type is pass-by-value then it doesn't add * anything to the required size of the hashtable. If it is * pass-by-reference then we have to add the estimated size of the * value itself, plus palloc overhead. */ ! else if (!get_typbyval(aggtranstype)) { int32 aggtranstypmod; int32 avgwidth; *** a/src/backend/utils/adt/numeric.c --- b/src/backend/utils/adt/numeric.c *************** *** 2464,2571 **** numeric_float4(PG_FUNCTION_ARGS) * * Aggregate functions * ! * The transition datatype for all these aggregates is a 3-element array ! * of Numeric, holding the values N, sum(X), sum(X*X) in that order. ! * ! * We represent N as a numeric mainly to avoid having to build a special ! * datatype; it's unlikely it'd overflow an int4, but ... * * ---------------------------------------------------------------------- */ ! static ArrayType * ! do_numeric_accum(ArrayType *transarray, Numeric newval) { ! Datum *transdatums; ! int ndatums; ! Datum N, ! sumX, ! sumX2; ! ArrayType *result; ! ! /* We assume the input is array of numeric */ ! deconstruct_array(transarray, ! NUMERICOID, -1, false, 'i', ! &transdatums, NULL, &ndatums); ! if (ndatums != 3) ! elog(ERROR, "expected 3-element numeric array"); ! N = transdatums[0]; ! sumX = transdatums[1]; ! sumX2 = transdatums[2]; ! ! N = DirectFunctionCall1(numeric_inc, N); ! sumX = DirectFunctionCall2(numeric_add, sumX, ! NumericGetDatum(newval)); ! sumX2 = DirectFunctionCall2(numeric_add, sumX2, ! DirectFunctionCall2(numeric_mul, ! NumericGetDatum(newval), ! NumericGetDatum(newval))); ! ! transdatums[0] = N; ! transdatums[1] = sumX; ! transdatums[2] = sumX2; ! ! result = construct_array(transdatums, 3, ! NUMERICOID, -1, false, 'i'); ! return result; } ! /* ! * Improve avg performance by not caclulating sum(X*X). ! */ ! static ArrayType * ! do_numeric_avg_accum(ArrayType *transarray, Numeric newval) { ! Datum *transdatums; ! int ndatums; ! Datum N, ! sumX; ! ArrayType *result; ! ! /* We assume the input is array of numeric */ ! deconstruct_array(transarray, ! NUMERICOID, -1, false, 'i', ! &transdatums, NULL, &ndatums); ! if (ndatums != 2) ! elog(ERROR, "expected 2-element numeric array"); ! N = transdatums[0]; ! sumX = transdatums[1]; ! ! N = DirectFunctionCall1(numeric_inc, N); ! sumX = DirectFunctionCall2(numeric_add, sumX, ! NumericGetDatum(newval)); ! ! transdatums[0] = N; ! transdatums[1] = sumX; ! ! result = construct_array(transdatums, 2, ! NUMERICOID, -1, false, 'i'); ! return result; } Datum numeric_accum(PG_FUNCTION_ARGS) { ! ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); ! Numeric newval = PG_GETARG_NUMERIC(1); ! PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval)); } /* * Optimized case for average of numeric. */ Datum numeric_avg_accum(PG_FUNCTION_ARGS) { ! ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); ! Numeric newval = PG_GETARG_NUMERIC(1); ! PG_RETURN_ARRAYTYPE_P(do_numeric_avg_accum(transarray, newval)); } /* * Integer data types all use Numeric accumulators to share code and * avoid risk of overflow. For int2 and int4 inputs, Numeric accumulation --- 2464,2620 ---- * * Aggregate functions * ! * The transition datatype for all these aggregates is a pointer to ! * a struct NumericAggState allocated in the aggregate context. * * ---------------------------------------------------------------------- */ ! typedef struct NumericAggState ! { ! bool first; ! bool isNaN; ! uint64 N; ! NumericVar sumX; ! NumericVar sumX2; ! bool calcSumX2; ! MemoryContext agg_context; ! } NumericAggState; ! ! ! static NumericAggState * ! makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2) { ! NumericAggState *state; ! MemoryContext agg_context; ! MemoryContext old_context; ! if (!AggCheckCallContext(fcinfo, &agg_context)) ! { ! elog(ERROR, "this is called in non-aggregate context"); ! } ! ! old_context = MemoryContextSwitchTo(agg_context); ! ! state = palloc0(sizeof(NumericAggState)); ! state->first = true; ! state->calcSumX2 = calcSumX2; ! state->agg_context = agg_context; ! ! MemoryContextSwitchTo(old_context); ! ! return state; } ! ! static void ! do_numeric_accum(NumericAggState *state, Numeric newval) { ! NumericVar X; ! NumericVar X2; ! MemoryContext old_context; ! bool first; ! ! first = state->first; ! state->first = false; ! state->N++; ! ! if (state->isNaN || NUMERIC_IS_NAN(newval)) ! { ! state->isNaN = true; ! return; ! } ! init_var_from_num(newval, &X); ! ! if (state->calcSumX2) ! { ! init_var(&X2); ! mul_var(&X, &X, &X2, X.dscale * 2); ! } ! ! old_context = MemoryContextSwitchTo(state->agg_context); ! ! if (!first) ! { ! NumericVar preSumX; ! ! memcpy(&preSumX, &(state->sumX), sizeof(NumericVar)); ! init_var(&(state->sumX)); ! add_var(&X, &preSumX, &(state->sumX)); ! free_var(&preSumX); ! ! if (state->calcSumX2) ! { ! NumericVar preSumX2; ! ! memcpy(&preSumX2, &(state->sumX2), sizeof(NumericVar)); ! init_var(&(state->sumX2)); ! add_var(&X2, &preSumX2, &(state->sumX2)); ! free_var(&preSumX2); ! } ! } ! else ! { ! set_var_from_var(&X, &(state->sumX)); ! ! if (state->calcSumX2) ! set_var_from_var(&X2, &(state->sumX2)); ! } ! ! MemoryContextSwitchTo(old_context); } + Datum numeric_accum(PG_FUNCTION_ARGS) { ! NumericAggState *state; ! ! state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0); ! if (!PG_ARGISNULL(1)) ! { ! /* On the first time through, create the state variable. */ ! if (state == NULL) ! state = makeNumericAggState(fcinfo, true); ! ! do_numeric_accum(state, PG_GETARG_NUMERIC(1)); ! } ! ! if (state == NULL) ! PG_RETURN_NULL(); ! else ! PG_RETURN_POINTER(state); } + /* * Optimized case for average of numeric. */ Datum numeric_avg_accum(PG_FUNCTION_ARGS) { ! NumericAggState *state; ! state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0); ! ! if (!PG_ARGISNULL(1)) ! { ! /* On the first time through, create the state variable. */ ! if (state == NULL) ! state = makeNumericAggState(fcinfo, false); ! ! do_numeric_accum(state, PG_GETARG_NUMERIC(1)); ! } ! ! if (state == NULL) ! PG_RETURN_NULL(); ! else ! PG_RETURN_POINTER(state); } + /* * Integer data types all use Numeric accumulators to share code and * avoid risk of overflow. For int2 and int4 inputs, Numeric accumulation *************** *** 2578,2664 **** numeric_avg_accum(PG_FUNCTION_ARGS) Datum int2_accum(PG_FUNCTION_ARGS) { ! ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); ! Datum newval2 = PG_GETARG_DATUM(1); ! Numeric newval; ! newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric, newval2)); ! PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval)); } Datum int4_accum(PG_FUNCTION_ARGS) { ! ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); ! Datum newval4 = PG_GETARG_DATUM(1); ! Numeric newval; ! newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric, newval4)); ! PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval)); } Datum int8_accum(PG_FUNCTION_ARGS) { ! ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); ! Datum newval8 = PG_GETARG_DATUM(1); ! Numeric newval; ! newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8)); ! PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval)); } /* * Optimized case for average of int8. */ Datum int8_avg_accum(PG_FUNCTION_ARGS) { ! ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); ! Datum newval8 = PG_GETARG_DATUM(1); ! Numeric newval; ! ! newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8)); ! PG_RETURN_ARRAYTYPE_P(do_numeric_avg_accum(transarray, newval)); } Datum numeric_avg(PG_FUNCTION_ARGS) { ! ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); ! Datum *transdatums; ! int ndatums; ! Numeric N, ! sumX; ! ! /* We assume the input is array of numeric */ ! deconstruct_array(transarray, ! NUMERICOID, -1, false, 'i', ! &transdatums, NULL, &ndatums); ! if (ndatums != 2) ! elog(ERROR, "expected 2-element numeric array"); ! N = DatumGetNumeric(transdatums[0]); ! sumX = DatumGetNumeric(transdatums[1]); ! /* SQL defines AVG of no values to be NULL */ ! /* N is zero iff no digits (cf. numeric_uminus) */ ! if (NUMERIC_NDIGITS(N) == 0) PG_RETURN_NULL(); ! PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, ! NumericGetDatum(sumX), ! NumericGetDatum(N))); } /* * Workhorse routine for the standard deviance and variance ! * aggregates. 'transarray' is the aggregate's transition ! * array. 'variance' specifies whether we should calculate the * variance or the standard deviation. 'sample' indicates whether the * caller is interested in the sample or the population * variance/stddev. --- 2627,2776 ---- Datum int2_accum(PG_FUNCTION_ARGS) { ! NumericAggState *state; ! state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0); ! if (!PG_ARGISNULL(1)) ! { ! Datum newval2 = PG_GETARG_DATUM(1); ! Numeric newval; ! ! /* On the first time through, create the state variable. */ ! if (state == NULL) ! state = makeNumericAggState(fcinfo, true); ! ! newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric, newval2)); ! do_numeric_accum(state, newval); ! } ! ! if (state == NULL) ! PG_RETURN_NULL(); ! else ! PG_RETURN_POINTER(state); } + Datum int4_accum(PG_FUNCTION_ARGS) { ! NumericAggState *state; ! ! state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0); ! if (!PG_ARGISNULL(1)) ! { ! Datum newval4 = PG_GETARG_DATUM(1); ! Numeric newval; ! ! /* On the first time through, create the state variable. */ ! if (state == NULL) ! state = makeNumericAggState(fcinfo, true); ! ! newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric, newval4)); ! do_numeric_accum(state, newval); ! } ! if (state == NULL) ! PG_RETURN_NULL(); ! else ! PG_RETURN_POINTER(state); } + Datum int8_accum(PG_FUNCTION_ARGS) { ! NumericAggState *state; ! state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0); ! ! if (!PG_ARGISNULL(1)) ! { ! Datum newval8 = PG_GETARG_DATUM(1); ! Numeric newval; ! ! /* On the first time through, create the state variable. */ ! if (state == NULL) ! state = makeNumericAggState(fcinfo, true); ! ! newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8)); ! do_numeric_accum(state, newval); ! } ! if (state == NULL) ! PG_RETURN_NULL(); ! else ! PG_RETURN_POINTER(state); } + /* * Optimized case for average of int8. */ Datum int8_avg_accum(PG_FUNCTION_ARGS) { ! NumericAggState *state; ! state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0); ! if (!PG_ARGISNULL(1)) ! { ! Datum newval8 = PG_GETARG_DATUM(1); ! Numeric newval; ! ! /* On the first time through, create the state variable. */ ! if (state == NULL) ! state = makeNumericAggState(fcinfo, false); ! ! newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8)); ! do_numeric_accum(state, newval); ! } ! ! if (state == NULL) ! PG_RETURN_NULL(); ! else ! PG_RETURN_POINTER(state); } Datum numeric_avg(PG_FUNCTION_ARGS) { ! Datum N_datum; ! Datum sumX_datum; ! NumericAggState *state; ! if (PG_ARGISNULL(0)) PG_RETURN_NULL(); ! state = (NumericAggState *) PG_GETARG_POINTER(0); ! ! N_datum = DirectFunctionCall1(int8_numeric, Int64GetDatum(state->N)); ! sumX_datum = NumericGetDatum(make_result(&state->sumX)); ! ! PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum)); } + + Datum + numeric_sum(PG_FUNCTION_ARGS) + { + NumericAggState *state; + + if (PG_ARGISNULL(0)) + PG_RETURN_NULL(); + + state = (NumericAggState *) PG_GETARG_POINTER(0); + + PG_RETURN_NUMERIC(make_result(&(state->sumX))); + } + + /* * Workhorse routine for the standard deviance and variance ! * aggregates. 'state' is aggregate's transition state. ! * 'variance' specifies whether we should calculate the * variance or the standard deviation. 'sample' indicates whether the * caller is interested in the sample or the population * variance/stddev. *************** *** 2667,2682 **** numeric_avg(PG_FUNCTION_ARGS) * *is_null is set to true and NULL is returned. */ static Numeric ! numeric_stddev_internal(ArrayType *transarray, bool variance, bool sample, bool *is_null) { ! Datum *transdatums; ! int ndatums; ! Numeric N, ! sumX, ! sumX2, ! res; NumericVar vN, vsumX, vsumX2, --- 2779,2789 ---- * *is_null is set to true and NULL is returned. */ static Numeric ! numeric_stddev_internal(NumericAggState *state, bool variance, bool sample, bool *is_null) { ! Numeric res; NumericVar vN, vsumX, vsumX2, *************** *** 2684,2705 **** numeric_stddev_internal(ArrayType *transarray, NumericVar *comp; int rscale; *is_null = false; ! /* We assume the input is array of numeric */ ! deconstruct_array(transarray, ! NUMERICOID, -1, false, 'i', ! &transdatums, NULL, &ndatums); ! if (ndatums != 3) ! elog(ERROR, "expected 3-element numeric array"); ! N = DatumGetNumeric(transdatums[0]); ! sumX = DatumGetNumeric(transdatums[1]); ! sumX2 = DatumGetNumeric(transdatums[2]); ! ! if (NUMERIC_IS_NAN(N) || NUMERIC_IS_NAN(sumX) || NUMERIC_IS_NAN(sumX2)) return make_result(&const_nan); ! init_var_from_num(N, &vN); /* * Sample stddev and variance are undefined when N <= 1; population stddev --- 2791,2814 ---- NumericVar *comp; int rscale; + if (state == NULL) + { + *is_null = true; + return NULL; + } + *is_null = false; ! if (state->isNaN) return make_result(&const_nan); ! init_var(&vN); ! init_var(&vsumX); ! init_var(&vsumX2); ! ! int8_to_numericvar(state->N, &vN); ! set_var_from_var(&(state->sumX), &vsumX); ! set_var_from_var(&(state->sumX2), &vsumX2); /* * Sample stddev and variance are undefined when N <= 1; population stddev *************** *** 2719,2726 **** numeric_stddev_internal(ArrayType *transarray, init_var(&vNminus1); sub_var(&vN, &const_one, &vNminus1); ! init_var_from_num(sumX, &vsumX); ! init_var_from_num(sumX2, &vsumX2); /* compute rscale for mul_var calls */ rscale = vsumX.dscale * 2; --- 2828,2835 ---- init_var(&vNminus1); sub_var(&vN, &const_one, &vNminus1); ! set_var_from_var(&(state->sumX), &vsumX); ! set_var_from_var(&(state->sumX2), &vsumX2); /* compute rscale for mul_var calls */ rscale = vsumX.dscale * 2; *************** *** 2761,2767 **** numeric_var_samp(PG_FUNCTION_ARGS) Numeric res; bool is_null; ! res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0), true, true, &is_null); if (is_null) --- 2870,2876 ---- Numeric res; bool is_null; ! res = numeric_stddev_internal((NumericAggState *) PG_GETARG_POINTER(0), true, true, &is_null); if (is_null) *************** *** 2776,2782 **** numeric_stddev_samp(PG_FUNCTION_ARGS) Numeric res; bool is_null; ! res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0), false, true, &is_null); if (is_null) --- 2885,2891 ---- Numeric res; bool is_null; ! res = numeric_stddev_internal((NumericAggState *) PG_GETARG_POINTER(0), false, true, &is_null); if (is_null) *************** *** 2791,2797 **** numeric_var_pop(PG_FUNCTION_ARGS) Numeric res; bool is_null; ! res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0), true, false, &is_null); if (is_null) --- 2900,2906 ---- Numeric res; bool is_null; ! res = numeric_stddev_internal((NumericAggState *) PG_GETARG_POINTER(0), true, false, &is_null); if (is_null) *************** *** 2806,2812 **** numeric_stddev_pop(PG_FUNCTION_ARGS) Numeric res; bool is_null; ! res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0), false, false, &is_null); if (is_null) --- 2915,2921 ---- Numeric res; bool is_null; ! res = numeric_stddev_internal((NumericAggState *) PG_GETARG_POINTER(0), false, false, &is_null); if (is_null) *** a/src/bin/pg_dump/pg_dump.c --- b/src/bin/pg_dump/pg_dump.c *************** *** 11402,11413 **** dumpAgg(Archive *fout, AggInfo *agginfo) --- 11402,11415 ---- int i_aggfinalfn; int i_aggsortop; int i_aggtranstype; + int i_aggtransspace; int i_agginitval; int i_convertok; const char *aggtransfn; const char *aggfinalfn; const char *aggsortop; const char *aggtranstype; + const char *aggtransspace; const char *agginitval; bool convertok; *************** *** 11425,11436 **** dumpAgg(Archive *fout, AggInfo *agginfo) selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name); /* Get aggregate-specific details */ ! if (fout->remoteVersion >= 80100) { appendPQExpBuffer(query, "SELECT aggtransfn, " "aggfinalfn, aggtranstype::pg_catalog.regtype, " "aggsortop::pg_catalog.regoperator, " ! "agginitval, " "'t'::boolean AS convertok " "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " "WHERE a.aggfnoid = p.oid " --- 11427,11450 ---- selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name); /* Get aggregate-specific details */ ! if (fout->remoteVersion >= 90300) ! { ! appendPQExpBuffer(query, "SELECT aggtransfn, " ! "aggfinalfn, aggtranstype::pg_catalog.regtype, " ! "aggsortop::pg_catalog.regoperator, " ! "aggtransspace, agginitval, " ! "'t'::boolean AS convertok " ! "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " ! "WHERE a.aggfnoid = p.oid " ! "AND p.oid = '%u'::pg_catalog.oid", ! agginfo->aggfn.dobj.catId.oid); ! } ! else if (fout->remoteVersion >= 80100) { appendPQExpBuffer(query, "SELECT aggtransfn, " "aggfinalfn, aggtranstype::pg_catalog.regtype, " "aggsortop::pg_catalog.regoperator, " ! "0 AS aggtransspace, agginitval, " "'t'::boolean AS convertok " "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " "WHERE a.aggfnoid = p.oid " *************** *** 11442,11448 **** dumpAgg(Archive *fout, AggInfo *agginfo) appendPQExpBuffer(query, "SELECT aggtransfn, " "aggfinalfn, aggtranstype::pg_catalog.regtype, " "0 AS aggsortop, " ! "agginitval, " "'t'::boolean AS convertok " "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " "WHERE a.aggfnoid = p.oid " --- 11456,11462 ---- appendPQExpBuffer(query, "SELECT aggtransfn, " "aggfinalfn, aggtranstype::pg_catalog.regtype, " "0 AS aggsortop, " ! "0 AS aggtransspace, agginitval, " "'t'::boolean AS convertok " "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " "WHERE a.aggfnoid = p.oid " *************** *** 11454,11460 **** dumpAgg(Archive *fout, AggInfo *agginfo) appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, " "format_type(aggtranstype, NULL) AS aggtranstype, " "0 AS aggsortop, " ! "agginitval, " "'t'::boolean AS convertok " "FROM pg_aggregate " "WHERE oid = '%u'::oid", --- 11468,11474 ---- appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, " "format_type(aggtranstype, NULL) AS aggtranstype, " "0 AS aggsortop, " ! "0 AS aggtransspace, agginitval, " "'t'::boolean AS convertok " "FROM pg_aggregate " "WHERE oid = '%u'::oid", *************** *** 11466,11472 **** dumpAgg(Archive *fout, AggInfo *agginfo) "aggfinalfn, " "(SELECT typname FROM pg_type WHERE oid = aggtranstype1) AS aggtranstype, " "0 AS aggsortop, " ! "agginitval1 AS agginitval, " "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) AS convertok " "FROM pg_aggregate " "WHERE oid = '%u'::oid", --- 11480,11486 ---- "aggfinalfn, " "(SELECT typname FROM pg_type WHERE oid = aggtranstype1) AS aggtranstype, " "0 AS aggsortop, " ! "0 AS aggtransspace, agginitval1 AS agginitval, " "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) AS convertok " "FROM pg_aggregate " "WHERE oid = '%u'::oid", *************** *** 11479,11484 **** dumpAgg(Archive *fout, AggInfo *agginfo) --- 11493,11499 ---- i_aggfinalfn = PQfnumber(res, "aggfinalfn"); i_aggsortop = PQfnumber(res, "aggsortop"); i_aggtranstype = PQfnumber(res, "aggtranstype"); + i_aggtransspace = PQfnumber(res, "aggtransspace"); i_agginitval = PQfnumber(res, "agginitval"); i_convertok = PQfnumber(res, "convertok"); *************** *** 11486,11491 **** dumpAgg(Archive *fout, AggInfo *agginfo) --- 11501,11507 ---- aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn); aggsortop = PQgetvalue(res, 0, i_aggsortop); aggtranstype = PQgetvalue(res, 0, i_aggtranstype); + aggtransspace = PQgetvalue(res, 0, i_aggtransspace); agginitval = PQgetvalue(res, 0, i_agginitval); convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't'); *************** *** 11522,11527 **** dumpAgg(Archive *fout, AggInfo *agginfo) --- 11538,11549 ---- fmtId(aggtranstype)); } + if (strcmp(aggtransspace, "0") != 0) + { + appendPQExpBuffer(details, ",\n SSPACE = %s", + aggtransspace); + } + if (!PQgetisnull(res, 0, i_agginitval)) { appendPQExpBuffer(details, ",\n INITCOND = "); *** a/src/include/catalog/pg_aggregate.h --- b/src/include/catalog/pg_aggregate.h *************** *** 44,49 **** CATALOG(pg_aggregate,2600) BKI_WITHOUT_OIDS --- 44,50 ---- regproc aggfinalfn; Oid aggsortop; Oid aggtranstype; + int32 aggtransspace; #ifdef CATALOG_VARLEN /* variable-length fields start here */ text agginitval; *************** *** 62,74 **** typedef FormData_pg_aggregate *Form_pg_aggregate; * ---------------- */ ! #define Natts_pg_aggregate 6 #define Anum_pg_aggregate_aggfnoid 1 #define Anum_pg_aggregate_aggtransfn 2 #define Anum_pg_aggregate_aggfinalfn 3 #define Anum_pg_aggregate_aggsortop 4 #define Anum_pg_aggregate_aggtranstype 5 ! #define Anum_pg_aggregate_agginitval 6 /* ---------------- --- 63,76 ---- * ---------------- */ ! #define Natts_pg_aggregate 7 #define Anum_pg_aggregate_aggfnoid 1 #define Anum_pg_aggregate_aggtransfn 2 #define Anum_pg_aggregate_aggfinalfn 3 #define Anum_pg_aggregate_aggsortop 4 #define Anum_pg_aggregate_aggtranstype 5 ! #define Anum_pg_aggregate_aggtransspace 6 ! #define Anum_pg_aggregate_agginitval 7 /* ---------------- *************** *** 77,239 **** typedef FormData_pg_aggregate *Form_pg_aggregate; */ /* avg */ ! DATA(insert ( 2100 int8_avg_accum numeric_avg 0 1231 "{0,0}" )); ! DATA(insert ( 2101 int4_avg_accum int8_avg 0 1016 "{0,0}" )); ! DATA(insert ( 2102 int2_avg_accum int8_avg 0 1016 "{0,0}" )); ! DATA(insert ( 2103 numeric_avg_accum numeric_avg 0 1231 "{0,0}" )); ! DATA(insert ( 2104 float4_accum float8_avg 0 1022 "{0,0,0}" )); ! DATA(insert ( 2105 float8_accum float8_avg 0 1022 "{0,0,0}" )); ! DATA(insert ( 2106 interval_accum interval_avg 0 1187 "{0 second,0 second}" )); /* sum */ ! DATA(insert ( 2107 int8_sum - 0 1700 _null_ )); ! DATA(insert ( 2108 int4_sum - 0 20 _null_ )); ! DATA(insert ( 2109 int2_sum - 0 20 _null_ )); ! DATA(insert ( 2110 float4pl - 0 700 _null_ )); ! DATA(insert ( 2111 float8pl - 0 701 _null_ )); ! DATA(insert ( 2112 cash_pl - 0 790 _null_ )); ! DATA(insert ( 2113 interval_pl - 0 1186 _null_ )); ! DATA(insert ( 2114 numeric_add - 0 1700 _null_ )); /* max */ ! DATA(insert ( 2115 int8larger - 413 20 _null_ )); ! DATA(insert ( 2116 int4larger - 521 23 _null_ )); ! DATA(insert ( 2117 int2larger - 520 21 _null_ )); ! DATA(insert ( 2118 oidlarger - 610 26 _null_ )); ! DATA(insert ( 2119 float4larger - 623 700 _null_ )); ! DATA(insert ( 2120 float8larger - 674 701 _null_ )); ! DATA(insert ( 2121 int4larger - 563 702 _null_ )); ! DATA(insert ( 2122 date_larger - 1097 1082 _null_ )); ! DATA(insert ( 2123 time_larger - 1112 1083 _null_ )); ! DATA(insert ( 2124 timetz_larger - 1554 1266 _null_ )); ! DATA(insert ( 2125 cashlarger - 903 790 _null_ )); ! DATA(insert ( 2126 timestamp_larger - 2064 1114 _null_ )); ! DATA(insert ( 2127 timestamptz_larger - 1324 1184 _null_ )); ! DATA(insert ( 2128 interval_larger - 1334 1186 _null_ )); ! DATA(insert ( 2129 text_larger - 666 25 _null_ )); ! DATA(insert ( 2130 numeric_larger - 1756 1700 _null_ )); ! DATA(insert ( 2050 array_larger - 1073 2277 _null_ )); ! DATA(insert ( 2244 bpchar_larger - 1060 1042 _null_ )); ! DATA(insert ( 2797 tidlarger - 2800 27 _null_ )); ! DATA(insert ( 3526 enum_larger - 3519 3500 _null_ )); /* min */ ! DATA(insert ( 2131 int8smaller - 412 20 _null_ )); ! DATA(insert ( 2132 int4smaller - 97 23 _null_ )); ! DATA(insert ( 2133 int2smaller - 95 21 _null_ )); ! DATA(insert ( 2134 oidsmaller - 609 26 _null_ )); ! DATA(insert ( 2135 float4smaller - 622 700 _null_ )); ! DATA(insert ( 2136 float8smaller - 672 701 _null_ )); ! DATA(insert ( 2137 int4smaller - 562 702 _null_ )); ! DATA(insert ( 2138 date_smaller - 1095 1082 _null_ )); ! DATA(insert ( 2139 time_smaller - 1110 1083 _null_ )); ! DATA(insert ( 2140 timetz_smaller - 1552 1266 _null_ )); ! DATA(insert ( 2141 cashsmaller - 902 790 _null_ )); ! DATA(insert ( 2142 timestamp_smaller - 2062 1114 _null_ )); ! DATA(insert ( 2143 timestamptz_smaller - 1322 1184 _null_ )); ! DATA(insert ( 2144 interval_smaller - 1332 1186 _null_ )); ! DATA(insert ( 2145 text_smaller - 664 25 _null_ )); ! DATA(insert ( 2146 numeric_smaller - 1754 1700 _null_ )); ! DATA(insert ( 2051 array_smaller - 1072 2277 _null_ )); ! DATA(insert ( 2245 bpchar_smaller - 1058 1042 _null_ )); ! DATA(insert ( 2798 tidsmaller - 2799 27 _null_ )); ! DATA(insert ( 3527 enum_smaller - 3518 3500 _null_ )); /* count */ ! DATA(insert ( 2147 int8inc_any - 0 20 "0" )); ! DATA(insert ( 2803 int8inc - 0 20 "0" )); /* var_pop */ ! DATA(insert ( 2718 int8_accum numeric_var_pop 0 1231 "{0,0,0}" )); ! DATA(insert ( 2719 int4_accum numeric_var_pop 0 1231 "{0,0,0}" )); ! DATA(insert ( 2720 int2_accum numeric_var_pop 0 1231 "{0,0,0}" )); ! DATA(insert ( 2721 float4_accum float8_var_pop 0 1022 "{0,0,0}" )); ! DATA(insert ( 2722 float8_accum float8_var_pop 0 1022 "{0,0,0}" )); ! DATA(insert ( 2723 numeric_accum numeric_var_pop 0 1231 "{0,0,0}" )); /* var_samp */ ! DATA(insert ( 2641 int8_accum numeric_var_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2642 int4_accum numeric_var_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2643 int2_accum numeric_var_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2644 float4_accum float8_var_samp 0 1022 "{0,0,0}" )); ! DATA(insert ( 2645 float8_accum float8_var_samp 0 1022 "{0,0,0}" )); ! DATA(insert ( 2646 numeric_accum numeric_var_samp 0 1231 "{0,0,0}" )); /* variance: historical Postgres syntax for var_samp */ ! DATA(insert ( 2148 int8_accum numeric_var_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2149 int4_accum numeric_var_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2150 int2_accum numeric_var_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2151 float4_accum float8_var_samp 0 1022 "{0,0,0}" )); ! DATA(insert ( 2152 float8_accum float8_var_samp 0 1022 "{0,0,0}" )); ! DATA(insert ( 2153 numeric_accum numeric_var_samp 0 1231 "{0,0,0}" )); /* stddev_pop */ ! DATA(insert ( 2724 int8_accum numeric_stddev_pop 0 1231 "{0,0,0}" )); ! DATA(insert ( 2725 int4_accum numeric_stddev_pop 0 1231 "{0,0,0}" )); ! DATA(insert ( 2726 int2_accum numeric_stddev_pop 0 1231 "{0,0,0}" )); ! DATA(insert ( 2727 float4_accum float8_stddev_pop 0 1022 "{0,0,0}" )); ! DATA(insert ( 2728 float8_accum float8_stddev_pop 0 1022 "{0,0,0}" )); ! DATA(insert ( 2729 numeric_accum numeric_stddev_pop 0 1231 "{0,0,0}" )); /* stddev_samp */ ! DATA(insert ( 2712 int8_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2713 int4_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2714 int2_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2715 float4_accum float8_stddev_samp 0 1022 "{0,0,0}" )); ! DATA(insert ( 2716 float8_accum float8_stddev_samp 0 1022 "{0,0,0}" )); ! DATA(insert ( 2717 numeric_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); /* stddev: historical Postgres syntax for stddev_samp */ ! DATA(insert ( 2154 int8_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2155 int4_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2156 int2_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); ! DATA(insert ( 2157 float4_accum float8_stddev_samp 0 1022 "{0,0,0}" )); ! DATA(insert ( 2158 float8_accum float8_stddev_samp 0 1022 "{0,0,0}" )); ! DATA(insert ( 2159 numeric_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); /* SQL2003 binary regression aggregates */ ! DATA(insert ( 2818 int8inc_float8_float8 - 0 20 "0" )); ! DATA(insert ( 2819 float8_regr_accum float8_regr_sxx 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2820 float8_regr_accum float8_regr_syy 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2821 float8_regr_accum float8_regr_sxy 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2822 float8_regr_accum float8_regr_avgx 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2823 float8_regr_accum float8_regr_avgy 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2824 float8_regr_accum float8_regr_r2 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2825 float8_regr_accum float8_regr_slope 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2826 float8_regr_accum float8_regr_intercept 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2827 float8_regr_accum float8_covar_pop 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2828 float8_regr_accum float8_covar_samp 0 1022 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2829 float8_regr_accum float8_corr 0 1022 "{0,0,0,0,0,0}" )); /* boolean-and and boolean-or */ ! DATA(insert ( 2517 booland_statefunc - 58 16 _null_ )); ! DATA(insert ( 2518 boolor_statefunc - 59 16 _null_ )); ! DATA(insert ( 2519 booland_statefunc - 58 16 _null_ )); /* bitwise integer */ ! DATA(insert ( 2236 int2and - 0 21 _null_ )); ! DATA(insert ( 2237 int2or - 0 21 _null_ )); ! DATA(insert ( 2238 int4and - 0 23 _null_ )); ! DATA(insert ( 2239 int4or - 0 23 _null_ )); ! DATA(insert ( 2240 int8and - 0 20 _null_ )); ! DATA(insert ( 2241 int8or - 0 20 _null_ )); ! DATA(insert ( 2242 bitand - 0 1560 _null_ )); ! DATA(insert ( 2243 bitor - 0 1560 _null_ )); /* xml */ ! DATA(insert ( 2901 xmlconcat2 - 0 142 _null_ )); /* array */ ! DATA(insert ( 2335 array_agg_transfn array_agg_finalfn 0 2281 _null_ )); /* text */ ! DATA(insert ( 3538 string_agg_transfn string_agg_finalfn 0 2281 _null_ )); /* bytea */ ! DATA(insert ( 3545 bytea_string_agg_transfn bytea_string_agg_finalfn 0 2281 _null_ )); /* json */ ! DATA(insert ( 3175 json_agg_transfn json_agg_finalfn 0 2281 _null_ )); /* * prototypes for functions in pg_aggregate.c --- 79,241 ---- */ /* avg */ ! DATA(insert ( 2100 int8_avg_accum numeric_avg 0 2281 128 _null_ )); ! DATA(insert ( 2101 int4_avg_accum int8_avg 0 1016 0 "{0,0}" )); ! DATA(insert ( 2102 int2_avg_accum int8_avg 0 1016 0 "{0,0}" )); ! DATA(insert ( 2103 numeric_avg_accum numeric_avg 0 2281 128 _null_ )); ! DATA(insert ( 2104 float4_accum float8_avg 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2105 float8_accum float8_avg 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2106 interval_accum interval_avg 0 1187 0 "{0 second,0 second}" )); /* sum */ ! DATA(insert ( 2107 int8_avg_accum numeric_sum 0 2281 128 _null_ )); ! DATA(insert ( 2108 int4_sum - 0 20 0 _null_ )); ! DATA(insert ( 2109 int2_sum - 0 20 0 _null_ )); ! DATA(insert ( 2110 float4pl - 0 700 0 _null_ )); ! DATA(insert ( 2111 float8pl - 0 701 0 _null_ )); ! DATA(insert ( 2112 cash_pl - 0 790 0 _null_ )); ! DATA(insert ( 2113 interval_pl - 0 1186 0 _null_ )); ! DATA(insert ( 2114 numeric_avg_accum numeric_sum 0 2281 128 _null_ )); /* max */ ! DATA(insert ( 2115 int8larger - 413 20 0 _null_ )); ! DATA(insert ( 2116 int4larger - 521 23 0 _null_ )); ! DATA(insert ( 2117 int2larger - 520 21 0 _null_ )); ! DATA(insert ( 2118 oidlarger - 610 26 0 _null_ )); ! DATA(insert ( 2119 float4larger - 623 700 0 _null_ )); ! DATA(insert ( 2120 float8larger - 674 701 0 _null_ )); ! DATA(insert ( 2121 int4larger - 563 702 0 _null_ )); ! DATA(insert ( 2122 date_larger - 1097 1082 0 _null_ )); ! DATA(insert ( 2123 time_larger - 1112 1083 0 _null_ )); ! DATA(insert ( 2124 timetz_larger - 1554 1266 0 _null_ )); ! DATA(insert ( 2125 cashlarger - 903 790 0 _null_ )); ! DATA(insert ( 2126 timestamp_larger - 2064 1114 0 _null_ )); ! DATA(insert ( 2127 timestamptz_larger - 1324 1184 0 _null_ )); ! DATA(insert ( 2128 interval_larger - 1334 1186 0 _null_ )); ! DATA(insert ( 2129 text_larger - 666 25 0 _null_ )); ! DATA(insert ( 2130 numeric_larger - 1756 1700 0 _null_ )); ! DATA(insert ( 2050 array_larger - 1073 2277 0 _null_ )); ! DATA(insert ( 2244 bpchar_larger - 1060 1042 0 _null_ )); ! DATA(insert ( 2797 tidlarger - 2800 27 0 _null_ )); ! DATA(insert ( 3526 enum_larger - 3519 3500 0 _null_ )); /* min */ ! DATA(insert ( 2131 int8smaller - 412 20 0 _null_ )); ! DATA(insert ( 2132 int4smaller - 97 23 0 _null_ )); ! DATA(insert ( 2133 int2smaller - 95 21 0 _null_ )); ! DATA(insert ( 2134 oidsmaller - 609 26 0 _null_ )); ! DATA(insert ( 2135 float4smaller - 622 700 0 _null_ )); ! DATA(insert ( 2136 float8smaller - 672 701 0 _null_ )); ! DATA(insert ( 2137 int4smaller - 562 702 0 _null_ )); ! DATA(insert ( 2138 date_smaller - 1095 1082 0 _null_ )); ! DATA(insert ( 2139 time_smaller - 1110 1083 0 _null_ )); ! DATA(insert ( 2140 timetz_smaller - 1552 1266 0 _null_ )); ! DATA(insert ( 2141 cashsmaller - 902 790 0 _null_ )); ! DATA(insert ( 2142 timestamp_smaller - 2062 1114 0 _null_ )); ! DATA(insert ( 2143 timestamptz_smaller - 1322 1184 0 _null_ )); ! DATA(insert ( 2144 interval_smaller - 1332 1186 0 _null_ )); ! DATA(insert ( 2145 text_smaller - 664 25 0 _null_ )); ! DATA(insert ( 2146 numeric_smaller - 1754 1700 0 _null_ )); ! DATA(insert ( 2051 array_smaller - 1072 2277 0 _null_ )); ! DATA(insert ( 2245 bpchar_smaller - 1058 1042 0 _null_ )); ! DATA(insert ( 2798 tidsmaller - 2799 27 0 _null_ )); ! DATA(insert ( 3527 enum_smaller - 3518 3500 0 _null_ )); /* count */ ! DATA(insert ( 2147 int8inc_any - 0 20 0 "0" )); ! DATA(insert ( 2803 int8inc - 0 20 0 "0" )); /* var_pop */ ! DATA(insert ( 2718 int8_accum numeric_var_pop 0 2281 128 _null_ )); ! DATA(insert ( 2719 int4_accum numeric_var_pop 0 2281 128 _null_ )); ! DATA(insert ( 2720 int2_accum numeric_var_pop 0 2281 128 _null_ )); ! DATA(insert ( 2721 float4_accum float8_var_pop 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2722 float8_accum float8_var_pop 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2723 numeric_accum numeric_var_pop 0 2281 128 _null_ )); /* var_samp */ ! DATA(insert ( 2641 int8_accum numeric_var_samp 0 2281 128 _null_ )); ! DATA(insert ( 2642 int4_accum numeric_var_samp 0 2281 128 _null_ )); ! DATA(insert ( 2643 int2_accum numeric_var_samp 0 2281 128 _null_ )); ! DATA(insert ( 2644 float4_accum float8_var_samp 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2645 float8_accum float8_var_samp 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2646 numeric_accum numeric_var_samp 0 2281 128 _null_ )); /* variance: historical Postgres syntax for var_samp */ ! DATA(insert ( 2148 int8_accum numeric_var_samp 0 2281 128 _null_ )); ! DATA(insert ( 2149 int4_accum numeric_var_samp 0 2281 128 _null_ )); ! DATA(insert ( 2150 int2_accum numeric_var_samp 0 2281 128 _null_ )); ! DATA(insert ( 2151 float4_accum float8_var_samp 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2152 float8_accum float8_var_samp 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2153 numeric_accum numeric_var_samp 0 2281 128 _null_ )); /* stddev_pop */ ! DATA(insert ( 2724 int8_accum numeric_stddev_pop 0 2281 128 _null_ )); ! DATA(insert ( 2725 int4_accum numeric_stddev_pop 0 2281 128 _null_ )); ! DATA(insert ( 2726 int2_accum numeric_stddev_pop 0 2281 128 _null_ )); ! DATA(insert ( 2727 float4_accum float8_stddev_pop 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2728 float8_accum float8_stddev_pop 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2729 numeric_accum numeric_stddev_pop 0 2281 128 _null_ )); /* stddev_samp */ ! DATA(insert ( 2712 int8_accum numeric_stddev_samp 0 2281 128 _null_ )); ! DATA(insert ( 2713 int4_accum numeric_stddev_samp 0 2281 128 _null_ )); ! DATA(insert ( 2714 int2_accum numeric_stddev_samp 0 2281 128 _null_ )); ! DATA(insert ( 2715 float4_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2716 float8_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2717 numeric_accum numeric_stddev_samp 0 2281 128 _null_ )); /* stddev: historical Postgres syntax for stddev_samp */ ! DATA(insert ( 2154 int8_accum numeric_stddev_samp 0 2281 128 _null_ )); ! DATA(insert ( 2155 int4_accum numeric_stddev_samp 0 2281 128 _null_ )); ! DATA(insert ( 2156 int2_accum numeric_stddev_samp 0 2281 128 _null_ )); ! DATA(insert ( 2157 float4_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2158 float8_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); ! DATA(insert ( 2159 numeric_accum numeric_stddev_samp 0 2281 128 _null_ )); /* SQL2003 binary regression aggregates */ ! DATA(insert ( 2818 int8inc_float8_float8 - 0 20 0 "0" )); ! DATA(insert ( 2819 float8_regr_accum float8_regr_sxx 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2820 float8_regr_accum float8_regr_syy 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2821 float8_regr_accum float8_regr_sxy 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2822 float8_regr_accum float8_regr_avgx 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2823 float8_regr_accum float8_regr_avgy 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2824 float8_regr_accum float8_regr_r2 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2825 float8_regr_accum float8_regr_slope 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2826 float8_regr_accum float8_regr_intercept 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2827 float8_regr_accum float8_covar_pop 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2828 float8_regr_accum float8_covar_samp 0 1022 0 "{0,0,0,0,0,0}" )); ! DATA(insert ( 2829 float8_regr_accum float8_corr 0 1022 0 "{0,0,0,0,0,0}" )); /* boolean-and and boolean-or */ ! DATA(insert ( 2517 booland_statefunc - 58 16 0 _null_ )); ! DATA(insert ( 2518 boolor_statefunc - 59 16 0 _null_ )); ! DATA(insert ( 2519 booland_statefunc - 58 16 0 _null_ )); /* bitwise integer */ ! DATA(insert ( 2236 int2and - 0 21 0 _null_ )); ! DATA(insert ( 2237 int2or - 0 21 0 _null_ )); ! DATA(insert ( 2238 int4and - 0 23 0 _null_ )); ! DATA(insert ( 2239 int4or - 0 23 0 _null_ )); ! DATA(insert ( 2240 int8and - 0 20 0 _null_ )); ! DATA(insert ( 2241 int8or - 0 20 0 _null_ )); ! DATA(insert ( 2242 bitand - 0 1560 0 _null_ )); ! DATA(insert ( 2243 bitor - 0 1560 0 _null_ )); /* xml */ ! DATA(insert ( 2901 xmlconcat2 - 0 142 0 _null_ )); /* array */ ! DATA(insert ( 2335 array_agg_transfn array_agg_finalfn 0 2281 0 _null_ )); /* text */ ! DATA(insert ( 3538 string_agg_transfn string_agg_finalfn 0 2281 0 _null_ )); /* bytea */ ! DATA(insert ( 3545 bytea_string_agg_transfn bytea_string_agg_finalfn 0 2281 0 _null_ )); /* json */ ! DATA(insert ( 3175 json_agg_transfn json_agg_finalfn 0 2281 0 _null_ )); /* * prototypes for functions in pg_aggregate.c *************** *** 246,251 **** extern Oid AggregateCreate(const char *aggName, --- 248,254 ---- List *aggfinalfnName, List *aggsortopName, Oid aggTransType, + int32 aggTransSpace, const char *agginitval); #endif /* PG_AGGREGATE_H */ *** a/src/include/catalog/pg_proc.h --- b/src/include/catalog/pg_proc.h *************** *** 2381,2407 **** DATA(insert OID = 2513 ( float8_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f t f i DESCR("aggregate final function"); DATA(insert OID = 1832 ( float8_stddev_samp PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "1022" _null_ _null_ _null_ _null_ float8_stddev_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 1833 ( numeric_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1700" _null_ _null_ _null_ _null_ numeric_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 2858 ( numeric_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1700" _null_ _null_ _null_ _null_ numeric_avg_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 1834 ( int2_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 21" _null_ _null_ _null_ _null_ int2_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 1835 ( int4_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 23" _null_ _null_ _null_ _null_ int4_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 1836 ( int8_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 20" _null_ _null_ _null_ _null_ int8_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 2746 ( int8_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 20" _null_ _null_ _null_ _null_ int8_avg_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 1837 ( numeric_avg PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_avg _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 2514 ( numeric_var_pop PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_var_pop _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 1838 ( numeric_var_samp PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_var_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 2596 ( numeric_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_stddev_pop _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 1839 ( numeric_stddev_samp PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_stddev_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); DATA(insert OID = 1840 ( int2_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 20 "20 21" _null_ _null_ _null_ _null_ int2_sum _null_ _null_ _null_ )); DESCR("aggregate transition function"); --- 2381,2409 ---- DESCR("aggregate final function"); DATA(insert OID = 1832 ( float8_stddev_samp PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "1022" _null_ _null_ _null_ _null_ float8_stddev_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 1833 ( numeric_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 1700" _null_ _null_ _null_ _null_ numeric_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 2858 ( numeric_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 1700" _null_ _null_ _null_ _null_ numeric_avg_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 1834 ( int2_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 21" _null_ _null_ _null_ _null_ int2_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 1835 ( int4_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 23" _null_ _null_ _null_ _null_ int4_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 1836 ( int8_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 20" _null_ _null_ _null_ _null_ int8_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 2746 ( int8_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 20" _null_ _null_ _null_ _null_ int8_avg_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); ! DATA(insert OID = 1837 ( numeric_avg PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_avg _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 3179 ( numeric_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_sum _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 2514 ( numeric_var_pop PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_var_pop _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 1838 ( numeric_var_samp PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_var_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); ! DATA(insert OID = 2596 ( numeric_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_stddev_pop _null_ _null_ _null_ )); ! DESCR("aggregate final function"); ! DATA(insert OID = 1839 ( numeric_stddev_samp PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_stddev_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); DATA(insert OID = 1840 ( int2_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 20 "20 21" _null_ _null_ _null_ _null_ int2_sum _null_ _null_ _null_ )); DESCR("aggregate transition function"); *** a/src/include/commands/defrem.h --- b/src/include/commands/defrem.h *************** *** 122,127 **** extern Datum transformGenericOptions(Oid catalogId, --- 122,128 ---- extern char *defGetString(DefElem *def); extern double defGetNumeric(DefElem *def); extern bool defGetBoolean(DefElem *def); + extern int32 defGetInt32(DefElem *def); extern int64 defGetInt64(DefElem *def); extern List *defGetQualifiedName(DefElem *def); extern TypeName *defGetTypeName(DefElem *def); *** a/src/include/utils/builtins.h --- b/src/include/utils/builtins.h *************** *** 981,986 **** extern Datum int4_accum(PG_FUNCTION_ARGS); --- 981,987 ---- extern Datum int8_accum(PG_FUNCTION_ARGS); extern Datum int8_avg_accum(PG_FUNCTION_ARGS); extern Datum numeric_avg(PG_FUNCTION_ARGS); + extern Datum numeric_sum(PG_FUNCTION_ARGS); extern Datum numeric_var_pop(PG_FUNCTION_ARGS); extern Datum numeric_var_samp(PG_FUNCTION_ARGS); extern Datum numeric_stddev_pop(PG_FUNCTION_ARGS);