diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 9af77c1..cfec246 100644
*** a/doc/src/sgml/catalogs.sgml
--- b/doc/src/sgml/catalogs.sgml
***************
*** 487,492 ****
--- 487,512 ----
        <entry>True to pass extra dummy arguments to <structfield>aggmfinalfn</structfield></entry>
       </row>
       <row>
+       <entry><structfield>aggfinalmodify</structfield></entry>
+       <entry><type>char</type></entry>
+       <entry></entry>
+       <entry>Whether <structfield>aggfinalfn</structfield> modifies the
+        transition state value:
+        <literal>r</literal> if it is read-only,
+        <literal>s</literal> if the <structfield>aggtransfn</structfield>
+        cannot be applied after the <structfield>aggfinalfn</structfield>, or
+        <literal>w</literal> if it writes on the value
+       </entry>
+      </row>
+      <row>
+       <entry><structfield>aggmfinalmodify</structfield></entry>
+       <entry><type>char</type></entry>
+       <entry></entry>
+       <entry>Like <structfield>aggfinalmodify</structfield>, but for
+        the <structfield>aggmfinalfn</structfield>
+       </entry>
+      </row>
+      <row>
        <entry><structfield>aggsortop</structfield></entry>
        <entry><type>oid</type></entry>
        <entry><literal><link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.oid</literal></entry>
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index a920450..ca3fd81 100644
*** a/src/backend/catalog/pg_aggregate.c
--- b/src/backend/catalog/pg_aggregate.c
***************
*** 19,24 ****
--- 19,25 ----
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_aggregate.h"
+ #include "catalog/pg_aggregate_fn.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_operator.h"
  #include "catalog/pg_proc.h"
*************** AggregateCreate(const char *aggName,
*** 65,70 ****
--- 66,73 ----
  				List *aggmfinalfnName,
  				bool finalfnExtraArgs,
  				bool mfinalfnExtraArgs,
+ 				char finalfnModify,
+ 				char mfinalfnModify,
  				List *aggsortopName,
  				Oid aggTransType,
  				int32 aggTransSpace,
*************** AggregateCreate(const char *aggName,
*** 656,661 ****
--- 659,666 ----
  	values[Anum_pg_aggregate_aggmfinalfn - 1] = ObjectIdGetDatum(mfinalfn);
  	values[Anum_pg_aggregate_aggfinalextra - 1] = BoolGetDatum(finalfnExtraArgs);
  	values[Anum_pg_aggregate_aggmfinalextra - 1] = BoolGetDatum(mfinalfnExtraArgs);
+ 	values[Anum_pg_aggregate_aggfinalmodify - 1] = CharGetDatum(finalfnModify);
+ 	values[Anum_pg_aggregate_aggmfinalmodify - 1] = CharGetDatum(mfinalfnModify);
  	values[Anum_pg_aggregate_aggsortop - 1] = ObjectIdGetDatum(sortop);
  	values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType);
  	values[Anum_pg_aggregate_aggtransspace - 1] = Int32GetDatum(aggTransSpace);
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index a63539a..07ef4c5 100644
*** a/src/backend/commands/aggregatecmds.c
--- b/src/backend/commands/aggregatecmds.c
***************
*** 26,31 ****
--- 26,32 ----
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_aggregate.h"
+ #include "catalog/pg_aggregate_fn.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
  #include "commands/alter.h"
***************
*** 39,44 ****
--- 40,48 ----
  #include "utils/syscache.h"
  
  
+ static char extractModify(DefElem *defel);
+ 
+ 
  /*
   *	DefineAggregate
   *
*************** DefineAggregate(ParseState *pstate, List
*** 67,72 ****
--- 71,78 ----
  	List	   *mfinalfuncName = NIL;
  	bool		finalfuncExtraArgs = false;
  	bool		mfinalfuncExtraArgs = false;
+ 	char		finalfuncModify = 0;
+ 	char		mfinalfuncModify = 0;
  	List	   *sortoperatorName = NIL;
  	TypeName   *baseType = NULL;
  	TypeName   *transType = NULL;
*************** DefineAggregate(ParseState *pstate, List
*** 143,148 ****
--- 149,158 ----
  			finalfuncExtraArgs = defGetBoolean(defel);
  		else if (pg_strcasecmp(defel->defname, "mfinalfunc_extra") == 0)
  			mfinalfuncExtraArgs = defGetBoolean(defel);
+ 		else if (pg_strcasecmp(defel->defname, "finalfunc_modify") == 0)
+ 			finalfuncModify = extractModify(defel);
+ 		else if (pg_strcasecmp(defel->defname, "mfinalfunc_modify") == 0)
+ 			mfinalfuncModify = extractModify(defel);
  		else if (pg_strcasecmp(defel->defname, "sortop") == 0)
  			sortoperatorName = defGetQualifiedName(defel);
  		else if (pg_strcasecmp(defel->defname, "basetype") == 0)
*************** DefineAggregate(ParseState *pstate, List
*** 236,241 ****
--- 246,260 ----
  	}
  
  	/*
+ 	 * Default values for modify flags can only be determined once we know the
+ 	 * aggKind.
+ 	 */
+ 	if (finalfuncModify == 0)
+ 		finalfuncModify = (aggKind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
+ 	if (mfinalfuncModify == 0)
+ 		mfinalfuncModify = (aggKind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
+ 
+ 	/*
  	 * look up the aggregate's input datatype(s).
  	 */
  	if (oldstyle)
*************** DefineAggregate(ParseState *pstate, List
*** 437,442 ****
--- 456,463 ----
  						   mfinalfuncName,	/* final function name */
  						   finalfuncExtraArgs,
  						   mfinalfuncExtraArgs,
+ 						   finalfuncModify,
+ 						   mfinalfuncModify,
  						   sortoperatorName,	/* sort operator name */
  						   transTypeId, /* transition data type */
  						   transSpace,	/* transition space */
*************** DefineAggregate(ParseState *pstate, List
*** 446,448 ****
--- 467,490 ----
  						   minitval,	/* initial condition */
  						   proparallel);	/* parallel safe? */
  }
+ 
+ /*
+  * Convert the string form of [m]finalfunc_modify to the catalog representation
+  */
+ static char
+ extractModify(DefElem *defel)
+ {
+ 	char	   *val = defGetString(defel);
+ 
+ 	if (strcmp(val, "read_only") == 0)
+ 		return AGGMODIFY_READ_ONLY;
+ 	if (strcmp(val, "stop_updates") == 0)
+ 		return AGGMODIFY_STOP_UPDATES;
+ 	if (strcmp(val, "read_write") == 0)
+ 		return AGGMODIFY_READ_WRITE;
+ 	ereport(ERROR,
+ 			(errcode(ERRCODE_SYNTAX_ERROR),
+ 			 errmsg("parameter \"%s\" must be READ_ONLY, STOP_UPDATES, or READ_WRITE",
+ 					defel->defname)));
+ 	return 0;					/* keep compiler quiet */
+ }
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 6543ece..36c6ecb 100644
*** a/src/backend/executor/nodeAgg.c
--- b/src/backend/executor/nodeAgg.c
*************** typedef struct AggStatePerTransData
*** 248,256 ****
  	/*
  	 * Link to an Aggref expr this state value is for.
  	 *
! 	 * There can be multiple Aggref's sharing the same state value, as long as
! 	 * the inputs and transition function are identical. This points to the
! 	 * first one of them.
  	 */
  	Aggref	   *aggref;
  
--- 248,256 ----
  	/*
  	 * Link to an Aggref expr this state value is for.
  	 *
! 	 * There can be multiple Aggref's sharing the same state value, so long as
! 	 * the inputs and transition functions are identical and the final
! 	 * functions are not read-write.  This points to the first one of them.
  	 */
  	Aggref	   *aggref;
  
*************** typedef struct AggStatePerAggData
*** 419,426 ****
  	Oid			finalfn_oid;
  
  	/*
! 	 * fmgr lookup data for final function --- only valid when finalfn_oid oid
! 	 * is not InvalidOid.
  	 */
  	FmgrInfo	finalfn;
  
--- 419,426 ----
  	Oid			finalfn_oid;
  
  	/*
! 	 * fmgr lookup data for final function --- only valid when finalfn_oid is
! 	 * not InvalidOid.
  	 */
  	FmgrInfo	finalfn;
  
*************** typedef struct AggStatePerAggData
*** 439,444 ****
--- 439,449 ----
  	int16		resulttypeLen;
  	bool		resulttypeByVal;
  
+ 	/*
+ 	 * "sharable" is false if this agg cannot share state values with other
+ 	 * aggregates because the final function is read-write.
+ 	 */
+ 	bool		sharable;
  }			AggStatePerAggData;
  
  /*
*************** static void build_pertrans_for_aggref(Ag
*** 572,577 ****
--- 577,583 ----
  static int find_compatible_peragg(Aggref *newagg, AggState *aggstate,
  					   int lastaggno, List **same_input_transnos);
  static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg,
+ 						 bool sharable,
  						 Oid aggtransfn, Oid aggtranstype,
  						 Oid aggserialfn, Oid aggdeserialfn,
  						 Datum initValue, bool initValueIsNull,
*************** ExecInitAgg(Agg *node, EState *estate, i
*** 3105,3110 ****
--- 3111,3117 ----
  		AclResult	aclresult;
  		Oid			transfn_oid,
  					finalfn_oid;
+ 		bool		sharable;
  		Oid			serialfn_oid,
  					deserialfn_oid;
  		Expr	   *finalfnexpr;
*************** ExecInitAgg(Agg *node, EState *estate, i
*** 3177,3182 ****
--- 3184,3198 ----
  		else
  			peragg->finalfn_oid = finalfn_oid = aggform->aggfinalfn;
  
+ 		/*
+ 		 * If finalfn is marked read-write, we can't share transition states;
+ 		 * but it is okay to share for AGGMODIFY_STOP_UPDATES aggs.  Also, if
+ 		 * we're not executing the finalfn here, we can share regardless.
+ 		 */
+ 		sharable = (aggform->aggfinalmodify != AGGMODIFY_READ_WRITE) ||
+ 			(finalfn_oid == InvalidOid);
+ 		peragg->sharable = sharable;
+ 
  		serialfn_oid = InvalidOid;
  		deserialfn_oid = InvalidOid;
  
*************** ExecInitAgg(Agg *node, EState *estate, i
*** 3315,3325 ****
  		 * 2. Build working state for invoking the transition function, or
  		 * look up previously initialized working state, if we can share it.
  		 *
! 		 * find_compatible_peragg() already collected a list of per-Trans's
! 		 * with the same inputs. Check if any of them have the same transition
! 		 * function and initial value.
  		 */
  		existing_transno = find_compatible_pertrans(aggstate, aggref,
  													transfn_oid, aggtranstype,
  													serialfn_oid, deserialfn_oid,
  													initValue, initValueIsNull,
--- 3331,3342 ----
  		 * 2. Build working state for invoking the transition function, or
  		 * look up previously initialized working state, if we can share it.
  		 *
! 		 * find_compatible_peragg() already collected a list of sharable
! 		 * per-Trans's with the same inputs. Check if any of them have the
! 		 * same transition function and initial value.
  		 */
  		existing_transno = find_compatible_pertrans(aggstate, aggref,
+ 													sharable,
  													transfn_oid, aggtranstype,
  													serialfn_oid, deserialfn_oid,
  													initValue, initValueIsNull,
*************** GetAggInitVal(Datum textInitVal, Oid tra
*** 3724,3733 ****
   * with this one, with the same input parameters. If no compatible aggregate
   * can be found, returns -1.
   *
!  * As a side-effect, this also collects a list of existing per-Trans structs
!  * with matching inputs. If no identical Aggref is found, the list is passed
!  * later to find_compatible_pertrans, to see if we can at least reuse the
!  * state value of another aggregate.
   */
  static int
  find_compatible_peragg(Aggref *newagg, AggState *aggstate,
--- 3741,3750 ----
   * with this one, with the same input parameters. If no compatible aggregate
   * can be found, returns -1.
   *
!  * As a side-effect, this also collects a list of existing, sharable per-Trans
!  * structs with matching inputs. If no identical Aggref is found, the list is
!  * passed later to find_compatible_pertrans, to see if we can at least reuse
!  * the state value of another aggregate.
   */
  static int
  find_compatible_peragg(Aggref *newagg, AggState *aggstate,
*************** find_compatible_peragg(Aggref *newagg, A
*** 3785,3795 ****
  		}
  
  		/*
! 		 * Not identical, but it had the same inputs. Return it to the caller,
! 		 * in case we can re-use its per-trans state.
  		 */
! 		*same_input_transnos = lappend_int(*same_input_transnos,
! 										   peragg->transno);
  	}
  
  	return -1;
--- 3802,3816 ----
  		}
  
  		/*
! 		 * Not identical, but it had the same inputs.  If the final function
! 		 * permits sharing, return its transno to the caller, in case we can
! 		 * re-use its per-trans state.  (If there's already sharing going on,
! 		 * we can report a transno more than once.  find_compatible_pertrans
! 		 * is cheap enough that it's not worth working hard to avoid that.)
  		 */
! 		if (peragg->sharable)
! 			*same_input_transnos = lappend_int(*same_input_transnos,
! 											   peragg->transno);
  	}
  
  	return -1;
*************** find_compatible_peragg(Aggref *newagg, A
*** 3804,3810 ****
   * verified to match.)
   */
  static int
! find_compatible_pertrans(AggState *aggstate, Aggref *newagg,
  						 Oid aggtransfn, Oid aggtranstype,
  						 Oid aggserialfn, Oid aggdeserialfn,
  						 Datum initValue, bool initValueIsNull,
--- 3825,3831 ----
   * verified to match.)
   */
  static int
! find_compatible_pertrans(AggState *aggstate, Aggref *newagg, bool sharable,
  						 Oid aggtransfn, Oid aggtranstype,
  						 Oid aggserialfn, Oid aggdeserialfn,
  						 Datum initValue, bool initValueIsNull,
*************** find_compatible_pertrans(AggState *aggst
*** 3812,3825 ****
  {
  	ListCell   *lc;
  
! 	/*
! 	 * For the moment, never try to share transition states between different
! 	 * ordered-set aggregates.  This is necessary because the finalfns of the
! 	 * built-in OSAs (see orderedsetaggs.c) are destructive of their
! 	 * transition states.  We should fix them so we can allow this, but not
! 	 * losing performance in the normal non-shared case will take some work.
! 	 */
! 	if (AGGKIND_IS_ORDERED_SET(newagg->aggkind))
  		return -1;
  
  	foreach(lc, transnos)
--- 3833,3840 ----
  {
  	ListCell   *lc;
  
! 	/* If this aggregate can't share transition states, give up */
! 	if (!sharable)
  		return -1;
  
  	foreach(lc, transnos)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 80be460..35174fe 100644
*** a/src/backend/executor/nodeWindowAgg.c
--- b/src/backend/executor/nodeWindowAgg.c
***************
*** 49,54 ****
--- 49,55 ----
  #include "utils/datum.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
+ #include "utils/regproc.h"
  #include "utils/syscache.h"
  #include "windowapi.h"
  
*************** initialize_peragg(WindowAggState *winsta
*** 2100,2105 ****
--- 2101,2107 ----
  				invtransfn_oid,
  				finalfn_oid;
  	bool		finalextra;
+ 	char		finalmodify;
  	Expr	   *transfnexpr,
  			   *invtransfnexpr,
  			   *finalfnexpr;
*************** initialize_peragg(WindowAggState *winsta
*** 2139,2144 ****
--- 2141,2147 ----
  		peraggstate->invtransfn_oid = invtransfn_oid = aggform->aggminvtransfn;
  		peraggstate->finalfn_oid = finalfn_oid = aggform->aggmfinalfn;
  		finalextra = aggform->aggmfinalextra;
+ 		finalmodify = aggform->aggmfinalmodify;
  		aggtranstype = aggform->aggmtranstype;
  		initvalAttNo = Anum_pg_aggregate_aggminitval;
  	}
*************** initialize_peragg(WindowAggState *winsta
*** 2148,2153 ****
--- 2151,2157 ----
  		peraggstate->invtransfn_oid = invtransfn_oid = InvalidOid;
  		peraggstate->finalfn_oid = finalfn_oid = aggform->aggfinalfn;
  		finalextra = aggform->aggfinalextra;
+ 		finalmodify = aggform->aggfinalmodify;
  		aggtranstype = aggform->aggtranstype;
  		initvalAttNo = Anum_pg_aggregate_agginitval;
  	}
*************** initialize_peragg(WindowAggState *winsta
*** 2198,2203 ****
--- 2202,2218 ----
  		}
  	}
  
+ 	/*
+ 	 * If the selected finalfn isn't read-only, we can't run this aggregate as
+ 	 * a window function.  This is a user-facing error, so we take a bit more
+ 	 * care with the error message than elsewhere in this function.
+ 	 */
+ 	if (finalmodify != AGGMODIFY_READ_ONLY)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				 errmsg("aggregate function %s does not support use as a window function",
+ 						format_procedure(wfunc->winfnoid))));
+ 
  	/* Detect how many arguments to pass to the finalfn */
  	if (finalextra)
  		peraggstate->numFinalArgs = numArguments + 1;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index e34c83a..898abd7 100644
*** a/src/bin/pg_dump/pg_dump.c
--- b/src/bin/pg_dump/pg_dump.c
***************
*** 42,47 ****
--- 42,48 ----
  #include "access/attnum.h"
  #include "access/sysattr.h"
  #include "access/transam.h"
+ #include "catalog/pg_aggregate.h"
  #include "catalog/pg_am.h"
  #include "catalog/pg_attribute.h"
  #include "catalog/pg_cast.h"
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13433,13440 ****
  	int			i_aggmfinalfn;
  	int			i_aggfinalextra;
  	int			i_aggmfinalextra;
  	int			i_aggsortop;
! 	int			i_hypothetical;
  	int			i_aggtranstype;
  	int			i_aggtransspace;
  	int			i_aggmtranstype;
--- 13434,13443 ----
  	int			i_aggmfinalfn;
  	int			i_aggfinalextra;
  	int			i_aggmfinalextra;
+ 	int			i_aggfinalmodify;
+ 	int			i_aggmfinalmodify;
  	int			i_aggsortop;
! 	int			i_aggkind;
  	int			i_aggtranstype;
  	int			i_aggtransspace;
  	int			i_aggmtranstype;
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13453,13461 ****
  	const char *aggmfinalfn;
  	bool		aggfinalextra;
  	bool		aggmfinalextra;
  	const char *aggsortop;
  	char	   *aggsortconvop;
! 	bool		hypothetical;
  	const char *aggtranstype;
  	const char *aggtransspace;
  	const char *aggmtranstype;
--- 13456,13466 ----
  	const char *aggmfinalfn;
  	bool		aggfinalextra;
  	bool		aggmfinalextra;
+ 	char		aggfinalmodify;
+ 	char		aggmfinalmodify;
  	const char *aggsortop;
  	char	   *aggsortconvop;
! 	char		aggkind;
  	const char *aggtranstype;
  	const char *aggtransspace;
  	const char *aggmtranstype;
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13464,13469 ****
--- 13469,13475 ----
  	const char *aggminitval;
  	bool		convertok;
  	const char *proparallel;
+ 	char		defaultfinalmodify;
  
  	/* Skip if not to be dumped */
  	if (!agginfo->aggfn.dobj.dump || dopt->dataOnly)
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13479,13493 ****
  	selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name);
  
  	/* Get aggregate-specific details */
! 	if (fout->remoteVersion >= 90600)
  	{
  		appendPQExpBuffer(query, "SELECT aggtransfn, "
  						  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
  						  "aggcombinefn, aggserialfn, aggdeserialfn, aggmtransfn, "
  						  "aggminvtransfn, aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
  						  "aggfinalextra, aggmfinalextra, "
  						  "aggsortop::pg_catalog.regoperator, "
! 						  "(aggkind = 'h') AS hypothetical, "
  						  "aggtransspace, agginitval, "
  						  "aggmtransspace, aggminitval, "
  						  "true AS convertok, "
--- 13485,13521 ----
  	selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name);
  
  	/* Get aggregate-specific details */
! 	if (fout->remoteVersion >= 110000)
  	{
  		appendPQExpBuffer(query, "SELECT aggtransfn, "
  						  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
  						  "aggcombinefn, aggserialfn, aggdeserialfn, aggmtransfn, "
  						  "aggminvtransfn, aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
  						  "aggfinalextra, aggmfinalextra, "
+ 						  "aggfinalmodify, aggmfinalmodify, "
  						  "aggsortop::pg_catalog.regoperator, "
! 						  "aggkind, "
! 						  "aggtransspace, agginitval, "
! 						  "aggmtransspace, aggminitval, "
! 						  "true AS convertok, "
! 						  "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs, "
! 						  "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs, "
! 						  "p.proparallel "
! 						  "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
! 						  "WHERE a.aggfnoid = p.oid "
! 						  "AND p.oid = '%u'::pg_catalog.oid",
! 						  agginfo->aggfn.dobj.catId.oid);
! 	}
! 	else if (fout->remoteVersion >= 90600)
! 	{
! 		appendPQExpBuffer(query, "SELECT aggtransfn, "
! 						  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
! 						  "aggcombinefn, aggserialfn, aggdeserialfn, aggmtransfn, "
! 						  "aggminvtransfn, aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
! 						  "aggfinalextra, aggmfinalextra, "
! 						  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
! 						  "aggsortop::pg_catalog.regoperator, "
! 						  "aggkind, "
  						  "aggtransspace, agginitval, "
  						  "aggmtransspace, aggminitval, "
  						  "true AS convertok, "
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13507,13514 ****
  						  "'-' AS aggdeserialfn, aggmtransfn, aggminvtransfn, "
  						  "aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
  						  "aggfinalextra, aggmfinalextra, "
  						  "aggsortop::pg_catalog.regoperator, "
! 						  "(aggkind = 'h') AS hypothetical, "
  						  "aggtransspace, agginitval, "
  						  "aggmtransspace, aggminitval, "
  						  "true AS convertok, "
--- 13535,13543 ----
  						  "'-' AS aggdeserialfn, aggmtransfn, aggminvtransfn, "
  						  "aggmfinalfn, aggmtranstype::pg_catalog.regtype, "
  						  "aggfinalextra, aggmfinalextra, "
+ 						  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
  						  "aggsortop::pg_catalog.regoperator, "
! 						  "aggkind, "
  						  "aggtransspace, agginitval, "
  						  "aggmtransspace, aggminitval, "
  						  "true AS convertok, "
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13528,13535 ****
  						  "'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
  						  "0 AS aggmtranstype, false AS aggfinalextra, "
  						  "false AS aggmfinalextra, "
  						  "aggsortop::pg_catalog.regoperator, "
! 						  "false AS hypothetical, "
  						  "0 AS aggtransspace, agginitval, "
  						  "0 AS aggmtransspace, NULL AS aggminitval, "
  						  "true AS convertok, "
--- 13557,13565 ----
  						  "'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
  						  "0 AS aggmtranstype, false AS aggfinalextra, "
  						  "false AS aggmfinalextra, "
+ 						  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
  						  "aggsortop::pg_catalog.regoperator, "
! 						  "'n' AS aggkind, "
  						  "0 AS aggtransspace, agginitval, "
  						  "0 AS aggmtransspace, NULL AS aggminitval, "
  						  "true AS convertok, "
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13549,13556 ****
  						  "'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
  						  "0 AS aggmtranstype, false AS aggfinalextra, "
  						  "false AS aggmfinalextra, "
  						  "aggsortop::pg_catalog.regoperator, "
! 						  "false AS hypothetical, "
  						  "0 AS aggtransspace, agginitval, "
  						  "0 AS aggmtransspace, NULL AS aggminitval, "
  						  "true AS convertok "
--- 13579,13587 ----
  						  "'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
  						  "0 AS aggmtranstype, false AS aggfinalextra, "
  						  "false AS aggmfinalextra, "
+ 						  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
  						  "aggsortop::pg_catalog.regoperator, "
! 						  "'n' AS aggkind, "
  						  "0 AS aggtransspace, agginitval, "
  						  "0 AS aggmtransspace, NULL AS aggminitval, "
  						  "true AS convertok "
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13567,13574 ****
  						  "'-' AS aggdeserialfn, '-' AS aggmtransfn, "
  						  "'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
  						  "0 AS aggmtranstype, false AS aggfinalextra, "
! 						  "false AS aggmfinalextra, 0 AS aggsortop, "
! 						  "false AS hypothetical, "
  						  "0 AS aggtransspace, agginitval, "
  						  "0 AS aggmtransspace, NULL AS aggminitval, "
  						  "true AS convertok "
--- 13598,13607 ----
  						  "'-' AS aggdeserialfn, '-' AS aggmtransfn, "
  						  "'-' AS aggminvtransfn, '-' AS aggmfinalfn, "
  						  "0 AS aggmtranstype, false AS aggfinalextra, "
! 						  "false AS aggmfinalextra, "
! 						  "'0' AS aggfinalmodify, '0' AS aggmfinalmodify, "
! 						  "0 AS aggsortop, "
! 						  "'n' AS aggkind, "
  						  "0 AS aggtransspace, agginitval, "
  						  "0 AS aggmtransspace, NULL AS aggminitval, "
  						  "true AS convertok "
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13590,13597 ****
  	i_aggmfinalfn = PQfnumber(res, "aggmfinalfn");
  	i_aggfinalextra = PQfnumber(res, "aggfinalextra");
  	i_aggmfinalextra = PQfnumber(res, "aggmfinalextra");
  	i_aggsortop = PQfnumber(res, "aggsortop");
! 	i_hypothetical = PQfnumber(res, "hypothetical");
  	i_aggtranstype = PQfnumber(res, "aggtranstype");
  	i_aggtransspace = PQfnumber(res, "aggtransspace");
  	i_aggmtranstype = PQfnumber(res, "aggmtranstype");
--- 13623,13632 ----
  	i_aggmfinalfn = PQfnumber(res, "aggmfinalfn");
  	i_aggfinalextra = PQfnumber(res, "aggfinalextra");
  	i_aggmfinalextra = PQfnumber(res, "aggmfinalextra");
+ 	i_aggfinalmodify = PQfnumber(res, "aggfinalmodify");
+ 	i_aggmfinalmodify = PQfnumber(res, "aggmfinalmodify");
  	i_aggsortop = PQfnumber(res, "aggsortop");
! 	i_aggkind = PQfnumber(res, "aggkind");
  	i_aggtranstype = PQfnumber(res, "aggtranstype");
  	i_aggtransspace = PQfnumber(res, "aggtransspace");
  	i_aggmtranstype = PQfnumber(res, "aggmtranstype");
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13611,13618 ****
  	aggmfinalfn = PQgetvalue(res, 0, i_aggmfinalfn);
  	aggfinalextra = (PQgetvalue(res, 0, i_aggfinalextra)[0] == 't');
  	aggmfinalextra = (PQgetvalue(res, 0, i_aggmfinalextra)[0] == 't');
  	aggsortop = PQgetvalue(res, 0, i_aggsortop);
! 	hypothetical = (PQgetvalue(res, 0, i_hypothetical)[0] == 't');
  	aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
  	aggtransspace = PQgetvalue(res, 0, i_aggtransspace);
  	aggmtranstype = PQgetvalue(res, 0, i_aggmtranstype);
--- 13646,13655 ----
  	aggmfinalfn = PQgetvalue(res, 0, i_aggmfinalfn);
  	aggfinalextra = (PQgetvalue(res, 0, i_aggfinalextra)[0] == 't');
  	aggmfinalextra = (PQgetvalue(res, 0, i_aggmfinalextra)[0] == 't');
+ 	aggfinalmodify = PQgetvalue(res, 0, i_aggfinalmodify)[0];
+ 	aggmfinalmodify = PQgetvalue(res, 0, i_aggmfinalmodify)[0];
  	aggsortop = PQgetvalue(res, 0, i_aggsortop);
! 	aggkind = PQgetvalue(res, 0, i_aggkind)[0];
  	aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
  	aggtransspace = PQgetvalue(res, 0, i_aggtransspace);
  	aggmtranstype = PQgetvalue(res, 0, i_aggmtranstype);
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13656,13661 ****
--- 13693,13706 ----
  		return;
  	}
  
+ 	/* identify default modify flag for aggkind (must match DefineAggregate) */
+ 	defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
+ 	/* replace omitted flags for old versions */
+ 	if (aggfinalmodify == '0')
+ 		aggfinalmodify = defaultfinalmodify;
+ 	if (aggmfinalmodify == '0')
+ 		aggmfinalmodify = defaultfinalmodify;
+ 
  	/* regproc and regtype output is already sufficiently quoted */
  	appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
  					  aggtransfn, aggtranstype);
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13678,13683 ****
--- 13723,13747 ----
  						  aggfinalfn);
  		if (aggfinalextra)
  			appendPQExpBufferStr(details, ",\n    FINALFUNC_EXTRA");
+ 		if (aggfinalmodify != defaultfinalmodify)
+ 		{
+ 			switch (aggfinalmodify)
+ 			{
+ 				case AGGMODIFY_READ_ONLY:
+ 					appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_ONLY");
+ 					break;
+ 				case AGGMODIFY_STOP_UPDATES:
+ 					appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = STOP_UPDATES");
+ 					break;
+ 				case AGGMODIFY_READ_WRITE:
+ 					appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_WRITE");
+ 					break;
+ 				default:
+ 					exit_horribly(NULL, "unrecognized aggfinalmodify value for aggregate \"%s\"\n",
+ 								  agginfo->aggfn.dobj.name);
+ 					break;
+ 			}
+ 		}
  	}
  
  	if (strcmp(aggcombinefn, "-") != 0)
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13715,13720 ****
--- 13779,13803 ----
  						  aggmfinalfn);
  		if (aggmfinalextra)
  			appendPQExpBufferStr(details, ",\n    MFINALFUNC_EXTRA");
+ 		if (aggmfinalmodify != defaultfinalmodify)
+ 		{
+ 			switch (aggmfinalmodify)
+ 			{
+ 				case AGGMODIFY_READ_ONLY:
+ 					appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_ONLY");
+ 					break;
+ 				case AGGMODIFY_STOP_UPDATES:
+ 					appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = STOP_UPDATES");
+ 					break;
+ 				case AGGMODIFY_READ_WRITE:
+ 					appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_WRITE");
+ 					break;
+ 				default:
+ 					exit_horribly(NULL, "unrecognized aggmfinalmodify value for aggregate \"%s\"\n",
+ 								  agginfo->aggfn.dobj.name);
+ 					break;
+ 			}
+ 		}
  	}
  
  	aggsortconvop = convertOperatorReference(fout, aggsortop);
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 13725,13731 ****
  		free(aggsortconvop);
  	}
  
! 	if (hypothetical)
  		appendPQExpBufferStr(details, ",\n    HYPOTHETICAL");
  
  	if (proparallel != NULL && proparallel[0] != PROPARALLEL_UNSAFE)
--- 13808,13814 ----
  		free(aggsortconvop);
  	}
  
! 	if (aggkind == AGGKIND_HYPOTHETICAL)
  		appendPQExpBufferStr(details, ",\n    HYPOTHETICAL");
  
  	if (proparallel != NULL && proparallel[0] != PROPARALLEL_UNSAFE)
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index c492fbd..df87fb5 100644
*** a/src/bin/pg_dump/t/002_pg_dump.pl
--- b/src/bin/pg_dump/t/002_pg_dump.pl
*************** qr/CREATE CAST \(timestamp with time zon
*** 2784,2789 ****
--- 2784,2790 ----
  						  basetype = int4,
  						  stype = _int8,
  						  finalfunc = int8_avg,
+ 						  finalfunc_modify = stop_updates,
  						  initcond1 = \'{0,0}\'
  					   );',
  		regexp => qr/^
*************** qr/CREATE CAST \(timestamp with time zon
*** 2791,2797 ****
  			\n\s+\QSFUNC = int4_avg_accum,\E
  			\n\s+\QSTYPE = bigint[],\E
  			\n\s+\QINITCOND = '{0,0}',\E
! 			\n\s+\QFINALFUNC = int8_avg\E
  			\n\);/xm,
  		like => {
  			binary_upgrade          => 1,
--- 2792,2799 ----
  			\n\s+\QSFUNC = int4_avg_accum,\E
  			\n\s+\QSTYPE = bigint[],\E
  			\n\s+\QINITCOND = '{0,0}',\E
! 			\n\s+\QFINALFUNC = int8_avg,\E
! 			\n\s+\QFINALFUNC_MODIFY = STOP_UPDATES\E
  			\n\);/xm,
  		like => {
  			binary_upgrade          => 1,
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 4d5b9bb..5fd68d3 100644
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 20,27 ****
  #define PG_AGGREGATE_H
  
  #include "catalog/genbki.h"
- #include "catalog/objectaddress.h"
- #include "nodes/pg_list.h"
  
  /* ----------------------------------------------------------------
   *		pg_aggregate definition.
--- 20,25 ----
***************
*** 41,46 ****
--- 39,46 ----
   *	aggmfinalfn			final function for moving-aggregate mode (0 if none)
   *	aggfinalextra		true to pass extra dummy arguments to aggfinalfn
   *	aggmfinalextra		true to pass extra dummy arguments to aggmfinalfn
+  *	aggfinalmodify		tells whether aggfinalfn modifies transition state
+  *	aggmfinalmodify		tells whether aggmfinalfn modifies transition state
   *	aggsortop			associated sort operator (0 if none)
   *	aggtranstype		type of aggregate's transition (state) data
   *	aggtransspace		estimated size of state data (0 for default estimate)
*************** CATALOG(pg_aggregate,2600) BKI_WITHOUT_O
*** 67,72 ****
--- 67,74 ----
  	regproc		aggmfinalfn;
  	bool		aggfinalextra;
  	bool		aggmfinalextra;
+ 	char		aggfinalmodify;
+ 	char		aggmfinalmodify;
  	Oid			aggsortop;
  	Oid			aggtranstype;
  	int32		aggtransspace;
*************** typedef FormData_pg_aggregate *Form_pg_a
*** 91,97 ****
   * ----------------
   */
  
! #define Natts_pg_aggregate					20
  #define Anum_pg_aggregate_aggfnoid			1
  #define Anum_pg_aggregate_aggkind			2
  #define Anum_pg_aggregate_aggnumdirectargs	3
--- 93,99 ----
   * ----------------
   */
  
! #define Natts_pg_aggregate					22
  #define Anum_pg_aggregate_aggfnoid			1
  #define Anum_pg_aggregate_aggkind			2
  #define Anum_pg_aggregate_aggnumdirectargs	3
*************** typedef FormData_pg_aggregate *Form_pg_a
*** 105,117 ****
  #define Anum_pg_aggregate_aggmfinalfn		11
  #define Anum_pg_aggregate_aggfinalextra		12
  #define Anum_pg_aggregate_aggmfinalextra	13
! #define Anum_pg_aggregate_aggsortop			14
! #define Anum_pg_aggregate_aggtranstype		15
! #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
--- 107,121 ----
  #define Anum_pg_aggregate_aggmfinalfn		11
  #define Anum_pg_aggregate_aggfinalextra		12
  #define Anum_pg_aggregate_aggmfinalextra	13
! #define Anum_pg_aggregate_aggfinalmodify	14
! #define Anum_pg_aggregate_aggmfinalmodify	15
! #define Anum_pg_aggregate_aggsortop			16
! #define Anum_pg_aggregate_aggtranstype		17
! #define Anum_pg_aggregate_aggtransspace		18
! #define Anum_pg_aggregate_aggmtranstype		19
! #define Anum_pg_aggregate_aggmtransspace	20
! #define Anum_pg_aggregate_agginitval		21
! #define Anum_pg_aggregate_aggminitval		22
  
  /*
   * Symbolic values for aggkind column.  We distinguish normal aggregates
*************** typedef FormData_pg_aggregate *Form_pg_a
*** 128,133 ****
--- 132,149 ----
  /* Use this macro to test for "ordered-set agg including hypothetical case" */
  #define AGGKIND_IS_ORDERED_SET(kind)  ((kind) != AGGKIND_NORMAL)
  
+ /*
+  * Symbolic values for aggfinalmodify and aggmfinalmodify columns.
+  * Preferably, finalfns do not modify the transition state value at all,
+  * but in some cases that would cost too much performance.  We distinguish
+  * "pure read only" and "trashes it arbitrarily" cases, as well as the
+  * intermediate case where the finalfn can be applied multiple times but
+  * the transfn cannot be applied anymore after the first finalfn call.
+  */
+ #define AGGMODIFY_READ_ONLY			'r'
+ #define AGGMODIFY_STOP_UPDATES		's'
+ #define AGGMODIFY_READ_WRITE		'w'
+ 
  
  /* ----------------
   * initial contents of pg_aggregate
*************** typedef FormData_pg_aggregate *Form_pg_a
*** 135,351 ****
   */
  
  /* 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	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	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	_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	_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	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	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	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	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	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	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	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" _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	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	_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	_null_ _null_ ));
  
  /* array */
! 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	_null_ _null_ ));
  
  /* bytea */
! 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	_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	_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	_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_ ));
! 
! 
! /*
!  * prototypes for functions in pg_aggregate.c
!  */
! extern ObjectAddress AggregateCreate(const char *aggName,
! 				Oid aggNamespace,
! 				char aggKind,
! 				int numArgs,
! 				int numDirectArgs,
! 				oidvector *parameterTypes,
! 				Datum allParameterTypes,
! 				Datum parameterModes,
! 				Datum parameterNames,
! 				List *parameterDefaults,
! 				Oid variadicArgType,
! 				List *aggtransfnName,
! 				List *aggfinalfnName,
! 				List *aggcombinefnName,
! 				List *aggserialfnName,
! 				List *aggdeserialfnName,
! 				List *aggmtransfnName,
! 				List *aggminvtransfnName,
! 				List *aggmfinalfnName,
! 				bool finalfnExtraArgs,
! 				bool mfinalfnExtraArgs,
! 				List *aggsortopName,
! 				Oid aggTransType,
! 				int32 aggTransSpace,
! 				Oid aggmTransType,
! 				int32 aggmTransSpace,
! 				const char *agginitval,
! 				const char *aggminitval,
! 				char proparallel);
  
  #endif							/* PG_AGGREGATE_H */
--- 151,333 ----
   */
  
  /* 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 r r 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 r r 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 r r 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 r r 0	2281	128 2281	128 _null_ _null_ ));
! DATA(insert ( 2104	n 0 float4_accum		float8_avg			float8_combine		-						-						-				-				-						f f r r 0	1022	0	0		0	"{0,0,0}" _null_ ));
! DATA(insert ( 2105	n 0 float8_accum		float8_avg			float8_combine		-						-						-				-				-						f f r r 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 r r 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 r r 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 r r 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 r r 0	20		0	1016	0	_null_ "{0,0}" ));
! DATA(insert ( 2110	n 0 float4pl			-					float4pl			-						-						-				-					-					f f r r 0	700		0	0		0	_null_ _null_ ));
! DATA(insert ( 2111	n 0 float8pl			-					float8pl			-						-						-				-					-					f f r r 0	701		0	0		0	_null_ _null_ ));
! DATA(insert ( 2112	n 0 cash_pl				-					cash_pl				-						-						cash_pl			cash_mi				-					f f r r 0	790		0	790		0	_null_ _null_ ));
! DATA(insert ( 2113	n 0 interval_pl			-					interval_pl			-						-						interval_pl		interval_mi			-					f f r r 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 r r 0	2281	128 2281	128 _null_ _null_ ));
  
  /* max */
! DATA(insert ( 2115	n 0 int8larger		-				int8larger			-	-	-				-				-				f f r r 413		20		0	0		0	_null_ _null_ ));
! DATA(insert ( 2116	n 0 int4larger		-				int4larger			-	-	-				-				-				f f r r 521		23		0	0		0	_null_ _null_ ));
! DATA(insert ( 2117	n 0 int2larger		-				int2larger			-	-	-				-				-				f f r r 520		21		0	0		0	_null_ _null_ ));
! DATA(insert ( 2118	n 0 oidlarger		-				oidlarger			-	-	-				-				-				f f r r 610		26		0	0		0	_null_ _null_ ));
! DATA(insert ( 2119	n 0 float4larger	-				float4larger		-	-	-				-				-				f f r r 623		700		0	0		0	_null_ _null_ ));
! DATA(insert ( 2120	n 0 float8larger	-				float8larger		-	-	-				-				-				f f r r 674		701		0	0		0	_null_ _null_ ));
! DATA(insert ( 2121	n 0 int4larger		-				int4larger			-	-	-				-				-				f f r r 563		702		0	0		0	_null_ _null_ ));
! DATA(insert ( 2122	n 0 date_larger		-				date_larger			-	-	-				-				-				f f r r 1097	1082	0	0		0	_null_ _null_ ));
! DATA(insert ( 2123	n 0 time_larger		-				time_larger			-	-	-				-				-				f f r r 1112	1083	0	0		0	_null_ _null_ ));
! DATA(insert ( 2124	n 0 timetz_larger	-				timetz_larger		-	-	-				-				-				f f r r 1554	1266	0	0		0	_null_ _null_ ));
! DATA(insert ( 2125	n 0 cashlarger		-				cashlarger			-	-	-				-				-				f f r r 903		790		0	0		0	_null_ _null_ ));
! DATA(insert ( 2126	n 0 timestamp_larger	-			timestamp_larger	-	-	-				-				-				f f r r 2064	1114	0	0		0	_null_ _null_ ));
! DATA(insert ( 2127	n 0 timestamptz_larger	-			timestamptz_larger	-	-	-				-				-				f f r r 1324	1184	0	0		0	_null_ _null_ ));
! DATA(insert ( 2128	n 0 interval_larger -				interval_larger		-	-	-				-				-				f f r r 1334	1186	0	0		0	_null_ _null_ ));
! DATA(insert ( 2129	n 0 text_larger		-				text_larger			-	-	-				-				-				f f r r 666		25		0	0		0	_null_ _null_ ));
! DATA(insert ( 2130	n 0 numeric_larger	-				numeric_larger		-	-	-				-				-				f f r r 1756	1700	0	0		0	_null_ _null_ ));
! DATA(insert ( 2050	n 0 array_larger	-				array_larger		-	-	-				-				-				f f r r 1073	2277	0	0		0	_null_ _null_ ));
! DATA(insert ( 2244	n 0 bpchar_larger	-				bpchar_larger		-	-	-				-				-				f f r r 1060	1042	0	0		0	_null_ _null_ ));
! DATA(insert ( 2797	n 0 tidlarger		-				tidlarger			-	-	-				-				-				f f r r 2800	27		0	0		0	_null_ _null_ ));
! DATA(insert ( 3526	n 0 enum_larger		-				enum_larger			-	-	-				-				-				f f r r 3519	3500	0	0		0	_null_ _null_ ));
! DATA(insert ( 3564	n 0 network_larger	-				network_larger		-	-	-				-				-				f f r r 1205	869		0	0		0	_null_ _null_ ));
  
  /* min */
! DATA(insert ( 2131	n 0 int8smaller		-				int8smaller			-	-	-				-				-				f f r r 412		20		0	0		0	_null_ _null_ ));
! DATA(insert ( 2132	n 0 int4smaller		-				int4smaller			-	-	-				-				-				f f r r 97		23		0	0		0	_null_ _null_ ));
! DATA(insert ( 2133	n 0 int2smaller		-				int2smaller			-	-	-				-				-				f f r r 95		21		0	0		0	_null_ _null_ ));
! DATA(insert ( 2134	n 0 oidsmaller		-				oidsmaller			-	-	-				-				-				f f r r 609		26		0	0		0	_null_ _null_ ));
! DATA(insert ( 2135	n 0 float4smaller	-				float4smaller		-	-	-				-				-				f f r r 622		700		0	0		0	_null_ _null_ ));
! DATA(insert ( 2136	n 0 float8smaller	-				float8smaller		-	-	-				-				-				f f r r 672		701		0	0		0	_null_ _null_ ));
! DATA(insert ( 2137	n 0 int4smaller		-				int4smaller			-	-	-				-				-				f f r r 562		702		0	0		0	_null_ _null_ ));
! DATA(insert ( 2138	n 0 date_smaller	-				date_smaller		-	-	-				-				-				f f r r 1095	1082	0	0		0	_null_ _null_ ));
! DATA(insert ( 2139	n 0 time_smaller	-				time_smaller		-	-	-				-				-				f f r r 1110	1083	0	0		0	_null_ _null_ ));
! DATA(insert ( 2140	n 0 timetz_smaller	-				timetz_smaller		-	-	-				-				-				f f r r 1552	1266	0	0		0	_null_ _null_ ));
! DATA(insert ( 2141	n 0 cashsmaller		-				cashsmaller			-	-	-				-				-				f f r r 902		790		0	0		0	_null_ _null_ ));
! DATA(insert ( 2142	n 0 timestamp_smaller	-			timestamp_smaller	-	-	-				-				-				f f r r 2062	1114	0	0		0	_null_ _null_ ));
! DATA(insert ( 2143	n 0 timestamptz_smaller -			timestamptz_smaller -	-	-				-				-				f f r r 1322	1184	0	0		0	_null_ _null_ ));
! DATA(insert ( 2144	n 0 interval_smaller	-			interval_smaller	-	-	-				-				-				f f r r 1332	1186	0	0		0	_null_ _null_ ));
! DATA(insert ( 2145	n 0 text_smaller	-				text_smaller		-	-	-				-				-				f f r r 664		25		0	0		0	_null_ _null_ ));
! DATA(insert ( 2146	n 0 numeric_smaller -				numeric_smaller		-	-	-				-				-				f f r r 1754	1700	0	0		0	_null_ _null_ ));
! DATA(insert ( 2051	n 0 array_smaller	-				array_smaller		-	-	-				-				-				f f r r 1072	2277	0	0		0	_null_ _null_ ));
! DATA(insert ( 2245	n 0 bpchar_smaller	-				bpchar_smaller		-	-	-				-				-				f f r r 1058	1042	0	0		0	_null_ _null_ ));
! DATA(insert ( 2798	n 0 tidsmaller		-				tidsmaller			-	-	-				-				-				f f r r 2799	27		0	0		0	_null_ _null_ ));
! DATA(insert ( 3527	n 0 enum_smaller	-				enum_smaller		-	-	-				-				-				f f r r 3518	3500	0	0		0	_null_ _null_ ));
! DATA(insert ( 3565	n 0 network_smaller -				network_smaller		-	-	-				-				-				f f r r 1203	869		0	0		0	_null_ _null_ ));
  
  /* count */
! DATA(insert ( 2147	n 0 int8inc_any		-				int8pl	-	-	int8inc_any		int8dec_any		-				f f r r 0		20		0	20		0	"0" "0" ));
! DATA(insert ( 2803	n 0 int8inc			-				int8pl	-	-	int8inc			int8dec			-				f f r r 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 r r 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 r r 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 r r 0	2281	48	2281	48	_null_ _null_ ));
! DATA(insert ( 2721	n 0 float4_accum	float8_var_pop			float8_combine			-						-							-				-				-						f f r r 0	1022	0	0		0	"{0,0,0}" _null_ ));
! DATA(insert ( 2722	n 0 float8_accum	float8_var_pop			float8_combine			-						-							-				-				-						f f r r 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 r r 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 r r 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 r r 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 r r 0	2281	48	2281	48	_null_ _null_ ));
! DATA(insert ( 2644	n 0 float4_accum	float8_var_samp			float8_combine			-						-							-				-				-						f f r r 0	1022	0	0		0	"{0,0,0}" _null_ ));
! DATA(insert ( 2645	n 0 float8_accum	float8_var_samp			float8_combine			-						-							-				-				-						f f r r 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 r r 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 r r 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 r r 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 r r 0	2281	48	2281	48	_null_ _null_ ));
! DATA(insert ( 2151	n 0 float4_accum	float8_var_samp			float8_combine			-						-							-				-				-						f f r r 0	1022	0	0		0	"{0,0,0}" _null_ ));
! DATA(insert ( 2152	n 0 float8_accum	float8_var_samp			float8_combine			-						-							-				-				-						f f r r 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 r r 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 r r 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 r r 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 r r 0	2281	48	2281	48	_null_ _null_ ));
! DATA(insert ( 2727	n 0 float4_accum	float8_stddev_pop		float8_combine			-						-							-				-				-						f f r r 0	1022	0	0		0	"{0,0,0}" _null_ ));
! DATA(insert ( 2728	n 0 float8_accum	float8_stddev_pop		float8_combine			-						-							-				-				-						f f r r 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 r r 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 r r 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 r r 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 r r 0	2281	48	2281	48	_null_ _null_ ));
! DATA(insert ( 2715	n 0 float4_accum	float8_stddev_samp			float8_combine			-						-							-			-				-							f f r r 0	1022	0	0		0	"{0,0,0}" _null_ ));
! DATA(insert ( 2716	n 0 float8_accum	float8_stddev_samp			float8_combine			-						-							-			-				-							f f r r 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 r r 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 r r 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 r r 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 r r 0	2281	48	2281	48	_null_ _null_ ));
! DATA(insert ( 2157	n 0 float4_accum	float8_stddev_samp			float8_combine			-						-							-				-				-							f f r r 0	1022	0	0		0	"{0,0,0}" _null_ ));
! DATA(insert ( 2158	n 0 float8_accum	float8_stddev_samp			float8_combine			-						-							-				-				-							f f r r 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 r r 0	2281	128 2281	128 _null_ _null_ ));
  
  /* SQL2003 binary regression aggregates */
! DATA(insert ( 2818	n 0 int8inc_float8_float8	-					int8pl				-	-	-				-				-			f f r r 0	20		0	0		0	"0" _null_ ));
! DATA(insert ( 2819	n 0 float8_regr_accum	float8_regr_sxx			float8_regr_combine -	-	-				-				-			f f r r 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 r r 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 r r 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 r r 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 r r 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 r r 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 r r 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 r r 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 r r 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 r r 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 r r 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 r r 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 r r 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 r r 58	16	0	2281	16	_null_ _null_ ));
  
  /* bitwise integer */
! DATA(insert ( 2236	n 0 int2and		-				int2and -	-	-				-				-				f f r r 0	21		0	0		0	_null_ _null_ ));
! DATA(insert ( 2237	n 0 int2or		-				int2or	-	-	-				-				-				f f r r 0	21		0	0		0	_null_ _null_ ));
! DATA(insert ( 2238	n 0 int4and		-				int4and -	-	-				-				-				f f r r 0	23		0	0		0	_null_ _null_ ));
! DATA(insert ( 2239	n 0 int4or		-				int4or	-	-	-				-				-				f f r r 0	23		0	0		0	_null_ _null_ ));
! DATA(insert ( 2240	n 0 int8and		-				int8and -	-	-				-				-				f f r r 0	20		0	0		0	_null_ _null_ ));
! DATA(insert ( 2241	n 0 int8or		-				int8or	-	-	-				-				-				f f r r 0	20		0	0		0	_null_ _null_ ));
! DATA(insert ( 2242	n 0 bitand		-				bitand	-	-	-				-				-				f f r r 0	1560	0	0		0	_null_ _null_ ));
! DATA(insert ( 2243	n 0 bitor		-				bitor	-	-	-				-				-				f f r r 0	1560	0	0		0	_null_ _null_ ));
  
  /* xml */
! DATA(insert ( 2901	n 0 xmlconcat2	-				-		-	-	-				-				-				f f r r 0	142		0	0		0	_null_ _null_ ));
  
  /* array */
! DATA(insert ( 2335	n 0 array_agg_transfn		array_agg_finalfn		-	-	-	-		-				-				t f r r 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 4053	n 0 array_agg_array_transfn array_agg_array_finalfn -	-	-	-		-				-				t f r r 0	2281	0	0		0	_null_ _null_ ));
  
  /* text */
! DATA(insert ( 3538	n 0 string_agg_transfn	string_agg_finalfn	-	-	-	-				-				-				f f r r 0	2281	0	0		0	_null_ _null_ ));
  
  /* bytea */
! DATA(insert ( 3545	n 0 bytea_string_agg_transfn	bytea_string_agg_finalfn	-	-	-	-				-				-		f f r r 0	2281	0	0		0	_null_ _null_ ));
  
  /* json */
! DATA(insert ( 3175	n 0 json_agg_transfn	json_agg_finalfn			-	-	-	-				-				-				f f r r 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3197	n 0 json_object_agg_transfn json_object_agg_finalfn -	-	-	-				-				-				f f r r 0	2281	0	0		0	_null_ _null_ ));
  
  /* jsonb */
! DATA(insert ( 3267	n 0 jsonb_agg_transfn	jsonb_agg_finalfn				-	-	-	-				-				-			f f r r 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3270	n 0 jsonb_object_agg_transfn jsonb_object_agg_finalfn	-	-	-	-				-				-			f f r r 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 w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3974	o 1 ordered_set_transition			percentile_cont_float8_final			-	-	-	-		-		-		f f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3976	o 1 ordered_set_transition			percentile_cont_interval_final			-	-	-	-		-		-		f f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3978	o 1 ordered_set_transition			percentile_disc_multi_final				-	-	-	-		-		-		t f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3980	o 1 ordered_set_transition			percentile_cont_float8_multi_final		-	-	-	-		-		-		f f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3982	o 1 ordered_set_transition			percentile_cont_interval_multi_final	-	-	-	-		-		-		f f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3984	o 0 ordered_set_transition			mode_final								-	-	-	-		-		-		t f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3986	h 1 ordered_set_transition_multi	rank_final								-	-	-	-		-		-		t f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3988	h 1 ordered_set_transition_multi	percent_rank_final						-	-	-	-		-		-		t f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3990	h 1 ordered_set_transition_multi	cume_dist_final							-	-	-	-		-		-		t f w w 0	2281	0	0		0	_null_ _null_ ));
! DATA(insert ( 3992	h 1 ordered_set_transition_multi	dense_rank_final						-	-	-	-		-		-		t f w w 0	2281	0	0		0	_null_ _null_ ));
  
  #endif							/* PG_AGGREGATE_H */
diff --git a/src/include/catalog/pg_aggregate_fn.h b/src/include/catalog/pg_aggregate_fn.h
index ...a323aab .
*** a/src/include/catalog/pg_aggregate_fn.h
--- b/src/include/catalog/pg_aggregate_fn.h
***************
*** 0 ****
--- 1,52 ----
+ /*-------------------------------------------------------------------------
+  *
+  * pg_aggregate_fn.h
+  *	  prototypes for functions in catalog/pg_aggregate.c
+  *
+  *
+  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * src/include/catalog/pg_aggregate_fn.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef PG_AGGREGATE_FN_H
+ #define PG_AGGREGATE_FN_H
+ 
+ #include "catalog/objectaddress.h"
+ #include "nodes/pg_list.h"
+ 
+ extern ObjectAddress AggregateCreate(const char *aggName,
+ 				Oid aggNamespace,
+ 				char aggKind,
+ 				int numArgs,
+ 				int numDirectArgs,
+ 				oidvector *parameterTypes,
+ 				Datum allParameterTypes,
+ 				Datum parameterModes,
+ 				Datum parameterNames,
+ 				List *parameterDefaults,
+ 				Oid variadicArgType,
+ 				List *aggtransfnName,
+ 				List *aggfinalfnName,
+ 				List *aggcombinefnName,
+ 				List *aggserialfnName,
+ 				List *aggdeserialfnName,
+ 				List *aggmtransfnName,
+ 				List *aggminvtransfnName,
+ 				List *aggmfinalfnName,
+ 				bool finalfnExtraArgs,
+ 				bool mfinalfnExtraArgs,
+ 				char finalfnModify,
+ 				char mfinalfnModify,
+ 				List *aggsortopName,
+ 				Oid aggTransType,
+ 				int32 aggTransSpace,
+ 				Oid aggmTransType,
+ 				int32 aggmTransSpace,
+ 				const char *agginitval,
+ 				const char *aggminitval,
+ 				char proparallel);
+ 
+ #endif							/* PG_AGGREGATE_FN_H */
diff --git a/src/test/regress/expected/create_aggregate.out b/src/test/regress/expected/create_aggregate.out
index 341ba52..723d0b1 100644
*** a/src/test/regress/expected/create_aggregate.out
--- b/src/test/regress/expected/create_aggregate.out
*************** create aggregate my_percentile_disc(floa
*** 71,77 ****
    stype = internal,
    sfunc = ordered_set_transition,
    finalfunc = percentile_disc_final,
!   finalfunc_extra = true
  );
  create aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") (
    stype = internal,
--- 71,78 ----
    stype = internal,
    sfunc = ordered_set_transition,
    finalfunc = percentile_disc_final,
!   finalfunc_extra = true,
!   finalfunc_modify = read_write
  );
  create aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") (
    stype = internal,
*************** CREATE AGGREGATE myavg (numeric)
*** 146,160 ****
  	finalfunc = numeric_avg,
  	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
  FROM pg_aggregate
  WHERE aggfnoid = 'myavg'::REGPROC;
!  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);
--- 147,163 ----
  	finalfunc = numeric_avg,
  	serialfunc = numeric_avg_serialize,
  	deserialfunc = numeric_avg_deserialize,
! 	combinefunc = numeric_avg_combine,
! 	finalfunc_modify = stop_updates  -- just to test a non-default setting
  );
  -- Ensure all these functions made it into the catalog
! SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype,
!        aggserialfn, aggdeserialfn, aggfinalmodify
  FROM pg_aggregate
  WHERE aggfnoid = 'myavg'::REGPROC;
!  aggfnoid |    aggtransfn     |    aggcombinefn     | aggtranstype |      aggserialfn      |      aggdeserialfn      | aggfinalmodify 
! ----------+-------------------+---------------------+--------------+-----------------------+-------------------------+----------------
!  myavg    | numeric_avg_accum | numeric_avg_combine | internal     | numeric_avg_serialize | numeric_avg_deserialize | s
  (1 row)
  
  DROP AGGREGATE myavg (numeric);
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index fcf8bd7..684f7f2 100644
*** a/src/test/regress/expected/opr_sanity.out
--- b/src/test/regress/expected/opr_sanity.out
*************** WHERE aggfnoid = 0 OR aggtransfn = 0 OR
*** 1275,1280 ****
--- 1275,1282 ----
      aggkind NOT IN ('n', 'o', 'h') OR
      aggnumdirectargs < 0 OR
      (aggkind = 'n' AND aggnumdirectargs > 0) OR
+     aggfinalmodify NOT IN ('r', 's', 'w') OR
+     aggmfinalmodify NOT IN ('r', 's', 'w') OR
      aggtranstype = 0 OR aggtransspace < 0 OR aggmtransspace < 0;
   ctid | aggfnoid 
  ------+----------
diff --git a/src/test/regress/sql/create_aggregate.sql b/src/test/regress/sql/create_aggregate.sql
index ae3a6c0..6e3651c 100644
*** a/src/test/regress/sql/create_aggregate.sql
--- b/src/test/regress/sql/create_aggregate.sql
*************** create aggregate my_percentile_disc(floa
*** 86,92 ****
    stype = internal,
    sfunc = ordered_set_transition,
    finalfunc = percentile_disc_final,
!   finalfunc_extra = true
  );
  
  create aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") (
--- 86,93 ----
    stype = internal,
    sfunc = ordered_set_transition,
    finalfunc = percentile_disc_final,
!   finalfunc_extra = true,
!   finalfunc_modify = read_write
  );
  
  create aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") (
*************** CREATE AGGREGATE myavg (numeric)
*** 161,171 ****
  	finalfunc = numeric_avg,
  	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
  FROM pg_aggregate
  WHERE aggfnoid = 'myavg'::REGPROC;
  
--- 162,174 ----
  	finalfunc = numeric_avg,
  	serialfunc = numeric_avg_serialize,
  	deserialfunc = numeric_avg_deserialize,
! 	combinefunc = numeric_avg_combine,
! 	finalfunc_modify = stop_updates  -- just to test a non-default setting
  );
  
  -- Ensure all these functions made it into the catalog
! SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype,
!        aggserialfn, aggdeserialfn, aggfinalmodify
  FROM pg_aggregate
  WHERE aggfnoid = 'myavg'::REGPROC;
  
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index 2945966..e8fdf84 100644
*** a/src/test/regress/sql/opr_sanity.sql
--- b/src/test/regress/sql/opr_sanity.sql
*************** WHERE aggfnoid = 0 OR aggtransfn = 0 OR
*** 795,800 ****
--- 795,802 ----
      aggkind NOT IN ('n', 'o', 'h') OR
      aggnumdirectargs < 0 OR
      (aggkind = 'n' AND aggnumdirectargs > 0) OR
+     aggfinalmodify NOT IN ('r', 's', 'w') OR
+     aggmfinalmodify NOT IN ('r', 's', 'w') OR
      aggtranstype = 0 OR aggtransspace < 0 OR aggmtransspace < 0;
  
  -- Make sure the matching pg_proc entry is sensible, too.
