]> granicus.if.org Git - postgresql/commitdiff
Fix type-safety problem with parallel aggregate serial/deserialization.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 22 Jun 2016 20:52:41 +0000 (16:52 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 22 Jun 2016 20:52:41 +0000 (16:52 -0400)
The original specification for this called for the deserialization function
to have signature "deserialize(serialtype) returns transtype", which is a
security violation if transtype is INTERNAL (which it always would be in
practice) and serialtype is not (which ditto).  The patch blithely overrode
the opr_sanity check for that, which was sloppy-enough work in itself,
but the indisputable reason this cannot be allowed to stand is that CREATE
FUNCTION will reject such a signature and thus it'd be impossible for
extensions to create parallelizable aggregates.

The minimum fix to make the signature type-safe is to add a second, dummy
argument of type INTERNAL.  But to lock it down a bit more and make misuse
of INTERNAL-accepting functions less likely, let's get rid of the ability
to specify a "serialtype" for an aggregate and just say that the only
useful serialtype is BYTEA --- which, in practice, is the only interesting
value anyway, due to the usefulness of the send/recv infrastructure for
this purpose.  That means we only have to allow "serialize(internal)
returns bytea" and "deserialize(bytea, internal) returns internal" as
the signatures for these support functions.

In passing fix bogus signature of int4_avg_combine, which I found thanks
to adding an opr_sanity check on combinefunc signatures.

catversion bump due to removing pg_aggregate.aggserialtype and adjusting
signatures of assorted built-in functions.

David Rowley and Tom Lane

Discussion: <27247.1466185504@sss.pgh.pa.us>

18 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/ref/create_aggregate.sgml
src/backend/catalog/pg_aggregate.c
src/backend/commands/aggregatecmds.c
src/backend/executor/nodeAgg.c
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/tlist.c
src/backend/parser/parse_agg.c
src/backend/utils/adt/numeric.c
src/bin/pg_dump/pg_dump.c
src/include/catalog/catversion.h
src/include/catalog/pg_aggregate.h
src/include/catalog/pg_proc.h
src/include/parser/parse_agg.h
src/test/regress/expected/create_aggregate.out
src/test/regress/expected/opr_sanity.out
src/test/regress/sql/create_aggregate.sql
src/test/regress/sql/opr_sanity.sql

index 2420c94bc19cdf004fa4cdb2cc718453f5781233..18e5faef5748c763ec022c9d7c128b7717f8fcb3 100644 (file)
       <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>
index 3df330393dec93b65e1036545edab4b4beb42532..6dc193199793d5322a951cdb7647dc67b3a50a0e 100644 (file)
@@ -30,7 +30,6 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> ( [ <replacea
     [ , 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> ]
@@ -50,10 +49,6 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> ( [ [ <replac
     [ , 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 } ]
@@ -72,7 +67,6 @@ CREATE AGGREGATE <replaceable class="PARAMETER">name</replaceable> (
     [ , 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> ]
@@ -255,7 +249,7 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
    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>
 
@@ -412,38 +406,51 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
     <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>
@@ -452,14 +459,13 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
     <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>
@@ -470,21 +476,12 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
     <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>
index 73d19ec3947ae330d64c0d29f1f94f08a294ffe6..959d3845df217455815c6c0e4c4f85b06ada486f 100644 (file)
@@ -67,7 +67,6 @@ AggregateCreate(const char *aggName,
                                bool mfinalfnExtraArgs,
                                List *aggsortopName,
                                Oid aggTransType,
-                               Oid aggSerialType,
                                int32 aggTransSpace,
                                Oid aggmTransType,
                                int32 aggmTransSpace,
@@ -440,44 +439,42 @@ AggregateCreate(const char *aggName,
        }
 
        /*
-        * 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))));
        }
 
        /*
@@ -661,7 +658,6 @@ AggregateCreate(const char *aggName,
        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);
@@ -688,8 +684,7 @@ AggregateCreate(const char *aggName,
         * 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 */
index f1fdc1a36037247eeaa546bdff25a9f17bb45502..d34c82c5baf7134d9f991dc64ff2bd838fc7eb92 100644 (file)
@@ -72,7 +72,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters,
        List       *sortoperatorName = NIL;
        TypeName   *baseType = NULL;
        TypeName   *transType = NULL;
-       TypeName   *serialType = NULL;
        TypeName   *mtransType = NULL;
        int32           transSpace = 0;
        int32           mtransSpace = 0;
@@ -88,7 +87,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters,
        List       *parameterDefaults;
        Oid                     variadicArgType;
        Oid                     transTypeId;
-       Oid                     serialTypeId = InvalidOid;
        Oid                     mtransTypeId = InvalidOid;
        char            transTypeType;
        char            mtransTypeType = 0;
@@ -164,8 +162,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters,
                }
                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)
@@ -333,73 +329,25 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters,
                                                        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")));
        }
 
        /*
@@ -493,7 +441,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters,
                                                   mfinalfuncExtraArgs,
                                                   sortoperatorName,    /* sort operator name */
                                                   transTypeId, /* transition data type */
-                                                  serialTypeId,                /* serialization data type */
                                                   transSpace,  /* transition space */
                                                   mtransTypeId,                /* transition data type */
                                                   mtransSpace, /* transition space */
index 7b282dec7dae9ff489e45d4b6ea32a1322fda92e..a44796461299856b99817a62ef8fff4206ee1c78 100644 (file)
@@ -514,10 +514,9 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
 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,
@@ -996,6 +995,9 @@ combine_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
 
                                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
@@ -2669,8 +2671,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
                AclResult       aclresult;
                Oid                     transfn_oid,
                                        finalfn_oid;
-               Oid                     serialtype_oid,
-                                       serialfn_oid,
+               Oid                     serialfn_oid,
                                        deserialfn_oid;
                Expr       *finalfnexpr;
                Oid                     aggtranstype;
@@ -2740,7 +2741,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
                else
                        peragg->finalfn_oid = finalfn_oid = InvalidOid;
 
-               serialtype_oid = InvalidOid;
                serialfn_oid = InvalidOid;
                deserialfn_oid = InvalidOid;
 
@@ -2753,13 +2753,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
                {
                        /*
                         * 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");
 
@@ -2768,17 +2764,11 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 
                        /* 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 */
@@ -2906,10 +2896,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
                        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);
@@ -2937,7 +2926,7 @@ static void
 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)
@@ -3065,10 +3054,7 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
 
        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);
@@ -3076,24 +3062,21 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
                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);
 
        }
index 0e738c1ccc098c0b7b1fa387c5b7c288cf6049fc..7138cad31d82452dc0b7aed9b9414919b258008c 100644 (file)
@@ -465,13 +465,11 @@ aggregates_allow_partial_walker(Node *node, partial_agg_context *context)
 
                /*
                 * 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;
 
index de0a8c7b57fff1f9d96d44919ce0db5b4fbbfb5c..5fa80ac51be7dce19f5e3011ee74c82f9b2b4de6 100644 (file)
@@ -15,7 +15,7 @@
 #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"
@@ -766,8 +766,8 @@ apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target)
 /*
  * 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
@@ -784,40 +784,29 @@ apply_partialaggref_adjustment(PathTarget *target)
 
                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);
                }
        }
 }
index b9ca066698ef916058d47c054e56cac12384d7f5..481a4ddc4847d49d73bef4181a891210248e7721 100644 (file)
@@ -71,6 +71,8 @@ static bool finalize_grouping_exprs_walker(Node *node,
                                                           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 -
@@ -1863,37 +1865,19 @@ build_aggregate_transfn_expr(Oid *agg_input_types,
                                                         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,
@@ -1936,20 +1920,13 @@ build_aggregate_combinefn_expr(Oid agg_state_type,
                                                           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,
@@ -1958,49 +1935,57 @@ build_aggregate_combinefn_expr(Oid agg_state_type,
                                                 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.
@@ -2014,33 +1999,19 @@ build_aggregate_finalfn_expr(Oid *agg_input_types,
                                                         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,
@@ -2051,3 +2022,24 @@ build_aggregate_finalfn_expr(Oid *agg_input_types,
                                                                                 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;
+}
index 6592ef4d2d93cf478bff2202609f8c04776327f5..f0b3b87f4c341c64c16121f810625e0cba6db990 100644 (file)
@@ -3510,10 +3510,7 @@ numeric_avg_combine(PG_FUNCTION_ARGS)
 /*
  * 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)
@@ -3564,17 +3561,13 @@ 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;
@@ -3582,6 +3575,8 @@ numeric_avg_deserialize(PG_FUNCTION_ARGS)
        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.
@@ -3619,11 +3614,7 @@ numeric_avg_deserialize(PG_FUNCTION_ARGS)
 /*
  * 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)
@@ -3683,16 +3674,12 @@ 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;
@@ -3700,6 +3687,8 @@ numeric_deserialize(PG_FUNCTION_ARGS)
        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.
@@ -3992,11 +3981,8 @@ numeric_poly_combine(PG_FUNCTION_ARGS)
 
 /*
  * 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)
@@ -4067,16 +4053,13 @@ 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;
@@ -4085,6 +4068,8 @@ numeric_poly_deserialize(PG_FUNCTION_ARGS)
        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.
@@ -4226,9 +4211,6 @@ int8_avg_combine(PG_FUNCTION_ARGS)
 /*
  * 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)
@@ -4286,14 +4268,11 @@ 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;
@@ -4301,6 +4280,8 @@ int8_avg_deserialize(PG_FUNCTION_ARGS)
        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.
index 13bfd2cfb934cdf0d769147e7b9657168c768752..08c2b0c7a302961c9548c31bb91445a676938e47 100644 (file)
@@ -13412,7 +13412,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        int                     i_aggsortop;
        int                     i_hypothetical;
        int                     i_aggtranstype;
-       int                     i_aggserialtype;
        int                     i_aggtransspace;
        int                     i_aggmtranstype;
        int                     i_aggmtransspace;
@@ -13434,7 +13433,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        char       *aggsortconvop;
        bool            hypothetical;
        const char *aggtranstype;
-       const char *aggserialtype;
        const char *aggtransspace;
        const char *aggmtranstype;
        const char *aggmtransspace;
@@ -13465,7 +13463,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                   "aggminvtransfn, aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
                                                  "aggfinalextra, aggmfinalextra, "
                                                  "aggsortop::pg_catalog.regoperator, "
-                                                 "aggserialtype::pg_catalog.regtype, "
                                                  "(aggkind = 'h') AS hypothetical, "
                                                  "aggtransspace, agginitval, "
                                                  "aggmtransspace, aggminitval, "
@@ -13487,7 +13484,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
                                                  "aggfinalextra, aggmfinalextra, "
                                                  "aggsortop::pg_catalog.regoperator, "
-                                                 "0 AS aggserialtype, "
                                                  "(aggkind = 'h') AS hypothetical, "
                                                  "aggtransspace, agginitval, "
                                                  "aggmtransspace, aggminitval, "
@@ -13509,7 +13505,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "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, "
@@ -13531,7 +13526,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "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, "
@@ -13550,7 +13544,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "'-' 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, "
@@ -13569,7 +13562,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "'-' 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, "
@@ -13588,7 +13580,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  "'-' 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, "
@@ -13611,7 +13602,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        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");
@@ -13635,7 +13625,6 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        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);
@@ -13722,20 +13711,13 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        }
 
        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)
        {
index 90bcd1bc254f7b99952f88815a58ed962be19a5a..9c404523d7d75c5b9ad4de83c526d7551297ea61 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201606171
+#define CATALOG_VERSION_NO     201606221
 
 #endif
index 057c88c077e616997571d1929107cf152faca90c..8865bba0103f00e3661a84e0dd79f09dd8b26a98 100644 (file)
@@ -34,8 +34,8 @@
  *     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)
@@ -45,7 +45,6 @@
  *     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)
@@ -70,7 +69,6 @@ CATALOG(pg_aggregate,2600) BKI_WITHOUT_OIDS
        bool            aggmfinalextra;
        Oid                     aggsortop;
        Oid                     aggtranstype;
-       Oid                     aggserialtype;
        int32           aggtransspace;
        Oid                     aggmtranstype;
        int32           aggmtransspace;
@@ -93,7 +91,7 @@ typedef FormData_pg_aggregate *Form_pg_aggregate;
  * ----------------
  */
 
-#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
@@ -109,12 +107,11 @@ typedef FormData_pg_aggregate *Form_pg_aggregate;
 #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
@@ -138,184 +135,184 @@ typedef FormData_pg_aggregate *Form_pg_aggregate;
  */
 
 /* 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_ ));
 
 
 /*
@@ -344,7 +341,6 @@ extern ObjectAddress AggregateCreate(const char *aggName,
                                bool mfinalfnExtraArgs,
                                List *aggsortopName,
                                Oid aggTransType,
-                               Oid aggSerialType,
                                int32 aggTransSpace,
                                Oid aggmTransType,
                                int32 aggmTransSpace,
index 6a65e77b5ecfd4d6a42e5b101ecc1585af3bc705..f441025f58ddbdcdcb099c11e8a6059f0dcdac8b 100644 (file)
@@ -2451,11 +2451,11 @@ DATA(insert OID = 3337 (  numeric_avg_combine    PGNSP PGUID 12 1 0 0 0 f f f f f
 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");
@@ -2469,7 +2469,7 @@ DATA(insert OID = 3338 (  numeric_poly_combine      PGNSP PGUID 12 1 0 0 0 f f f f
 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");
@@ -2485,9 +2485,9 @@ DATA(insert OID = 2785 (  int8_avg_combine          PGNSP PGUID 12 1 0 0 0 f f f f f f
 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");
index 1408d4e9fd2bcc66dbcc589e2975b2e6bf2ecd7b..28fc354a424c8cdd040f8991c4314f41c2b2b168 100644 (file)
@@ -51,12 +51,12 @@ extern void build_aggregate_combinefn_expr(Oid agg_state_type,
                                                           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,
index 625dae5cdbb66cc76e3f28f3ef60a1483163f004..341ba52b8d6c9e3877f200cc582186bda3f0e0ef 100644 (file)
@@ -102,36 +102,19 @@ CREATE AGGREGATE sumdouble (float8)
     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
 );
@@ -141,27 +124,15 @@ CREATE AGGREGATE myavg (numeric)
 (
        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
@@ -173,18 +144,17 @@ CREATE AGGREGATE myavg (numeric)
        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);
index b1596401306179a8fff29ed19c459969fa6408e3..826441442b72c3e1c0ea4f082de99924cf99d94a 100644 (file)
@@ -279,21 +279,16 @@ ORDER BY 1, 2;
 -- 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
@@ -1442,6 +1437,84 @@ WHERE a.aggfnoid = p.oid AND
 ----------+---------+-----+---------+-----+---------
 (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
@@ -1534,89 +1607,6 @@ WHERE proisagg AND provariadic != 0 AND a.aggkind = 'n';
 -----+---------
 (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
index c98c154a8296baa6e345576c716a482cdd23880d..ae3a6c0ebec9ccfc65752b8fbff3daca50e03474 100644 (file)
@@ -117,27 +117,11 @@ CREATE AGGREGATE sumdouble (float8)
 
 -- 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
 );
 
@@ -146,7 +130,6 @@ CREATE AGGREGATE myavg (numeric)
 (
        stype = internal,
        sfunc = numeric_avg_accum,
-       serialtype = bytea,
        serialfunc = numeric_avg_deserialize,
        deserialfunc = numeric_avg_deserialize
 );
@@ -156,27 +139,15 @@ CREATE AGGREGATE myavg (numeric)
 (
        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
@@ -188,14 +159,13 @@ CREATE AGGREGATE myavg (numeric)
        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;
 
index 62c84d035d52b56b8154dc5e29abc9e785a96554..bb9b6bb3b8a351ec20af27bc2ed8a76c9ce25388 100644 (file)
@@ -228,9 +228,8 @@ ORDER BY 1, 2;
 -- 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
@@ -937,6 +936,72 @@ WHERE a.aggfnoid = p.oid AND
     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.
 
@@ -1004,64 +1069,6 @@ SELECT p.oid, proname
 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 ****************