<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
<entry>Data type of the aggregate function's internal transition (state) data</entry>
</row>
- <row>
- <entry><structfield>aggserialtype</structfield></entry>
- <entry><type>oid</type></entry>
- <entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
- <entry>Return data type of the aggregate function's serialization function (zero if none)</entry>
- </row>
<row>
<entry><structfield>aggtransspace</structfield></entry>
<entry><type>int4</type></entry>
[ , COMBINEFUNC = <replaceable class="PARAMETER">combinefunc</replaceable> ]
[ , SERIALFUNC = <replaceable class="PARAMETER">serialfunc</replaceable> ]
[ , DESERIALFUNC = <replaceable class="PARAMETER">deserialfunc</replaceable> ]
- [ , SERIALTYPE = <replaceable class="PARAMETER">serialtype</replaceable> ]
[ , INITCOND = <replaceable class="PARAMETER">initial_condition</replaceable> ]
[ , MSFUNC = <replaceable class="PARAMETER">msfunc</replaceable> ]
[ , MINVFUNC = <replaceable class="PARAMETER">minvfunc</replaceable> ]
[ , SSPACE = <replaceable class="PARAMETER">state_data_size</replaceable> ]
[ , FINALFUNC = <replaceable class="PARAMETER">ffunc</replaceable> ]
[ , FINALFUNC_EXTRA ]
- [ , COMBINEFUNC = <replaceable class="PARAMETER">combinefunc</replaceable> ]
- [ , SERIALFUNC = <replaceable class="PARAMETER">serialfunc</replaceable> ]
- [ , DESERIALFUNC = <replaceable class="PARAMETER">deserialfunc</replaceable> ]
- [ , SERIALTYPE = <replaceable class="PARAMETER">serialtype</replaceable> ]
[ , INITCOND = <replaceable class="PARAMETER">initial_condition</replaceable> ]
[ , HYPOTHETICAL ]
[ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
[ , COMBINEFUNC = <replaceable class="PARAMETER">combinefunc</replaceable> ]
[ , SERIALFUNC = <replaceable class="PARAMETER">serialfunc</replaceable> ]
[ , DESERIALFUNC = <replaceable class="PARAMETER">deserialfunc</replaceable> ]
- [ , SERIALTYPE = <replaceable class="PARAMETER">serialtype</replaceable> ]
[ , INITCOND = <replaceable class="PARAMETER">initial_condition</replaceable> ]
[ , MSFUNC = <replaceable class="PARAMETER">msfunc</replaceable> ]
[ , MINVFUNC = <replaceable class="PARAMETER">minvfunc</replaceable> ]
To be able to create an aggregate function, you must
have <literal>USAGE</literal> privilege on the argument types, the state
type(s), and the return type, as well as <literal>EXECUTE</literal>
- privilege on the transition and final functions.
+ privilege on the supporting functions.
</para>
</refsect1>
<term><replaceable class="PARAMETER">combinefunc</replaceable></term>
<listitem>
<para>
- The <replaceable class="PARAMETER">combinefunc</replaceable> may
- optionally be specified in order to allow the aggregate function to
- support partial aggregation. This is a prerequisite to allow the
- aggregate to participate in certain optimizations such as parallel
- aggregation.
+ The <replaceable class="PARAMETER">combinefunc</replaceable> function
+ may optionally be specified to allow the aggregate function to support
+ partial aggregation. This is a prerequisite to allow the aggregate to
+ participate in certain optimizations such as parallel aggregation.
</para>
<para>
- This function can be thought of as an <replaceable class="PARAMETER">
- sfunc</replaceable>, where instead of acting upon individual input rows
- and adding these to the aggregate state, it adds other aggregate states
- to the aggregate state.
+ If provided,
+ the <replaceable class="PARAMETER">combinefunc</replaceable> must
+ combine two <replaceable class="PARAMETER">state_data_type</replaceable>
+ values, each containing the result of aggregation over some subset of
+ the input values, to produce a
+ new <replaceable class="PARAMETER">state_data_type</replaceable> that
+ represents the result of aggregating over both sets of inputs. This
+ function can be thought of as
+ an <replaceable class="PARAMETER">sfunc</replaceable>, where instead of
+ acting upon individual input rows and adding these to the aggregate
+ state, it adds another aggregate state to the aggregate state.
+ Typically, it is not possible to define
+ a <replaceable class="PARAMETER">combinefunc</replaceable> for aggregate
+ functions that are sensitive to the order of the input values, since the
+ relative ordering of the inputs that went into the subset states is
+ indeterminate.
</para>
<para>
The <replaceable class="PARAMETER">combinefunc</replaceable> must accept
- two arguments of <replaceable class="PARAMETER">state_data_type
- </replaceable> and return <replaceable class="PARAMETER">state_data_type
- </replaceable>. Optionally this function may be <quote>strict</quote>. In
- this case the function will not be called when either of the input states
- are null.
+ two arguments of
+ the <replaceable class="PARAMETER">state_data_type</replaceable> and
+ return a value of
+ the <replaceable class="PARAMETER">state_data_type</replaceable>.
+ Optionally this function may be <quote>strict</quote>. In this case the
+ function will not be called when either of the input states are null;
+ the other state will be taken as the correct result.
</para>
-
+
<para>
- For aggregate functions with an <literal>INTERNAL</literal>
- <replaceable class="PARAMETER">state_data_type</replaceable> the
- <replaceable class="PARAMETER">combinefunc</replaceable> must not be
- <quote>strict</quote>. In this scenario the
- <replaceable class="PARAMETER">combinefunc</replaceable> must take charge
- and ensure that the null states are handled correctly and that the state
- being returned is a pointer to memory which belongs in the aggregate
- memory context.
+ For aggregate functions
+ whose <replaceable class="PARAMETER">state_data_type</replaceable>
+ is <type>internal</type>,
+ the <replaceable class="PARAMETER">combinefunc</replaceable> must not be
+ strict. In this scenario
+ the <replaceable class="PARAMETER">combinefunc</replaceable> must ensure
+ that null states are handled correctly and that the state being returned
+ is properly stored in the aggregate memory context.
</para>
</listitem>
</varlistentry>
<term><replaceable class="PARAMETER">serialfunc</replaceable></term>
<listitem>
<para>
- In order to allow aggregate functions with an <literal>INTERNAL</>
- <replaceable class="PARAMETER">state_data_type</replaceable> to
- participate in parallel aggregation, the aggregate must have a valid
- <replaceable class="PARAMETER">serialfunc</replaceable>, which must
- serialize the aggregate state into <replaceable class="PARAMETER">
- serialtype</replaceable>. This function must take a single argument of
- <replaceable class="PARAMETER">state_data_type</replaceable> and return
- <replaceable class="PARAMETER">serialtype</replaceable>. A
+ An aggregate function
+ whose <replaceable class="PARAMETER">state_data_type</replaceable>
+ is <type>internal</> can participate in parallel aggregation only if it
+ has a <replaceable class="PARAMETER">serialfunc</replaceable> function,
+ which must serialize the aggregate state into a <type>bytea</> value for
+ transmission to another process. This function must take a single
+ argument of type <type>internal</> and return type <type>bytea</>. A
corresponding <replaceable class="PARAMETER">deserialfunc</replaceable>
is also required.
</para>
<term><replaceable class="PARAMETER">deserialfunc</replaceable></term>
<listitem>
<para>
- Deserializes a previously serialized aggregate state back into
+ Deserialize a previously serialized aggregate state back into
<replaceable class="PARAMETER">state_data_type</replaceable>. This
- function must take a single argument of <replaceable class="PARAMETER">
- serialtype</replaceable> and return <replaceable class="PARAMETER">
- state_data_type</replaceable>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="PARAMETER">serialtype</replaceable></term>
- <listitem>
- <para>
- The data type to into which an <literal>INTERNAL</literal> aggregate
- state should be serialized.
+ function must take two arguments of types <type>bytea</>
+ and <type>internal</>, and produce a result of type <type>internal</>.
+ (Note: the second, <type>internal</> argument is unused, but is required
+ for type safety reasons.)
</para>
</listitem>
</varlistentry>
bool mfinalfnExtraArgs,
List *aggsortopName,
Oid aggTransType,
- Oid aggSerialType,
int32 aggTransSpace,
Oid aggmTransType,
int32 aggmTransSpace,
}
/*
- * Validate the serialization function, if present. We must ensure that
- * the return type of this function is the same as the specified
- * serialType.
+ * Validate the serialization function, if present.
*/
if (aggserialfnName)
{
- fnArgs[0] = aggTransType;
+ fnArgs[0] = INTERNALOID;
serialfn = lookup_agg_function(aggserialfnName, 1,
fnArgs, variadicArgType,
&rettype);
- if (rettype != aggSerialType)
+ if (rettype != BYTEAOID)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("return type of serialization function %s is not %s",
NameListToString(aggserialfnName),
- format_type_be(aggSerialType))));
+ format_type_be(BYTEAOID))));
}
/*
- * Validate the deserialization function, if present. We must ensure that
- * the return type of this function is the same as the transType.
+ * Validate the deserialization function, if present.
*/
if (aggdeserialfnName)
{
- fnArgs[0] = aggSerialType;
+ fnArgs[0] = BYTEAOID;
+ fnArgs[1] = INTERNALOID; /* dummy argument for type safety */
- deserialfn = lookup_agg_function(aggdeserialfnName, 1,
+ deserialfn = lookup_agg_function(aggdeserialfnName, 2,
fnArgs, variadicArgType,
&rettype);
- if (rettype != aggTransType)
+ if (rettype != INTERNALOID)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("return type of deserialization function %s is not %s",
NameListToString(aggdeserialfnName),
- format_type_be(aggTransType))));
+ format_type_be(INTERNALOID))));
}
/*
values[Anum_pg_aggregate_aggmfinalextra - 1] = BoolGetDatum(mfinalfnExtraArgs);
values[Anum_pg_aggregate_aggsortop - 1] = ObjectIdGetDatum(sortop);
values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType);
- values[Anum_pg_aggregate_aggserialtype - 1] = ObjectIdGetDatum(aggSerialType);
values[Anum_pg_aggregate_aggtransspace - 1] = Int32GetDatum(aggTransSpace);
values[Anum_pg_aggregate_aggmtranstype - 1] = ObjectIdGetDatum(aggmTransType);
values[Anum_pg_aggregate_aggmtransspace - 1] = Int32GetDatum(aggmTransSpace);
* Create dependencies for the aggregate (above and beyond those already
* made by ProcedureCreate). Note: we don't need an explicit dependency
* on aggTransType since we depend on it indirectly through transfn.
- * Likewise for aggmTransType using the mtransfunc, and also for
- * aggSerialType using the serialfn, if they exist.
+ * Likewise for aggmTransType using the mtransfunc, if it exists.
*/
/* Depends on transition function */
List *sortoperatorName = NIL;
TypeName *baseType = NULL;
TypeName *transType = NULL;
- TypeName *serialType = NULL;
TypeName *mtransType = NULL;
int32 transSpace = 0;
int32 mtransSpace = 0;
List *parameterDefaults;
Oid variadicArgType;
Oid transTypeId;
- Oid serialTypeId = InvalidOid;
Oid mtransTypeId = InvalidOid;
char transTypeType;
char mtransTypeType = 0;
}
else if (pg_strcasecmp(defel->defname, "stype") == 0)
transType = defGetTypeName(defel);
- else if (pg_strcasecmp(defel->defname, "serialtype") == 0)
- serialType = defGetTypeName(defel);
else if (pg_strcasecmp(defel->defname, "stype1") == 0)
transType = defGetTypeName(defel);
else if (pg_strcasecmp(defel->defname, "sspace") == 0)
format_type_be(transTypeId))));
}
- if (serialType)
+ if (serialfuncName && deserialfuncName)
{
/*
- * There's little point in having a serialization/deserialization
- * function on aggregates that don't have an internal state, so let's
- * just disallow this as it may help clear up any confusion or
- * needless authoring of these functions.
+ * Serialization is only needed/allowed for transtype INTERNAL.
*/
if (transTypeId != INTERNALOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("a serialization type must only be specified when the aggregate transition data type is %s",
+ errmsg("serialization functions may be specified only when the aggregate transition data type is %s",
format_type_be(INTERNALOID))));
-
- serialTypeId = typenameTypeId(NULL, serialType);
-
- if (get_typtype(mtransTypeId) == TYPTYPE_PSEUDO &&
- !IsPolymorphicType(serialTypeId))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("aggregate serialization data type cannot be %s",
- format_type_be(serialTypeId))));
-
- /*
- * We disallow INTERNAL serialType as the whole point of the
- * serialized types is to allow the aggregate state to be output, and
- * we cannot output INTERNAL. This check, combined with the one above
- * ensures that the trans type and serialization type are not the
- * same.
- */
- if (serialTypeId == INTERNALOID)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("aggregate serialization data type cannot be %s",
- format_type_be(serialTypeId))));
-
- /*
- * If serialType is specified then serialfuncName and deserialfuncName
- * must be present; if not, then none of the serialization options
- * should have been specified.
- */
- if (serialfuncName == NIL)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("aggregate serialization function must be specified when serialization type is specified")));
-
- if (deserialfuncName == NIL)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("aggregate deserialization function must be specified when serialization type is specified")));
}
- else
+ else if (serialfuncName || deserialfuncName)
{
/*
- * If serialization type was not specified then there shouldn't be a
- * serialization function.
+ * Cannot specify one function without the other.
*/
- if (serialfuncName != NIL)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("must specify serialization type when specifying serialization function")));
-
- /* likewise for the deserialization function */
- if (deserialfuncName != NIL)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("must specify serialization type when specifying deserialization function")));
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+ errmsg("must specify both or neither of serialization and deserialization functions")));
}
/*
mfinalfuncExtraArgs,
sortoperatorName, /* sort operator name */
transTypeId, /* transition data type */
- serialTypeId, /* serialization data type */
transSpace, /* transition space */
mtransTypeId, /* transition data type */
mtransSpace, /* transition space */
static void build_pertrans_for_aggref(AggStatePerTrans pertrans,
AggState *aggsate, EState *estate,
Aggref *aggref, Oid aggtransfn, Oid aggtranstype,
- Oid aggserialtype, Oid aggserialfn,
- Oid aggdeserialfn, Datum initValue,
- bool initValueIsNull, Oid *inputTypes,
- int numArguments);
+ Oid aggserialfn, Oid aggdeserialfn,
+ Datum initValue, bool initValueIsNull,
+ Oid *inputTypes, int numArguments);
static int find_compatible_peragg(Aggref *newagg, AggState *aggstate,
int lastaggno, List **same_input_transnos);
static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg,
dsinfo->arg[0] = slot->tts_values[0];
dsinfo->argnull[0] = slot->tts_isnull[0];
+ /* Dummy second argument for type-safety reasons */
+ dsinfo->arg[1] = PointerGetDatum(NULL);
+ dsinfo->argnull[1] = false;
/*
* We run the deserialization functions in per-input-tuple
AclResult aclresult;
Oid transfn_oid,
finalfn_oid;
- Oid serialtype_oid,
- serialfn_oid,
+ Oid serialfn_oid,
deserialfn_oid;
Expr *finalfnexpr;
Oid aggtranstype;
else
peragg->finalfn_oid = finalfn_oid = InvalidOid;
- serialtype_oid = InvalidOid;
serialfn_oid = InvalidOid;
deserialfn_oid = InvalidOid;
{
/*
* The planner should only have generated an agg node with
- * serialStates if every aggregate with an INTERNAL state has a
- * serialization type, serialization function and deserialization
- * function. Let's ensure it didn't mess that up.
+ * serialStates if every aggregate with an INTERNAL state has
+ * serialization/deserialization functions. Verify that.
*/
- if (!OidIsValid(aggform->aggserialtype))
- elog(ERROR, "serialtype not set during serialStates aggregation step");
-
if (!OidIsValid(aggform->aggserialfn))
elog(ERROR, "serialfunc not set during serialStates aggregation step");
/* serialization func only required when not finalizing aggs */
if (!aggstate->finalizeAggs)
- {
serialfn_oid = aggform->aggserialfn;
- serialtype_oid = aggform->aggserialtype;
- }
/* deserialization func only required when combining states */
if (aggstate->combineStates)
- {
deserialfn_oid = aggform->aggdeserialfn;
- serialtype_oid = aggform->aggserialtype;
- }
}
/* Check that aggregate owner has permission to call component fns */
pertrans = &pertransstates[++transno];
build_pertrans_for_aggref(pertrans, aggstate, estate,
aggref, transfn_oid, aggtranstype,
- serialtype_oid, serialfn_oid,
- deserialfn_oid, initValue,
- initValueIsNull, inputTypes,
- numArguments);
+ serialfn_oid, deserialfn_oid,
+ initValue, initValueIsNull,
+ inputTypes, numArguments);
peragg->transno = transno;
}
ReleaseSysCache(aggTuple);
build_pertrans_for_aggref(AggStatePerTrans pertrans,
AggState *aggstate, EState *estate,
Aggref *aggref,
- Oid aggtransfn, Oid aggtranstype, Oid aggserialtype,
+ Oid aggtransfn, Oid aggtranstype,
Oid aggserialfn, Oid aggdeserialfn,
Datum initValue, bool initValueIsNull,
Oid *inputTypes, int numArguments)
if (OidIsValid(aggserialfn))
{
- build_aggregate_serialfn_expr(aggtranstype,
- aggserialtype,
- aggref->inputcollid,
- aggserialfn,
+ build_aggregate_serialfn_expr(aggserialfn,
&serialfnexpr);
fmgr_info(aggserialfn, &pertrans->serialfn);
fmgr_info_set_expr((Node *) serialfnexpr, &pertrans->serialfn);
InitFunctionCallInfoData(pertrans->serialfn_fcinfo,
&pertrans->serialfn,
1,
- pertrans->aggCollation,
+ InvalidOid,
(void *) aggstate, NULL);
}
if (OidIsValid(aggdeserialfn))
{
- build_aggregate_serialfn_expr(aggserialtype,
- aggtranstype,
- aggref->inputcollid,
- aggdeserialfn,
- &deserialfnexpr);
+ build_aggregate_deserialfn_expr(aggdeserialfn,
+ &deserialfnexpr);
fmgr_info(aggdeserialfn, &pertrans->deserialfn);
fmgr_info_set_expr((Node *) deserialfnexpr, &pertrans->deserialfn);
InitFunctionCallInfoData(pertrans->deserialfn_fcinfo,
&pertrans->deserialfn,
- 1,
- pertrans->aggCollation,
+ 2,
+ InvalidOid,
(void *) aggstate, NULL);
}
/*
* If we find any aggs with an internal transtype then we must check
- * that these have a serialization type, serialization func and
- * deserialization func; otherwise, we set the maximum allowed type to
- * PAT_INTERNAL_ONLY.
+ * whether these have serialization/deserialization functions;
+ * otherwise, we set the maximum allowed type to PAT_INTERNAL_ONLY.
*/
if (aggform->aggtranstype == INTERNALOID &&
- (!OidIsValid(aggform->aggserialtype) ||
- !OidIsValid(aggform->aggserialfn) ||
+ (!OidIsValid(aggform->aggserialfn) ||
!OidIsValid(aggform->aggdeserialfn)))
context->allowedtype = PAT_INTERNAL_ONLY;
#include "postgres.h"
#include "access/htup_details.h"
-#include "catalog/pg_aggregate.h"
+#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/tlist.h"
/*
* apply_partialaggref_adjustment
* Convert PathTarget to be suitable for a partial aggregate node. We simply
- * adjust any Aggref nodes found in the target and set the aggoutputtype to
- * the aggtranstype or aggserialtype. This allows exprType() to return the
+ * adjust any Aggref nodes found in the target and set the aggoutputtype
+ * appropriately. This allows exprType() to return the
* actual type that will be produced.
*
* Note: We expect 'target' to be a flat target list and not have Aggrefs buried
if (IsA(aggref, Aggref))
{
- HeapTuple aggTuple;
- Form_pg_aggregate aggform;
Aggref *newaggref;
- aggTuple = SearchSysCache1(AGGFNOID,
- ObjectIdGetDatum(aggref->aggfnoid));
- if (!HeapTupleIsValid(aggTuple))
- elog(ERROR, "cache lookup failed for aggregate %u",
- aggref->aggfnoid);
- aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
-
newaggref = (Aggref *) copyObject(aggref);
/*
- * Use the serialization type, if one exists. Note that we don't
- * support it being a polymorphic type. (XXX really we ought to
- * hardwire this as INTERNAL -> BYTEA, and avoid a catalog lookup
- * here altogether?)
+ * Normally, a partial aggregate returns the aggregate's
+ * transition type, but if that's INTERNAL, it returns BYTEA
+ * instead. (XXX this assumes we're doing parallel aggregate with
+ * serialization; later we might need an argument to tell this
+ * function whether we're doing parallel or just local partial
+ * aggregation.)
*/
- if (OidIsValid(aggform->aggserialtype))
- newaggref->aggoutputtype = aggform->aggserialtype;
+ Assert(OidIsValid(newaggref->aggtranstype));
+
+ if (newaggref->aggtranstype == INTERNALOID)
+ newaggref->aggoutputtype = BYTEAOID;
else
- {
- /* Otherwise, we return the aggregate's transition type */
- Assert(OidIsValid(newaggref->aggtranstype));
newaggref->aggoutputtype = newaggref->aggtranstype;
- }
/* flag it as partial */
newaggref->aggpartial = true;
lfirst(lc) = newaggref;
-
- ReleaseSysCache(aggTuple);
}
}
}
check_ungrouped_columns_context *context);
static void check_agglevels_and_constraints(ParseState *pstate, Node *expr);
static List *expand_groupingset_node(GroupingSet *gs);
+static Node *make_agg_arg(Oid argtype, Oid argcollation);
+
/*
* transformAggregateCall -
Expr **transfnexpr,
Expr **invtransfnexpr)
{
- Param *argp;
List *args;
FuncExpr *fexpr;
int i;
/*
- * Build arg list to use in the transfn FuncExpr node. We really only care
- * that transfn can discover the actual argument types at runtime using
- * get_fn_expr_argtype(), so it's okay to use Param nodes that don't
- * correspond to any real Param.
+ * Build arg list to use in the transfn FuncExpr node.
*/
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_state_type;
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
-
- args = list_make1(argp);
+ args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));
for (i = agg_num_direct_inputs; i < agg_num_inputs; i++)
{
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_input_types[i];
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
- args = lappend(args, argp);
+ args = lappend(args,
+ make_agg_arg(agg_input_types[i], agg_input_collation));
}
fexpr = makeFuncExpr(transfn_oid,
Oid combinefn_oid,
Expr **combinefnexpr)
{
- Param *argp;
+ Node *argp;
List *args;
FuncExpr *fexpr;
- /* Build arg list to use in the combinefn FuncExpr node. */
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_state_type;
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
+ /* combinefn takes two arguments of the aggregate state type */
+ argp = make_agg_arg(agg_state_type, agg_input_collation);
- /* transition state type is arg 1 and 2 */
args = list_make2(argp, argp);
fexpr = makeFuncExpr(combinefn_oid,
InvalidOid,
agg_input_collation,
COERCE_EXPLICIT_CALL);
- fexpr->funcvariadic = false;
+ /* combinefn is currently never treated as variadic */
*combinefnexpr = (Expr *) fexpr;
}
/*
* Like build_aggregate_transfn_expr, but creates an expression tree for the
- * serialization or deserialization function of an aggregate, rather than the
- * transition function. This may be used for either the serialization or
- * deserialization function by swapping the first two parameters over.
+ * serialization function of an aggregate.
*/
void
-build_aggregate_serialfn_expr(Oid agg_input_type,
- Oid agg_output_type,
- Oid agg_input_collation,
- Oid serialfn_oid,
+build_aggregate_serialfn_expr(Oid serialfn_oid,
Expr **serialfnexpr)
{
- Param *argp;
List *args;
FuncExpr *fexpr;
- /* Build arg list to use in the FuncExpr node. */
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_input_type;
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
-
- /* takes a single arg of the agg_input_type */
- args = list_make1(argp);
+ /* serialfn always takes INTERNAL and returns BYTEA */
+ args = list_make1(make_agg_arg(INTERNALOID, InvalidOid));
fexpr = makeFuncExpr(serialfn_oid,
- agg_output_type,
+ BYTEAOID,
args,
InvalidOid,
- agg_input_collation,
+ InvalidOid,
COERCE_EXPLICIT_CALL);
- fexpr->funcvariadic = false;
*serialfnexpr = (Expr *) fexpr;
}
+/*
+ * Like build_aggregate_transfn_expr, but creates an expression tree for the
+ * deserialization function of an aggregate.
+ */
+void
+build_aggregate_deserialfn_expr(Oid deserialfn_oid,
+ Expr **deserialfnexpr)
+{
+ List *args;
+ FuncExpr *fexpr;
+
+ /* deserialfn always takes BYTEA, INTERNAL and returns INTERNAL */
+ args = list_make2(make_agg_arg(BYTEAOID, InvalidOid),
+ make_agg_arg(INTERNALOID, InvalidOid));
+
+ fexpr = makeFuncExpr(deserialfn_oid,
+ INTERNALOID,
+ args,
+ InvalidOid,
+ InvalidOid,
+ COERCE_EXPLICIT_CALL);
+ *deserialfnexpr = (Expr *) fexpr;
+}
+
/*
* Like build_aggregate_transfn_expr, but creates an expression tree for the
* final function of an aggregate, rather than the transition function.
Oid finalfn_oid,
Expr **finalfnexpr)
{
- Param *argp;
List *args;
int i;
/*
* Build expr tree for final function
*/
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_state_type;
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
- args = list_make1(argp);
+ args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));
/* finalfn may take additional args, which match agg's input types */
for (i = 0; i < num_finalfn_inputs - 1; i++)
{
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_input_types[i];
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
- args = lappend(args, argp);
+ args = lappend(args,
+ make_agg_arg(agg_input_types[i], agg_input_collation));
}
*finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid,
COERCE_EXPLICIT_CALL);
/* finalfn is currently never treated as variadic */
}
+
+/*
+ * Convenience function to build dummy argument expressions for aggregates.
+ *
+ * We really only care that an aggregate support function can discover its
+ * actual argument types at runtime using get_fn_expr_argtype(), so it's okay
+ * to use Param nodes that don't correspond to any real Param.
+ */
+static Node *
+make_agg_arg(Oid argtype, Oid argcollation)
+{
+ Param *argp = makeNode(Param);
+
+ argp->paramkind = PARAM_EXEC;
+ argp->paramid = -1;
+ argp->paramtype = argtype;
+ argp->paramtypmod = -1;
+ argp->paramcollid = argcollation;
+ argp->location = -1;
+ return (Node *) argp;
+}
/*
* numeric_avg_serialize
* Serialize NumericAggState for numeric aggregates that don't require
- * sumX2. Serializes NumericAggState into bytea using the standard pq API.
- *
- * numeric_avg_deserialize(numeric_avg_serialize(state)) must result in a state
- * which matches the original input state.
+ * sumX2.
*/
Datum
numeric_avg_serialize(PG_FUNCTION_ARGS)
/*
* numeric_avg_deserialize
- * Deserialize bytea into NumericAggState for numeric aggregates that
- * don't require sumX2. Deserializes bytea into NumericAggState using the
- * standard pq API.
- *
- * numeric_avg_serialize(numeric_avg_deserialize(bytea)) must result in a value
- * which matches the original bytea value.
+ * Deserialize bytea into NumericAggState for numeric aggregates that
+ * don't require sumX2.
*/
Datum
numeric_avg_deserialize(PG_FUNCTION_ARGS)
{
- bytea *sstate = PG_GETARG_BYTEA_P(0);
+ bytea *sstate;
NumericAggState *result;
Datum temp;
StringInfoData buf;
if (!AggCheckCallContext(fcinfo, NULL))
elog(ERROR, "aggregate function called in non-aggregate context");
+ sstate = PG_GETARG_BYTEA_P(0);
+
/*
* Copy the bytea into a StringInfo so that we can "receive" it using the
* standard pq API.
/*
* numeric_serialize
* Serialization function for NumericAggState for numeric aggregates that
- * require sumX2. Serializes NumericAggState into bytea using the standard
- * pq API.
- *
- * numeric_deserialize(numeric_serialize(state)) must result in a state which
- * matches the original input state.
+ * require sumX2.
*/
Datum
numeric_serialize(PG_FUNCTION_ARGS)
/*
* numeric_deserialize
* Deserialization function for NumericAggState for numeric aggregates that
- * require sumX2. Deserializes bytea into into NumericAggState using the
- * standard pq API.
- *
- * numeric_serialize(numeric_deserialize(bytea)) must result in a value which
- * matches the original bytea value.
+ * require sumX2.
*/
Datum
numeric_deserialize(PG_FUNCTION_ARGS)
{
- bytea *sstate = PG_GETARG_BYTEA_P(0);
+ bytea *sstate;
NumericAggState *result;
Datum temp;
StringInfoData buf;
if (!AggCheckCallContext(fcinfo, NULL))
elog(ERROR, "aggregate function called in non-aggregate context");
+ sstate = PG_GETARG_BYTEA_P(0);
+
/*
* Copy the bytea into a StringInfo so that we can "receive" it using the
* standard pq API.
/*
* numeric_poly_serialize
- * Serialize PolyNumAggState into bytea using the standard pq API for
- * aggregate functions which require sumX2.
- *
- * numeric_poly_deserialize(numeric_poly_serialize(state)) must result in a
- * state which matches the original input state.
+ * Serialize PolyNumAggState into bytea for aggregate functions which
+ * require sumX2.
*/
Datum
numeric_poly_serialize(PG_FUNCTION_ARGS)
/*
* numeric_poly_deserialize
- * Deserialize PolyNumAggState from bytea using the standard pq API for
- * aggregate functions which require sumX2.
- *
- * numeric_poly_serialize(numeric_poly_deserialize(bytea)) must result in a
- * state which matches the original input state.
+ * Deserialize PolyNumAggState from bytea for aggregate functions which
+ * require sumX2.
*/
Datum
numeric_poly_deserialize(PG_FUNCTION_ARGS)
{
- bytea *sstate = PG_GETARG_BYTEA_P(0);
+ bytea *sstate;
PolyNumAggState *result;
Datum sumX;
Datum sumX2;
if (!AggCheckCallContext(fcinfo, NULL))
elog(ERROR, "aggregate function called in non-aggregate context");
+ sstate = PG_GETARG_BYTEA_P(0);
+
/*
* Copy the bytea into a StringInfo so that we can "receive" it using the
* standard pq API.
/*
* int8_avg_serialize
* Serialize PolyNumAggState into bytea using the standard pq API.
- *
- * int8_avg_deserialize(int8_avg_serialize(state)) must result in a state which
- * matches the original input state.
*/
Datum
int8_avg_serialize(PG_FUNCTION_ARGS)
/*
* int8_avg_deserialize
* Deserialize bytea back into PolyNumAggState.
- *
- * int8_avg_serialize(int8_avg_deserialize(bytea)) must result in a value which
- * matches the original bytea value.
*/
Datum
int8_avg_deserialize(PG_FUNCTION_ARGS)
{
- bytea *sstate = PG_GETARG_BYTEA_P(0);
+ bytea *sstate;
PolyNumAggState *result;
StringInfoData buf;
Datum temp;
if (!AggCheckCallContext(fcinfo, NULL))
elog(ERROR, "aggregate function called in non-aggregate context");
+ sstate = PG_GETARG_BYTEA_P(0);
+
/*
* Copy the bytea into a StringInfo so that we can "receive" it using the
* standard pq API.
int i_aggsortop;
int i_hypothetical;
int i_aggtranstype;
- int i_aggserialtype;
int i_aggtransspace;
int i_aggmtranstype;
int i_aggmtransspace;
char *aggsortconvop;
bool hypothetical;
const char *aggtranstype;
- const char *aggserialtype;
const char *aggtransspace;
const char *aggmtranstype;
const char *aggmtransspace;
"aggminvtransfn, aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
"aggfinalextra, aggmfinalextra, "
"aggsortop::pg_catalog.regoperator, "
- "aggserialtype::pg_catalog.regtype, "
"(aggkind = 'h') AS hypothetical, "
"aggtransspace, agginitval, "
"aggmtransspace, aggminitval, "
"aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
"aggfinalextra, aggmfinalextra, "
"aggsortop::pg_catalog.regoperator, "
- "0 AS aggserialtype, "
"(aggkind = 'h') AS hypothetical, "
"aggtransspace, agginitval, "
"aggmtransspace, aggminitval, "
"0 AS aggmtranstype, false AS aggfinalextra, "
"false AS aggmfinalextra, "
"aggsortop::pg_catalog.regoperator, "
- "0 AS aggserialtype, "
"false AS hypothetical, "
"0 AS aggtransspace, agginitval, "
"0 AS aggmtransspace, NULL AS aggminitval, "
"0 AS aggmtranstype, false AS aggfinalextra, "
"false AS aggmfinalextra, "
"aggsortop::pg_catalog.regoperator, "
- "0 AS aggserialtype, "
"false AS hypothetical, "
"0 AS aggtransspace, agginitval, "
"0 AS aggmtransspace, NULL AS aggminitval, "
"'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
"0 AS aggmtranstype, false AS aggfinalextra, "
"false AS aggmfinalextra, 0 AS aggsortop, "
- "0 AS aggserialtype, "
"false AS hypothetical, "
"0 AS aggtransspace, agginitval, "
"0 AS aggmtransspace, NULL AS aggminitval, "
"'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
"0 AS aggmtranstype, false AS aggfinalextra, "
"false AS aggmfinalextra, 0 AS aggsortop, "
- "0 AS aggserialtype, "
"false AS hypothetical, "
"0 AS aggtransspace, agginitval, "
"0 AS aggmtransspace, NULL AS aggminitval, "
"'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
"0 AS aggmtranstype, false AS aggfinalextra, "
"false AS aggmfinalextra, 0 AS aggsortop, "
- "0 AS aggserialtype, "
"false AS hypothetical, "
"0 AS aggtransspace, agginitval1 AS agginitval, "
"0 AS aggmtransspace, NULL AS aggminitval, "
i_aggfinalextra = PQfnumber(res, "aggfinalextra");
i_aggmfinalextra = PQfnumber(res, "aggmfinalextra");
i_aggsortop = PQfnumber(res, "aggsortop");
- i_aggserialtype = PQfnumber(res, "aggserialtype");
i_hypothetical = PQfnumber(res, "hypothetical");
i_aggtranstype = PQfnumber(res, "aggtranstype");
i_aggtransspace = PQfnumber(res, "aggtransspace");
aggsortop = PQgetvalue(res, 0, i_aggsortop);
hypothetical = (PQgetvalue(res, 0, i_hypothetical)[0] == 't');
aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
- aggserialtype = PQgetvalue(res, 0, i_aggserialtype);
aggtransspace = PQgetvalue(res, 0, i_aggtransspace);
aggmtranstype = PQgetvalue(res, 0, i_aggmtranstype);
aggmtransspace = PQgetvalue(res, 0, i_aggmtransspace);
}
if (strcmp(aggcombinefn, "-") != 0)
- {
appendPQExpBuffer(details, ",\n COMBINEFUNC = %s", aggcombinefn);
- }
- /*
- * CREATE AGGREGATE should ensure we either have all of these, or none of
- * them.
- */
if (strcmp(aggserialfn, "-") != 0)
- {
appendPQExpBuffer(details, ",\n SERIALFUNC = %s", aggserialfn);
+
+ if (strcmp(aggdeserialfn, "-") != 0)
appendPQExpBuffer(details, ",\n DESERIALFUNC = %s", aggdeserialfn);
- appendPQExpBuffer(details, ",\n SERIALTYPE = %s", aggserialtype);
- }
if (strcmp(aggmtransfn, "-") != 0)
{
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201606171
+#define CATALOG_VERSION_NO 201606221
#endif
* aggtransfn transition function
* aggfinalfn final function (0 if none)
* aggcombinefn combine function (0 if none)
- * aggserialfn function to convert transtype to serialtype (0 if none)
- * aggdeserialfn function to convert serialtype to transtype (0 if none)
+ * aggserialfn function to convert transtype to bytea (0 if none)
+ * aggdeserialfn function to convert bytea to transtype (0 if none)
* aggmtransfn forward function for moving-aggregate mode (0 if none)
* aggminvtransfn inverse function for moving-aggregate mode (0 if none)
* aggmfinalfn final function for moving-aggregate mode (0 if none)
* aggtranstype type of aggregate's transition (state) data
* aggtransspace estimated size of state data (0 for default estimate)
* aggmtranstype type of moving-aggregate state data (0 if none)
- * aggserialtype datatype to serialize state to. (0 if none)
* aggmtransspace estimated size of moving-agg state (0 for default est)
* agginitval initial value for transition state (can be NULL)
* aggminitval initial value for moving-agg state (can be NULL)
bool aggmfinalextra;
Oid aggsortop;
Oid aggtranstype;
- Oid aggserialtype;
int32 aggtransspace;
Oid aggmtranstype;
int32 aggmtransspace;
* ----------------
*/
-#define Natts_pg_aggregate 21
+#define Natts_pg_aggregate 20
#define Anum_pg_aggregate_aggfnoid 1
#define Anum_pg_aggregate_aggkind 2
#define Anum_pg_aggregate_aggnumdirectargs 3
#define Anum_pg_aggregate_aggmfinalextra 13
#define Anum_pg_aggregate_aggsortop 14
#define Anum_pg_aggregate_aggtranstype 15
-#define Anum_pg_aggregate_aggserialtype 16
-#define Anum_pg_aggregate_aggtransspace 17
-#define Anum_pg_aggregate_aggmtranstype 18
-#define Anum_pg_aggregate_aggmtransspace 19
-#define Anum_pg_aggregate_agginitval 20
-#define Anum_pg_aggregate_aggminitval 21
+#define Anum_pg_aggregate_aggtransspace 16
+#define Anum_pg_aggregate_aggmtranstype 17
+#define Anum_pg_aggregate_aggmtransspace 18
+#define Anum_pg_aggregate_agginitval 19
+#define Anum_pg_aggregate_aggminitval 20
/*
* Symbolic values for aggkind column. We distinguish normal aggregates
*/
/* avg */
-DATA(insert ( 2100 n 0 int8_avg_accum numeric_poly_avg int8_avg_combine int8_avg_serialize int8_avg_deserialize int8_avg_accum int8_avg_accum_inv numeric_poly_avg f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2101 n 0 int4_avg_accum int8_avg int4_avg_combine - - int4_avg_accum int4_avg_accum_inv int8_avg f f 0 1016 0 0 1016 0 "{0,0}" "{0,0}" ));
-DATA(insert ( 2102 n 0 int2_avg_accum int8_avg int4_avg_combine - - int2_avg_accum int2_avg_accum_inv int8_avg f f 0 1016 0 0 1016 0 "{0,0}" "{0,0}" ));
-DATA(insert ( 2103 n 0 numeric_avg_accum numeric_avg numeric_avg_combine numeric_avg_serialize numeric_avg_deserialize numeric_avg_accum numeric_accum_inv numeric_avg f f 0 2281 17 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2104 n 0 float4_accum float8_avg float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2105 n 0 float8_accum float8_avg float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2106 n 0 interval_accum interval_avg interval_combine - - interval_accum interval_accum_inv interval_avg f f 0 1187 0 0 1187 0 "{0 second,0 second}" "{0 second,0 second}" ));
+DATA(insert ( 2100 n 0 int8_avg_accum numeric_poly_avg int8_avg_combine int8_avg_serialize int8_avg_deserialize int8_avg_accum int8_avg_accum_inv numeric_poly_avg f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2101 n 0 int4_avg_accum int8_avg int4_avg_combine - - int4_avg_accum int4_avg_accum_inv int8_avg f f 0 1016 0 1016 0 "{0,0}" "{0,0}" ));
+DATA(insert ( 2102 n 0 int2_avg_accum int8_avg int4_avg_combine - - int2_avg_accum int2_avg_accum_inv int8_avg f f 0 1016 0 1016 0 "{0,0}" "{0,0}" ));
+DATA(insert ( 2103 n 0 numeric_avg_accum numeric_avg numeric_avg_combine numeric_avg_serialize numeric_avg_deserialize numeric_avg_accum numeric_accum_inv numeric_avg f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2104 n 0 float4_accum float8_avg float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2105 n 0 float8_accum float8_avg float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2106 n 0 interval_accum interval_avg interval_combine - - interval_accum interval_accum_inv interval_avg f f 0 1187 0 1187 0 "{0 second,0 second}" "{0 second,0 second}" ));
/* sum */
-DATA(insert ( 2107 n 0 int8_avg_accum numeric_poly_sum int8_avg_combine int8_avg_serialize int8_avg_deserialize int8_avg_accum int8_avg_accum_inv numeric_poly_sum f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2108 n 0 int4_sum - int8pl - - int4_avg_accum int4_avg_accum_inv int2int4_sum f f 0 20 0 0 1016 0 _null_ "{0,0}" ));
-DATA(insert ( 2109 n 0 int2_sum - int8pl - - int2_avg_accum int2_avg_accum_inv int2int4_sum f f 0 20 0 0 1016 0 _null_ "{0,0}" ));
-DATA(insert ( 2110 n 0 float4pl - float4pl - - - - - f f 0 700 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2111 n 0 float8pl - float8pl - - - - - f f 0 701 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2112 n 0 cash_pl - cash_pl - - cash_pl cash_mi - f f 0 790 0 0 790 0 _null_ _null_ ));
-DATA(insert ( 2113 n 0 interval_pl - interval_pl - - interval_pl interval_mi - f f 0 1186 0 0 1186 0 _null_ _null_ ));
-DATA(insert ( 2114 n 0 numeric_avg_accum numeric_sum numeric_avg_combine numeric_avg_serialize numeric_avg_deserialize numeric_avg_accum numeric_accum_inv numeric_sum f f 0 2281 17 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2107 n 0 int8_avg_accum numeric_poly_sum int8_avg_combine int8_avg_serialize int8_avg_deserialize int8_avg_accum int8_avg_accum_inv numeric_poly_sum f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2108 n 0 int4_sum - int8pl - - int4_avg_accum int4_avg_accum_inv int2int4_sum f f 0 20 0 1016 0 _null_ "{0,0}" ));
+DATA(insert ( 2109 n 0 int2_sum - int8pl - - int2_avg_accum int2_avg_accum_inv int2int4_sum f f 0 20 0 1016 0 _null_ "{0,0}" ));
+DATA(insert ( 2110 n 0 float4pl - float4pl - - - - - f f 0 700 0 0 0 _null_ _null_ ));
+DATA(insert ( 2111 n 0 float8pl - float8pl - - - - - f f 0 701 0 0 0 _null_ _null_ ));
+DATA(insert ( 2112 n 0 cash_pl - cash_pl - - cash_pl cash_mi - f f 0 790 0 790 0 _null_ _null_ ));
+DATA(insert ( 2113 n 0 interval_pl - interval_pl - - interval_pl interval_mi - f f 0 1186 0 1186 0 _null_ _null_ ));
+DATA(insert ( 2114 n 0 numeric_avg_accum numeric_sum numeric_avg_combine numeric_avg_serialize numeric_avg_deserialize numeric_avg_accum numeric_accum_inv numeric_sum f f 0 2281 128 2281 128 _null_ _null_ ));
/* max */
-DATA(insert ( 2115 n 0 int8larger - int8larger - - - - - f f 413 20 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2116 n 0 int4larger - int4larger - - - - - f f 521 23 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2117 n 0 int2larger - int2larger - - - - - f f 520 21 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2118 n 0 oidlarger - oidlarger - - - - - f f 610 26 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2119 n 0 float4larger - float4larger - - - - - f f 623 700 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2120 n 0 float8larger - float8larger - - - - - f f 674 701 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2121 n 0 int4larger - int4larger - - - - - f f 563 702 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2122 n 0 date_larger - date_larger - - - - - f f 1097 1082 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2123 n 0 time_larger - time_larger - - - - - f f 1112 1083 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2124 n 0 timetz_larger - timetz_larger - - - - - f f 1554 1266 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2125 n 0 cashlarger - cashlarger - - - - - f f 903 790 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2126 n 0 timestamp_larger - timestamp_larger - - - - - f f 2064 1114 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2127 n 0 timestamptz_larger - timestamptz_larger - - - - - f f 1324 1184 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2128 n 0 interval_larger - interval_larger - - - - - f f 1334 1186 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2129 n 0 text_larger - text_larger - - - - - f f 666 25 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2130 n 0 numeric_larger - numeric_larger - - - - - f f 1756 1700 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2050 n 0 array_larger - array_larger - - - - - f f 1073 2277 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2244 n 0 bpchar_larger - bpchar_larger - - - - - f f 1060 1042 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2797 n 0 tidlarger - tidlarger - - - - - f f 2800 27 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3526 n 0 enum_larger - enum_larger - - - - - f f 3519 3500 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3564 n 0 network_larger - network_larger - - - - - f f 1205 869 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 2115 n 0 int8larger - int8larger - - - - - f f 413 20 0 0 0 _null_ _null_ ));
+DATA(insert ( 2116 n 0 int4larger - int4larger - - - - - f f 521 23 0 0 0 _null_ _null_ ));
+DATA(insert ( 2117 n 0 int2larger - int2larger - - - - - f f 520 21 0 0 0 _null_ _null_ ));
+DATA(insert ( 2118 n 0 oidlarger - oidlarger - - - - - f f 610 26 0 0 0 _null_ _null_ ));
+DATA(insert ( 2119 n 0 float4larger - float4larger - - - - - f f 623 700 0 0 0 _null_ _null_ ));
+DATA(insert ( 2120 n 0 float8larger - float8larger - - - - - f f 674 701 0 0 0 _null_ _null_ ));
+DATA(insert ( 2121 n 0 int4larger - int4larger - - - - - f f 563 702 0 0 0 _null_ _null_ ));
+DATA(insert ( 2122 n 0 date_larger - date_larger - - - - - f f 1097 1082 0 0 0 _null_ _null_ ));
+DATA(insert ( 2123 n 0 time_larger - time_larger - - - - - f f 1112 1083 0 0 0 _null_ _null_ ));
+DATA(insert ( 2124 n 0 timetz_larger - timetz_larger - - - - - f f 1554 1266 0 0 0 _null_ _null_ ));
+DATA(insert ( 2125 n 0 cashlarger - cashlarger - - - - - f f 903 790 0 0 0 _null_ _null_ ));
+DATA(insert ( 2126 n 0 timestamp_larger - timestamp_larger - - - - - f f 2064 1114 0 0 0 _null_ _null_ ));
+DATA(insert ( 2127 n 0 timestamptz_larger - timestamptz_larger - - - - - f f 1324 1184 0 0 0 _null_ _null_ ));
+DATA(insert ( 2128 n 0 interval_larger - interval_larger - - - - - f f 1334 1186 0 0 0 _null_ _null_ ));
+DATA(insert ( 2129 n 0 text_larger - text_larger - - - - - f f 666 25 0 0 0 _null_ _null_ ));
+DATA(insert ( 2130 n 0 numeric_larger - numeric_larger - - - - - f f 1756 1700 0 0 0 _null_ _null_ ));
+DATA(insert ( 2050 n 0 array_larger - array_larger - - - - - f f 1073 2277 0 0 0 _null_ _null_ ));
+DATA(insert ( 2244 n 0 bpchar_larger - bpchar_larger - - - - - f f 1060 1042 0 0 0 _null_ _null_ ));
+DATA(insert ( 2797 n 0 tidlarger - tidlarger - - - - - f f 2800 27 0 0 0 _null_ _null_ ));
+DATA(insert ( 3526 n 0 enum_larger - enum_larger - - - - - f f 3519 3500 0 0 0 _null_ _null_ ));
+DATA(insert ( 3564 n 0 network_larger - network_larger - - - - - f f 1205 869 0 0 0 _null_ _null_ ));
/* min */
-DATA(insert ( 2131 n 0 int8smaller - int8smaller - - - - - f f 412 20 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2132 n 0 int4smaller - int4smaller - - - - - f f 97 23 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2133 n 0 int2smaller - int2smaller - - - - - f f 95 21 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2134 n 0 oidsmaller - oidsmaller - - - - - f f 609 26 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2135 n 0 float4smaller - float4smaller - - - - - f f 622 700 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2136 n 0 float8smaller - float8smaller - - - - - f f 672 701 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2137 n 0 int4smaller - int4smaller - - - - - f f 562 702 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2138 n 0 date_smaller - date_smaller - - - - - f f 1095 1082 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2139 n 0 time_smaller - time_smaller - - - - - f f 1110 1083 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2140 n 0 timetz_smaller - timetz_smaller - - - - - f f 1552 1266 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2141 n 0 cashsmaller - cashsmaller - - - - - f f 902 790 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2142 n 0 timestamp_smaller - timestamp_smaller - - - - - f f 2062 1114 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2143 n 0 timestamptz_smaller - timestamptz_smaller - - - - - f f 1322 1184 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2144 n 0 interval_smaller - interval_smaller - - - - - f f 1332 1186 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2145 n 0 text_smaller - text_smaller - - - - - f f 664 25 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2146 n 0 numeric_smaller - numeric_smaller - - - - - f f 1754 1700 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2051 n 0 array_smaller - array_smaller - - - - - f f 1072 2277 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2245 n 0 bpchar_smaller - bpchar_smaller - - - - - f f 1058 1042 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2798 n 0 tidsmaller - tidsmaller - - - - - f f 2799 27 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3527 n 0 enum_smaller - enum_smaller - - - - - f f 3518 3500 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3565 n 0 network_smaller - network_smaller - - - - - f f 1203 869 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 2131 n 0 int8smaller - int8smaller - - - - - f f 412 20 0 0 0 _null_ _null_ ));
+DATA(insert ( 2132 n 0 int4smaller - int4smaller - - - - - f f 97 23 0 0 0 _null_ _null_ ));
+DATA(insert ( 2133 n 0 int2smaller - int2smaller - - - - - f f 95 21 0 0 0 _null_ _null_ ));
+DATA(insert ( 2134 n 0 oidsmaller - oidsmaller - - - - - f f 609 26 0 0 0 _null_ _null_ ));
+DATA(insert ( 2135 n 0 float4smaller - float4smaller - - - - - f f 622 700 0 0 0 _null_ _null_ ));
+DATA(insert ( 2136 n 0 float8smaller - float8smaller - - - - - f f 672 701 0 0 0 _null_ _null_ ));
+DATA(insert ( 2137 n 0 int4smaller - int4smaller - - - - - f f 562 702 0 0 0 _null_ _null_ ));
+DATA(insert ( 2138 n 0 date_smaller - date_smaller - - - - - f f 1095 1082 0 0 0 _null_ _null_ ));
+DATA(insert ( 2139 n 0 time_smaller - time_smaller - - - - - f f 1110 1083 0 0 0 _null_ _null_ ));
+DATA(insert ( 2140 n 0 timetz_smaller - timetz_smaller - - - - - f f 1552 1266 0 0 0 _null_ _null_ ));
+DATA(insert ( 2141 n 0 cashsmaller - cashsmaller - - - - - f f 902 790 0 0 0 _null_ _null_ ));
+DATA(insert ( 2142 n 0 timestamp_smaller - timestamp_smaller - - - - - f f 2062 1114 0 0 0 _null_ _null_ ));
+DATA(insert ( 2143 n 0 timestamptz_smaller - timestamptz_smaller - - - - - f f 1322 1184 0 0 0 _null_ _null_ ));
+DATA(insert ( 2144 n 0 interval_smaller - interval_smaller - - - - - f f 1332 1186 0 0 0 _null_ _null_ ));
+DATA(insert ( 2145 n 0 text_smaller - text_smaller - - - - - f f 664 25 0 0 0 _null_ _null_ ));
+DATA(insert ( 2146 n 0 numeric_smaller - numeric_smaller - - - - - f f 1754 1700 0 0 0 _null_ _null_ ));
+DATA(insert ( 2051 n 0 array_smaller - array_smaller - - - - - f f 1072 2277 0 0 0 _null_ _null_ ));
+DATA(insert ( 2245 n 0 bpchar_smaller - bpchar_smaller - - - - - f f 1058 1042 0 0 0 _null_ _null_ ));
+DATA(insert ( 2798 n 0 tidsmaller - tidsmaller - - - - - f f 2799 27 0 0 0 _null_ _null_ ));
+DATA(insert ( 3527 n 0 enum_smaller - enum_smaller - - - - - f f 3518 3500 0 0 0 _null_ _null_ ));
+DATA(insert ( 3565 n 0 network_smaller - network_smaller - - - - - f f 1203 869 0 0 0 _null_ _null_ ));
/* count */
-DATA(insert ( 2147 n 0 int8inc_any - int8pl - - int8inc_any int8dec_any - f f 0 20 0 0 20 0 "0" "0" ));
-DATA(insert ( 2803 n 0 int8inc - int8pl - - int8inc int8dec - f f 0 20 0 0 20 0 "0" "0" ));
+DATA(insert ( 2147 n 0 int8inc_any - int8pl - - int8inc_any int8dec_any - f f 0 20 0 20 0 "0" "0" ));
+DATA(insert ( 2803 n 0 int8inc - int8pl - - int8inc int8dec - f f 0 20 0 20 0 "0" "0" ));
/* var_pop */
-DATA(insert ( 2718 n 0 int8_accum numeric_var_pop numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_var_pop f f 0 2281 17 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2719 n 0 int4_accum numeric_poly_var_pop numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_var_pop f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2720 n 0 int2_accum numeric_poly_var_pop numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_var_pop f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2721 n 0 float4_accum float8_var_pop float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2722 n 0 float8_accum float8_var_pop float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2723 n 0 numeric_accum numeric_var_pop numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_var_pop f f 0 2281 17 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2718 n 0 int8_accum numeric_var_pop numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_var_pop f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2719 n 0 int4_accum numeric_poly_var_pop numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_var_pop f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2720 n 0 int2_accum numeric_poly_var_pop numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_var_pop f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2721 n 0 float4_accum float8_var_pop float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2722 n 0 float8_accum float8_var_pop float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2723 n 0 numeric_accum numeric_var_pop numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_var_pop f f 0 2281 128 2281 128 _null_ _null_ ));
/* var_samp */
-DATA(insert ( 2641 n 0 int8_accum numeric_var_samp numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_var_samp f f 0 2281 17 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2642 n 0 int4_accum numeric_poly_var_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_var_samp f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2643 n 0 int2_accum numeric_poly_var_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_var_samp f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2644 n 0 float4_accum float8_var_samp float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2645 n 0 float8_accum float8_var_samp float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2646 n 0 numeric_accum numeric_var_samp numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 17 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2641 n 0 int8_accum numeric_var_samp numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2642 n 0 int4_accum numeric_poly_var_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_var_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2643 n 0 int2_accum numeric_poly_var_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_var_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2644 n 0 float4_accum float8_var_samp float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2645 n 0 float8_accum float8_var_samp float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2646 n 0 numeric_accum numeric_var_samp numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
/* variance: historical Postgres syntax for var_samp */
-DATA(insert ( 2148 n 0 int8_accum numeric_var_samp numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_var_samp f f 0 2281 17 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2149 n 0 int4_accum numeric_poly_var_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_var_samp f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2150 n 0 int2_accum numeric_poly_var_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_var_samp f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2151 n 0 float4_accum float8_var_samp float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2152 n 0 float8_accum float8_var_samp float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2153 n 0 numeric_accum numeric_var_samp numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 17 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2148 n 0 int8_accum numeric_var_samp numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2149 n 0 int4_accum numeric_poly_var_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_var_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2150 n 0 int2_accum numeric_poly_var_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_var_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2151 n 0 float4_accum float8_var_samp float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2152 n 0 float8_accum float8_var_samp float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2153 n 0 numeric_accum numeric_var_samp numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
/* stddev_pop */
-DATA(insert ( 2724 n 0 int8_accum numeric_stddev_pop numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_stddev_pop f f 0 2281 17 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2725 n 0 int4_accum numeric_poly_stddev_pop numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_stddev_pop f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2726 n 0 int2_accum numeric_poly_stddev_pop numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_stddev_pop f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2727 n 0 float4_accum float8_stddev_pop float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2728 n 0 float8_accum float8_stddev_pop float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2729 n 0 numeric_accum numeric_stddev_pop numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_stddev_pop f f 0 2281 17 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2724 n 0 int8_accum numeric_stddev_pop numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_stddev_pop f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2725 n 0 int4_accum numeric_poly_stddev_pop numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_stddev_pop f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2726 n 0 int2_accum numeric_poly_stddev_pop numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_stddev_pop f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2727 n 0 float4_accum float8_stddev_pop float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2728 n 0 float8_accum float8_stddev_pop float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2729 n 0 numeric_accum numeric_stddev_pop numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_stddev_pop f f 0 2281 128 2281 128 _null_ _null_ ));
/* stddev_samp */
-DATA(insert ( 2712 n 0 int8_accum numeric_stddev_samp numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 17 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2713 n 0 int4_accum numeric_poly_stddev_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_stddev_samp f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2714 n 0 int2_accum numeric_poly_stddev_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_stddev_samp f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2715 n 0 float4_accum float8_stddev_samp float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2716 n 0 float8_accum float8_stddev_samp float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2717 n 0 numeric_accum numeric_stddev_samp numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 17 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2712 n 0 int8_accum numeric_stddev_samp numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2713 n 0 int4_accum numeric_poly_stddev_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_stddev_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2714 n 0 int2_accum numeric_poly_stddev_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_stddev_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2715 n 0 float4_accum float8_stddev_samp float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2716 n 0 float8_accum float8_stddev_samp float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2717 n 0 numeric_accum numeric_stddev_samp numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
/* stddev: historical Postgres syntax for stddev_samp */
-DATA(insert ( 2154 n 0 int8_accum numeric_stddev_samp numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 17 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2155 n 0 int4_accum numeric_poly_stddev_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_stddev_samp f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2156 n 0 int2_accum numeric_poly_stddev_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_stddev_samp f f 0 2281 17 48 2281 48 _null_ _null_ ));
-DATA(insert ( 2157 n 0 float4_accum float8_stddev_samp float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2158 n 0 float8_accum float8_stddev_samp float8_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2159 n 0 numeric_accum numeric_stddev_samp numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 17 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2154 n 0 int8_accum numeric_stddev_samp numeric_combine numeric_serialize numeric_deserialize int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2155 n 0 int4_accum numeric_poly_stddev_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int4_accum int4_accum_inv numeric_poly_stddev_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2156 n 0 int2_accum numeric_poly_stddev_samp numeric_poly_combine numeric_poly_serialize numeric_poly_deserialize int2_accum int2_accum_inv numeric_poly_stddev_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2157 n 0 float4_accum float8_stddev_samp float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2158 n 0 float8_accum float8_stddev_samp float8_combine - - - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2159 n 0 numeric_accum numeric_stddev_samp numeric_combine numeric_serialize numeric_deserialize numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
/* SQL2003 binary regression aggregates */
-DATA(insert ( 2818 n 0 int8inc_float8_float8 - int8pl - - - - - f f 0 20 0 0 0 0 "0" _null_ ));
-DATA(insert ( 2819 n 0 float8_regr_accum float8_regr_sxx float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2820 n 0 float8_regr_accum float8_regr_syy float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2821 n 0 float8_regr_accum float8_regr_sxy float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2822 n 0 float8_regr_accum float8_regr_avgx float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2823 n 0 float8_regr_accum float8_regr_avgy float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2824 n 0 float8_regr_accum float8_regr_r2 float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2825 n 0 float8_regr_accum float8_regr_slope float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2826 n 0 float8_regr_accum float8_regr_intercept float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2827 n 0 float8_regr_accum float8_covar_pop float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2828 n 0 float8_regr_accum float8_covar_samp float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
-DATA(insert ( 2829 n 0 float8_regr_accum float8_corr float8_regr_combine - - - - - f f 0 1022 0 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2818 n 0 int8inc_float8_float8 - int8pl - - - - - f f 0 20 0 0 0 "0" _null_ ));
+DATA(insert ( 2819 n 0 float8_regr_accum float8_regr_sxx float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2820 n 0 float8_regr_accum float8_regr_syy float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2821 n 0 float8_regr_accum float8_regr_sxy float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2822 n 0 float8_regr_accum float8_regr_avgx float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2823 n 0 float8_regr_accum float8_regr_avgy float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2824 n 0 float8_regr_accum float8_regr_r2 float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2825 n 0 float8_regr_accum float8_regr_slope float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2826 n 0 float8_regr_accum float8_regr_intercept float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2827 n 0 float8_regr_accum float8_covar_pop float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2828 n 0 float8_regr_accum float8_covar_samp float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
+DATA(insert ( 2829 n 0 float8_regr_accum float8_corr float8_regr_combine - - - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
/* boolean-and and boolean-or */
-DATA(insert ( 2517 n 0 booland_statefunc - booland_statefunc - - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 0 2281 16 _null_ _null_ ));
-DATA(insert ( 2518 n 0 boolor_statefunc - boolor_statefunc - - bool_accum bool_accum_inv bool_anytrue f f 59 16 0 0 2281 16 _null_ _null_ ));
-DATA(insert ( 2519 n 0 booland_statefunc - booland_statefunc - - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 0 2281 16 _null_ _null_ ));
+DATA(insert ( 2517 n 0 booland_statefunc - booland_statefunc - - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 2281 16 _null_ _null_ ));
+DATA(insert ( 2518 n 0 boolor_statefunc - boolor_statefunc - - bool_accum bool_accum_inv bool_anytrue f f 59 16 0 2281 16 _null_ _null_ ));
+DATA(insert ( 2519 n 0 booland_statefunc - booland_statefunc - - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 2281 16 _null_ _null_ ));
/* bitwise integer */
-DATA(insert ( 2236 n 0 int2and - int2and - - - - - f f 0 21 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2237 n 0 int2or - int2or - - - - - f f 0 21 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2238 n 0 int4and - int4and - - - - - f f 0 23 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2239 n 0 int4or - int4or - - - - - f f 0 23 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2240 n 0 int8and - int8and - - - - - f f 0 20 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2241 n 0 int8or - int8or - - - - - f f 0 20 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2242 n 0 bitand - bitand - - - - - f f 0 1560 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 2243 n 0 bitor - bitor - - - - - f f 0 1560 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 2236 n 0 int2and - int2and - - - - - f f 0 21 0 0 0 _null_ _null_ ));
+DATA(insert ( 2237 n 0 int2or - int2or - - - - - f f 0 21 0 0 0 _null_ _null_ ));
+DATA(insert ( 2238 n 0 int4and - int4and - - - - - f f 0 23 0 0 0 _null_ _null_ ));
+DATA(insert ( 2239 n 0 int4or - int4or - - - - - f f 0 23 0 0 0 _null_ _null_ ));
+DATA(insert ( 2240 n 0 int8and - int8and - - - - - f f 0 20 0 0 0 _null_ _null_ ));
+DATA(insert ( 2241 n 0 int8or - int8or - - - - - f f 0 20 0 0 0 _null_ _null_ ));
+DATA(insert ( 2242 n 0 bitand - bitand - - - - - f f 0 1560 0 0 0 _null_ _null_ ));
+DATA(insert ( 2243 n 0 bitor - bitor - - - - - f f 0 1560 0 0 0 _null_ _null_ ));
/* xml */
-DATA(insert ( 2901 n 0 xmlconcat2 - - - - - - - f f 0 142 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 2901 n 0 xmlconcat2 - - - - - - - f f 0 142 0 0 0 _null_ _null_ ));
/* array */
-DATA(insert ( 2335 n 0 array_agg_transfn array_agg_finalfn - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 4053 n 0 array_agg_array_transfn array_agg_array_finalfn - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 2335 n 0 array_agg_transfn array_agg_finalfn - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 4053 n 0 array_agg_array_transfn array_agg_array_finalfn - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
/* text */
-DATA(insert ( 3538 n 0 string_agg_transfn string_agg_finalfn - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 3538 n 0 string_agg_transfn string_agg_finalfn - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
/* bytea */
-DATA(insert ( 3545 n 0 bytea_string_agg_transfn bytea_string_agg_finalfn - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 3545 n 0 bytea_string_agg_transfn bytea_string_agg_finalfn - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
/* json */
-DATA(insert ( 3175 n 0 json_agg_transfn json_agg_finalfn - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3197 n 0 json_object_agg_transfn json_object_agg_finalfn - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 3175 n 0 json_agg_transfn json_agg_finalfn - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3197 n 0 json_object_agg_transfn json_object_agg_finalfn - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
/* jsonb */
-DATA(insert ( 3267 n 0 jsonb_agg_transfn jsonb_agg_finalfn - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3270 n 0 jsonb_object_agg_transfn jsonb_object_agg_finalfn - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 3267 n 0 jsonb_agg_transfn jsonb_agg_finalfn - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3270 n 0 jsonb_object_agg_transfn jsonb_object_agg_finalfn - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
/* ordered-set and hypothetical-set aggregates */
-DATA(insert ( 3972 o 1 ordered_set_transition percentile_disc_final - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3974 o 1 ordered_set_transition percentile_cont_float8_final - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3976 o 1 ordered_set_transition percentile_cont_interval_final - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3978 o 1 ordered_set_transition percentile_disc_multi_final - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3980 o 1 ordered_set_transition percentile_cont_float8_multi_final - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3982 o 1 ordered_set_transition percentile_cont_interval_multi_final - - - - - - f f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3984 o 0 ordered_set_transition mode_final - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3986 h 1 ordered_set_transition_multi rank_final - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3988 h 1 ordered_set_transition_multi percent_rank_final - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3990 h 1 ordered_set_transition_multi cume_dist_final - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
-DATA(insert ( 3992 h 1 ordered_set_transition_multi dense_rank_final - - - - - - t f 0 2281 0 0 0 0 _null_ _null_ ));
+DATA(insert ( 3972 o 1 ordered_set_transition percentile_disc_final - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3974 o 1 ordered_set_transition percentile_cont_float8_final - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3976 o 1 ordered_set_transition percentile_cont_interval_final - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3978 o 1 ordered_set_transition percentile_disc_multi_final - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3980 o 1 ordered_set_transition percentile_cont_float8_multi_final - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3982 o 1 ordered_set_transition percentile_cont_interval_multi_final - - - - - - f f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3984 o 0 ordered_set_transition mode_final - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3986 h 1 ordered_set_transition_multi rank_final - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3988 h 1 ordered_set_transition_multi percent_rank_final - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3990 h 1 ordered_set_transition_multi cume_dist_final - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
+DATA(insert ( 3992 h 1 ordered_set_transition_multi dense_rank_final - - - - - - t f 0 2281 0 0 0 _null_ _null_ ));
/*
bool mfinalfnExtraArgs,
List *aggsortopName,
Oid aggTransType,
- Oid aggSerialType,
int32 aggTransSpace,
Oid aggmTransType,
int32 aggmTransSpace,
DESCR("aggregate combine function");
DATA(insert OID = 2740 ( numeric_avg_serialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "2281" _null_ _null_ _null_ _null_ _null_ numeric_avg_serialize _null_ _null_ _null_ ));
DESCR("aggregate serial function");
-DATA(insert OID = 2741 ( numeric_avg_deserialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2281 "17" _null_ _null_ _null_ _null_ _null_ numeric_avg_deserialize _null_ _null_ _null_ ));
+DATA(insert OID = 2741 ( numeric_avg_deserialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 2281 "17 2281" _null_ _null_ _null_ _null_ _null_ numeric_avg_deserialize _null_ _null_ _null_ ));
DESCR("aggregate deserial function");
DATA(insert OID = 3335 ( numeric_serialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "2281" _null_ _null_ _null_ _null_ _null_ numeric_serialize _null_ _null_ _null_ ));
DESCR("aggregate serial function");
-DATA(insert OID = 3336 ( numeric_deserialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2281 "17" _null_ _null_ _null_ _null_ _null_ numeric_deserialize _null_ _null_ _null_ ));
+DATA(insert OID = 3336 ( numeric_deserialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 2281 "17 2281" _null_ _null_ _null_ _null_ _null_ numeric_deserialize _null_ _null_ _null_ ));
DESCR("aggregate deserial function");
DATA(insert OID = 3548 ( numeric_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f f f i s 2 0 2281 "2281 1700" _null_ _null_ _null_ _null_ _null_ numeric_accum_inv _null_ _null_ _null_ ));
DESCR("aggregate transition function");
DESCR("aggregate combine function");
DATA(insert OID = 3339 ( numeric_poly_serialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "2281" _null_ _null_ _null_ _null_ _null_ numeric_poly_serialize _null_ _null_ _null_ ));
DESCR("aggregate serial function");
-DATA(insert OID = 3340 ( numeric_poly_deserialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2281 "17" _null_ _null_ _null_ _null_ _null_ numeric_poly_deserialize _null_ _null_ _null_ ));
+DATA(insert OID = 3340 ( numeric_poly_deserialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 2281 "17 2281" _null_ _null_ _null_ _null_ _null_ numeric_poly_deserialize _null_ _null_ _null_ ));
DESCR("aggregate deserial function");
DATA(insert OID = 2746 ( int8_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i s 2 0 2281 "2281 20" _null_ _null_ _null_ _null_ _null_ int8_avg_accum _null_ _null_ _null_ ));
DESCR("aggregate transition function");
DESCR("aggregate combine function");
DATA(insert OID = 2786 ( int8_avg_serialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "2281" _null_ _null_ _null_ _null_ _null_ int8_avg_serialize _null_ _null_ _null_ ));
DESCR("aggregate serial function");
-DATA(insert OID = 2787 ( int8_avg_deserialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2281 "17" _null_ _null_ _null_ _null_ _null_ int8_avg_deserialize _null_ _null_ _null_ ));
+DATA(insert OID = 2787 ( int8_avg_deserialize PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 2281 "17 2281" _null_ _null_ _null_ _null_ _null_ int8_avg_deserialize _null_ _null_ _null_ ));
DESCR("aggregate deserial function");
-DATA(insert OID = 3324 ( int4_avg_combine PGNSP PGUID 12 1 0 0 0 f f f f f f i s 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ _null_ int4_avg_combine _null_ _null_ _null_ ));
+DATA(insert OID = 3324 ( int4_avg_combine PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 1016 "1016 1016" _null_ _null_ _null_ _null_ _null_ int4_avg_combine _null_ _null_ _null_ ));
DESCR("aggregate combine function");
DATA(insert OID = 3178 ( numeric_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i s 1 0 1700 "2281" _null_ _null_ _null_ _null_ _null_ numeric_sum _null_ _null_ _null_ ));
DESCR("aggregate final function");
Oid combinefn_oid,
Expr **combinefnexpr);
-extern void build_aggregate_serialfn_expr(Oid agg_state_type,
- Oid agg_serial_type,
- Oid agg_input_collation,
- Oid serialfn_oid,
+extern void build_aggregate_serialfn_expr(Oid serialfn_oid,
Expr **serialfnexpr);
+extern void build_aggregate_deserialfn_expr(Oid deserialfn_oid,
+ Expr **deserialfnexpr);
+
extern void build_aggregate_finalfn_expr(Oid *agg_input_types,
int num_finalfn_inputs,
Oid agg_state_type,
minvfunc = float8mi
);
-- aggregate combine and serialization functions
--- Ensure stype and serialtype can't be the same
+-- can't specify just one of serialfunc and deserialfunc
CREATE AGGREGATE myavg (numeric)
(
stype = internal,
sfunc = numeric_avg_accum,
- serialtype = internal
-);
-ERROR: aggregate serialization data type cannot be internal
--- if serialtype is specified we need a serialfunc and deserialfunc
-CREATE AGGREGATE myavg (numeric)
-(
- stype = internal,
- sfunc = numeric_avg_accum,
- serialtype = bytea
-);
-ERROR: aggregate serialization function must be specified when serialization type is specified
-CREATE AGGREGATE myavg (numeric)
-(
- stype = internal,
- sfunc = numeric_avg_accum,
- serialtype = bytea,
serialfunc = numeric_avg_serialize
);
-ERROR: aggregate deserialization function must be specified when serialization type is specified
+ERROR: must specify both or neither of serialization and deserialization functions
-- serialfunc must have correct parameters
CREATE AGGREGATE myavg (numeric)
(
stype = internal,
sfunc = numeric_avg_accum,
- serialtype = bytea,
serialfunc = numeric_avg_deserialize,
deserialfunc = numeric_avg_deserialize
);
(
stype = internal,
sfunc = numeric_avg_accum,
- serialtype = bytea,
serialfunc = numeric_avg_serialize,
deserialfunc = numeric_avg_serialize
);
-ERROR: function numeric_avg_serialize(bytea) does not exist
--- ensure return type of serialfunc is checked
-CREATE AGGREGATE myavg (numeric)
-(
- stype = internal,
- sfunc = numeric_avg_accum,
- serialtype = text,
- serialfunc = numeric_avg_serialize,
- deserialfunc = numeric_avg_deserialize
-);
-ERROR: return type of serialization function numeric_avg_serialize is not text
+ERROR: function numeric_avg_serialize(bytea, internal) does not exist
-- ensure combine function parameters are checked
CREATE AGGREGATE myavg (numeric)
(
stype = internal,
sfunc = numeric_avg_accum,
- serialtype = bytea,
serialfunc = numeric_avg_serialize,
deserialfunc = numeric_avg_deserialize,
combinefunc = int4larger
stype = internal,
sfunc = numeric_avg_accum,
finalfunc = numeric_avg,
- serialtype = bytea,
serialfunc = numeric_avg_serialize,
deserialfunc = numeric_avg_deserialize,
combinefunc = numeric_avg_combine
);
-- Ensure all these functions made it into the catalog
-SELECT aggfnoid,aggtransfn,aggcombinefn,aggtranstype,aggserialfn,aggdeserialfn,aggserialtype
+SELECT aggfnoid,aggtransfn,aggcombinefn,aggtranstype,aggserialfn,aggdeserialfn
FROM pg_aggregate
WHERE aggfnoid = 'myavg'::REGPROC;
- aggfnoid | aggtransfn | aggcombinefn | aggtranstype | aggserialfn | aggdeserialfn | aggserialtype
-----------+-------------------+---------------------+--------------+-----------------------+-------------------------+---------------
- myavg | numeric_avg_accum | numeric_avg_combine | 2281 | numeric_avg_serialize | numeric_avg_deserialize | 17
+ aggfnoid | aggtransfn | aggcombinefn | aggtranstype | aggserialfn | aggdeserialfn
+----------+-------------------+---------------------+--------------+-----------------------+-------------------------
+ myavg | numeric_avg_accum | numeric_avg_combine | 2281 | numeric_avg_serialize | numeric_avg_deserialize
(1 row)
DROP AGGREGATE myavg (numeric);
-- Look for functions that return type "internal" and do not have any
-- "internal" argument. Such a function would be a security hole since
-- it might be used to call an internal function from an SQL command.
--- As of 7.3 this query should find internal_in, and as of 9.6 aggregate
--- deserialization will be found too. These should contain a runtime check to
--- ensure they can only be called in an aggregate context.
+-- As of 7.3 this query should find only internal_in, which is safe because
+-- it always throws an error when called.
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE p1.prorettype = 'internal'::regtype AND NOT
'internal'::regtype = ANY (p1.proargtypes);
- oid | proname
-------+--------------------------
- 2741 | numeric_avg_deserialize
- 3336 | numeric_deserialize
- 3340 | numeric_poly_deserialize
- 2787 | int8_avg_deserialize
+ oid | proname
+------+-------------
2304 | internal_in
-(5 rows)
+(1 row)
-- Look for functions that return a polymorphic type and do not have any
-- polymorphic argument. Calls of such functions would be unresolvable
----------+---------+-----+---------+-----+---------
(0 rows)
+-- Check that all combine functions have signature
+-- combine(transtype, transtype) returns transtype
+-- NOTE: use physically_coercible here, not binary_coercible, because
+-- max and min on abstime are implemented using int4larger/int4smaller.
+SELECT a.aggfnoid, p.proname
+FROM pg_aggregate as a, pg_proc as p
+WHERE a.aggcombinefn = p.oid AND
+ (p.pronargs != 2 OR
+ p.prorettype != p.proargtypes[0] OR
+ p.prorettype != p.proargtypes[1] OR
+ NOT physically_coercible(a.aggtranstype, p.proargtypes[0]));
+ aggfnoid | proname
+----------+---------
+(0 rows)
+
+-- Check that no combine function for an INTERNAL transtype is strict.
+SELECT a.aggfnoid, p.proname
+FROM pg_aggregate as a, pg_proc as p
+WHERE a.aggcombinefn = p.oid AND
+ a.aggtranstype = 'internal'::regtype AND p.proisstrict;
+ aggfnoid | proname
+----------+---------
+(0 rows)
+
+-- serialize/deserialize functions should be specified only for aggregates
+-- with transtype internal and a combine function, and we should have both
+-- or neither of them.
+SELECT aggfnoid, aggtranstype, aggserialfn, aggdeserialfn
+FROM pg_aggregate
+WHERE (aggserialfn != 0 OR aggdeserialfn != 0)
+ AND (aggtranstype != 'internal'::regtype OR aggcombinefn = 0 OR
+ aggserialfn = 0 OR aggdeserialfn = 0);
+ aggfnoid | aggtranstype | aggserialfn | aggdeserialfn
+----------+--------------+-------------+---------------
+(0 rows)
+
+-- Check that all serialization functions have signature
+-- serialize(internal) returns bytea
+-- Also insist that they be strict; it's wasteful to run them on NULLs.
+SELECT a.aggfnoid, p.proname
+FROM pg_aggregate as a, pg_proc as p
+WHERE a.aggserialfn = p.oid AND
+ (p.prorettype != 'bytea'::regtype OR p.pronargs != 1 OR
+ p.proargtypes[0] != 'internal'::regtype OR
+ NOT p.proisstrict);
+ aggfnoid | proname
+----------+---------
+(0 rows)
+
+-- Check that all deserialization functions have signature
+-- deserialize(bytea, internal) returns internal
+-- Also insist that they be strict; it's wasteful to run them on NULLs.
+SELECT a.aggfnoid, p.proname
+FROM pg_aggregate as a, pg_proc as p
+WHERE a.aggdeserialfn = p.oid AND
+ (p.prorettype != 'internal'::regtype OR p.pronargs != 2 OR
+ p.proargtypes[0] != 'bytea'::regtype OR
+ p.proargtypes[1] != 'internal'::regtype OR
+ NOT p.proisstrict);
+ aggfnoid | proname
+----------+---------
+(0 rows)
+
+-- Check that aggregates which have the same transition function also have
+-- the same combine, serialization, and deserialization functions.
+-- While that isn't strictly necessary, it's fishy if they don't.
+SELECT a.aggfnoid, a.aggcombinefn, a.aggserialfn, a.aggdeserialfn,
+ b.aggfnoid, b.aggcombinefn, b.aggserialfn, b.aggdeserialfn
+FROM
+ pg_aggregate a, pg_aggregate b
+WHERE
+ a.aggfnoid < b.aggfnoid AND a.aggtransfn = b.aggtransfn AND
+ (a.aggcombinefn != b.aggcombinefn OR a.aggserialfn != b.aggserialfn
+ OR a.aggdeserialfn != b.aggdeserialfn);
+ aggfnoid | aggcombinefn | aggserialfn | aggdeserialfn | aggfnoid | aggcombinefn | aggserialfn | aggdeserialfn
+----------+--------------+-------------+---------------+----------+--------------+-------------+---------------
+(0 rows)
+
-- Cross-check aggsortop (if present) against pg_operator.
-- We expect to find entries for bool_and, bool_or, every, max, and min.
SELECT DISTINCT proname, oprname
-----+---------
(0 rows)
--- Check that all serial functions have a return type the same as the serial
--- type.
-SELECT a.aggserialfn,a.aggserialtype,p.prorettype
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggserialfn = p.oid
-WHERE a.aggserialtype <> p.prorettype;
- aggserialfn | aggserialtype | prorettype
--------------+---------------+------------
-(0 rows)
-
--- Check that all the deserial functions have the same input type as the
--- serialtype
-SELECT a.aggserialfn,a.aggserialtype,p.proargtypes[0]
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggdeserialfn = p.oid
-WHERE p.proargtypes[0] <> a.aggserialtype;
- aggserialfn | aggserialtype | proargtypes
--------------+---------------+-------------
-(0 rows)
-
--- An aggregate should either have a complete set of serialtype, serial func
--- and deserial func, or none of them.
-SELECT aggserialtype,aggserialfn,aggdeserialfn
-FROM pg_aggregate
-WHERE (aggserialtype <> 0 OR aggserialfn <> 0 OR aggdeserialfn <> 0)
- AND (aggserialtype = 0 OR aggserialfn = 0 OR aggdeserialfn = 0);
- aggserialtype | aggserialfn | aggdeserialfn
----------------+-------------+---------------
-(0 rows)
-
--- Check that all aggregates with serialtypes have internal states.
--- (There's no point in serializing anything apart from internal)
-SELECT aggfnoid,aggserialtype,aggtranstype
-FROM pg_aggregate
-WHERE aggserialtype <> 0 AND aggtranstype <> 'internal'::regtype;
- aggfnoid | aggserialtype | aggtranstype
-----------+---------------+--------------
-(0 rows)
-
--- Check that all serial functions are strict. It's wasteful for these to be
--- called with NULL values.
-SELECT aggfnoid,aggserialfn
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggserialfn = p.oid
-WHERE p.proisstrict = false;
- aggfnoid | aggserialfn
-----------+-------------
-(0 rows)
-
--- Check that all deserial functions are strict. It's wasteful for these to be
--- called with NULL values.
-SELECT aggfnoid,aggdeserialfn
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggdeserialfn = p.oid
-WHERE p.proisstrict = false;
- aggfnoid | aggdeserialfn
-----------+---------------
-(0 rows)
-
--- Check that no combine functions with an INTERNAL return type are strict.
-SELECT aggfnoid,aggcombinefn
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggcombinefn = p.oid
-INNER JOIN pg_type t ON a.aggtranstype = t.oid
-WHERE t.typname = 'internal' AND p.proisstrict = true;
- aggfnoid | aggcombinefn
-----------+--------------
-(0 rows)
-
--- Check that aggregates which have the same transition function also have
--- the same combine, serialization, and deserialization functions.
-SELECT a.aggfnoid, a.aggcombinefn, a.aggserialfn, a.aggdeserialfn,
- b.aggfnoid, b.aggcombinefn, b.aggserialfn, b.aggdeserialfn
-FROM
- pg_aggregate a, pg_aggregate b
-WHERE
- a.aggfnoid < b.aggfnoid AND a.aggtransfn = b.aggtransfn AND
- (a.aggcombinefn != b.aggcombinefn OR a.aggserialfn != b.aggserialfn
- OR a.aggdeserialfn != b.aggdeserialfn);
- aggfnoid | aggcombinefn | aggserialfn | aggdeserialfn | aggfnoid | aggcombinefn | aggserialfn | aggdeserialfn
-----------+--------------+-------------+---------------+----------+--------------+-------------+---------------
-(0 rows)
-
-- **************** pg_opfamily ****************
-- Look for illegal values in pg_opfamily fields
SELECT p1.oid
-- aggregate combine and serialization functions
--- Ensure stype and serialtype can't be the same
+-- can't specify just one of serialfunc and deserialfunc
CREATE AGGREGATE myavg (numeric)
(
stype = internal,
sfunc = numeric_avg_accum,
- serialtype = internal
-);
-
--- if serialtype is specified we need a serialfunc and deserialfunc
-CREATE AGGREGATE myavg (numeric)
-(
- stype = internal,
- sfunc = numeric_avg_accum,
- serialtype = bytea
-);
-
-CREATE AGGREGATE myavg (numeric)
-(
- stype = internal,
- sfunc = numeric_avg_accum,
- serialtype = bytea,
serialfunc = numeric_avg_serialize
);
(
stype = internal,
sfunc = numeric_avg_accum,
- serialtype = bytea,
serialfunc = numeric_avg_deserialize,
deserialfunc = numeric_avg_deserialize
);
(
stype = internal,
sfunc = numeric_avg_accum,
- serialtype = bytea,
serialfunc = numeric_avg_serialize,
deserialfunc = numeric_avg_serialize
);
--- ensure return type of serialfunc is checked
-CREATE AGGREGATE myavg (numeric)
-(
- stype = internal,
- sfunc = numeric_avg_accum,
- serialtype = text,
- serialfunc = numeric_avg_serialize,
- deserialfunc = numeric_avg_deserialize
-);
-
-- ensure combine function parameters are checked
CREATE AGGREGATE myavg (numeric)
(
stype = internal,
sfunc = numeric_avg_accum,
- serialtype = bytea,
serialfunc = numeric_avg_serialize,
deserialfunc = numeric_avg_deserialize,
combinefunc = int4larger
stype = internal,
sfunc = numeric_avg_accum,
finalfunc = numeric_avg,
- serialtype = bytea,
serialfunc = numeric_avg_serialize,
deserialfunc = numeric_avg_deserialize,
combinefunc = numeric_avg_combine
);
-- Ensure all these functions made it into the catalog
-SELECT aggfnoid,aggtransfn,aggcombinefn,aggtranstype,aggserialfn,aggdeserialfn,aggserialtype
+SELECT aggfnoid,aggtransfn,aggcombinefn,aggtranstype,aggserialfn,aggdeserialfn
FROM pg_aggregate
WHERE aggfnoid = 'myavg'::REGPROC;
-- Look for functions that return type "internal" and do not have any
-- "internal" argument. Such a function would be a security hole since
-- it might be used to call an internal function from an SQL command.
--- As of 7.3 this query should find internal_in, and as of 9.6 aggregate
--- deserialization will be found too. These should contain a runtime check to
--- ensure they can only be called in an aggregate context.
+-- As of 7.3 this query should find only internal_in, which is safe because
+-- it always throws an error when called.
SELECT p1.oid, p1.proname
FROM pg_proc as p1
a.aggminvtransfn = iptr.oid AND
ptr.proisstrict != iptr.proisstrict;
+-- Check that all combine functions have signature
+-- combine(transtype, transtype) returns transtype
+-- NOTE: use physically_coercible here, not binary_coercible, because
+-- max and min on abstime are implemented using int4larger/int4smaller.
+
+SELECT a.aggfnoid, p.proname
+FROM pg_aggregate as a, pg_proc as p
+WHERE a.aggcombinefn = p.oid AND
+ (p.pronargs != 2 OR
+ p.prorettype != p.proargtypes[0] OR
+ p.prorettype != p.proargtypes[1] OR
+ NOT physically_coercible(a.aggtranstype, p.proargtypes[0]));
+
+-- Check that no combine function for an INTERNAL transtype is strict.
+
+SELECT a.aggfnoid, p.proname
+FROM pg_aggregate as a, pg_proc as p
+WHERE a.aggcombinefn = p.oid AND
+ a.aggtranstype = 'internal'::regtype AND p.proisstrict;
+
+-- serialize/deserialize functions should be specified only for aggregates
+-- with transtype internal and a combine function, and we should have both
+-- or neither of them.
+
+SELECT aggfnoid, aggtranstype, aggserialfn, aggdeserialfn
+FROM pg_aggregate
+WHERE (aggserialfn != 0 OR aggdeserialfn != 0)
+ AND (aggtranstype != 'internal'::regtype OR aggcombinefn = 0 OR
+ aggserialfn = 0 OR aggdeserialfn = 0);
+
+-- Check that all serialization functions have signature
+-- serialize(internal) returns bytea
+-- Also insist that they be strict; it's wasteful to run them on NULLs.
+
+SELECT a.aggfnoid, p.proname
+FROM pg_aggregate as a, pg_proc as p
+WHERE a.aggserialfn = p.oid AND
+ (p.prorettype != 'bytea'::regtype OR p.pronargs != 1 OR
+ p.proargtypes[0] != 'internal'::regtype OR
+ NOT p.proisstrict);
+
+-- Check that all deserialization functions have signature
+-- deserialize(bytea, internal) returns internal
+-- Also insist that they be strict; it's wasteful to run them on NULLs.
+
+SELECT a.aggfnoid, p.proname
+FROM pg_aggregate as a, pg_proc as p
+WHERE a.aggdeserialfn = p.oid AND
+ (p.prorettype != 'internal'::regtype OR p.pronargs != 2 OR
+ p.proargtypes[0] != 'bytea'::regtype OR
+ p.proargtypes[1] != 'internal'::regtype OR
+ NOT p.proisstrict);
+
+-- Check that aggregates which have the same transition function also have
+-- the same combine, serialization, and deserialization functions.
+-- While that isn't strictly necessary, it's fishy if they don't.
+
+SELECT a.aggfnoid, a.aggcombinefn, a.aggserialfn, a.aggdeserialfn,
+ b.aggfnoid, b.aggcombinefn, b.aggserialfn, b.aggdeserialfn
+FROM
+ pg_aggregate a, pg_aggregate b
+WHERE
+ a.aggfnoid < b.aggfnoid AND a.aggtransfn = b.aggtransfn AND
+ (a.aggcombinefn != b.aggcombinefn OR a.aggserialfn != b.aggserialfn
+ OR a.aggdeserialfn != b.aggdeserialfn);
+
-- Cross-check aggsortop (if present) against pg_operator.
-- We expect to find entries for bool_and, bool_or, every, max, and min.
FROM pg_proc AS p JOIN pg_aggregate AS a ON a.aggfnoid = p.oid
WHERE proisagg AND provariadic != 0 AND a.aggkind = 'n';
--- Check that all serial functions have a return type the same as the serial
--- type.
-SELECT a.aggserialfn,a.aggserialtype,p.prorettype
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggserialfn = p.oid
-WHERE a.aggserialtype <> p.prorettype;
-
--- Check that all the deserial functions have the same input type as the
--- serialtype
-SELECT a.aggserialfn,a.aggserialtype,p.proargtypes[0]
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggdeserialfn = p.oid
-WHERE p.proargtypes[0] <> a.aggserialtype;
-
--- An aggregate should either have a complete set of serialtype, serial func
--- and deserial func, or none of them.
-SELECT aggserialtype,aggserialfn,aggdeserialfn
-FROM pg_aggregate
-WHERE (aggserialtype <> 0 OR aggserialfn <> 0 OR aggdeserialfn <> 0)
- AND (aggserialtype = 0 OR aggserialfn = 0 OR aggdeserialfn = 0);
-
--- Check that all aggregates with serialtypes have internal states.
--- (There's no point in serializing anything apart from internal)
-SELECT aggfnoid,aggserialtype,aggtranstype
-FROM pg_aggregate
-WHERE aggserialtype <> 0 AND aggtranstype <> 'internal'::regtype;
-
--- Check that all serial functions are strict. It's wasteful for these to be
--- called with NULL values.
-SELECT aggfnoid,aggserialfn
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggserialfn = p.oid
-WHERE p.proisstrict = false;
-
--- Check that all deserial functions are strict. It's wasteful for these to be
--- called with NULL values.
-SELECT aggfnoid,aggdeserialfn
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggdeserialfn = p.oid
-WHERE p.proisstrict = false;
-
--- Check that no combine functions with an INTERNAL return type are strict.
-SELECT aggfnoid,aggcombinefn
-FROM pg_aggregate a
-INNER JOIN pg_proc p ON a.aggcombinefn = p.oid
-INNER JOIN pg_type t ON a.aggtranstype = t.oid
-WHERE t.typname = 'internal' AND p.proisstrict = true;
-
--- Check that aggregates which have the same transition function also have
--- the same combine, serialization, and deserialization functions.
-SELECT a.aggfnoid, a.aggcombinefn, a.aggserialfn, a.aggdeserialfn,
- b.aggfnoid, b.aggcombinefn, b.aggserialfn, b.aggdeserialfn
-FROM
- pg_aggregate a, pg_aggregate b
-WHERE
- a.aggfnoid < b.aggfnoid AND a.aggtransfn = b.aggtransfn AND
- (a.aggcombinefn != b.aggcombinefn OR a.aggserialfn != b.aggserialfn
- OR a.aggdeserialfn != b.aggdeserialfn);
-- **************** pg_opfamily ****************