1 /*-------------------------------------------------------------------------
2  *
3  * pg_aggregate.c
4  *	  routines to support manipulation of the pg_aggregate relation
5  *
6  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/backend/catalog/pg_aggregate.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "access/htup_details.h"
18 #include "access/table.h"
19 #include "catalog/dependency.h"
20 #include "catalog/indexing.h"
21 #include "catalog/pg_aggregate.h"
22 #include "catalog/pg_language.h"
23 #include "catalog/pg_operator.h"
24 #include "catalog/pg_proc.h"
25 #include "catalog/pg_type.h"
26 #include "miscadmin.h"
27 #include "parser/parse_coerce.h"
28 #include "parser/parse_func.h"
29 #include "parser/parse_oper.h"
30 #include "utils/acl.h"
31 #include "utils/builtins.h"
32 #include "utils/lsyscache.h"
33 #include "utils/rel.h"
34 #include "utils/syscache.h"
35 
36 
37 static Oid	lookup_agg_function(List *fnName, int nargs, Oid *input_types,
38 								Oid variadicArgType,
39 								Oid *rettype);
40 
41 
42 /*
43  * AggregateCreate
44  */
45 ObjectAddress
AggregateCreate(const char * aggName,Oid aggNamespace,bool replace,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)46 AggregateCreate(const char *aggName,
47 				Oid aggNamespace,
48 				bool replace,
49 				char aggKind,
50 				int numArgs,
51 				int numDirectArgs,
52 				oidvector *parameterTypes,
53 				Datum allParameterTypes,
54 				Datum parameterModes,
55 				Datum parameterNames,
56 				List *parameterDefaults,
57 				Oid variadicArgType,
58 				List *aggtransfnName,
59 				List *aggfinalfnName,
60 				List *aggcombinefnName,
61 				List *aggserialfnName,
62 				List *aggdeserialfnName,
63 				List *aggmtransfnName,
64 				List *aggminvtransfnName,
65 				List *aggmfinalfnName,
66 				bool finalfnExtraArgs,
67 				bool mfinalfnExtraArgs,
68 				char finalfnModify,
69 				char mfinalfnModify,
70 				List *aggsortopName,
71 				Oid aggTransType,
72 				int32 aggTransSpace,
73 				Oid aggmTransType,
74 				int32 aggmTransSpace,
75 				const char *agginitval,
76 				const char *aggminitval,
77 				char proparallel)
78 {
79 	Relation	aggdesc;
80 	HeapTuple	tup;
81 	HeapTuple	oldtup;
82 	bool		nulls[Natts_pg_aggregate];
83 	Datum		values[Natts_pg_aggregate];
84 	bool		replaces[Natts_pg_aggregate];
85 	Form_pg_proc proc;
86 	Oid			transfn;
87 	Oid			finalfn = InvalidOid;	/* can be omitted */
88 	Oid			combinefn = InvalidOid; /* can be omitted */
89 	Oid			serialfn = InvalidOid;	/* can be omitted */
90 	Oid			deserialfn = InvalidOid;	/* can be omitted */
91 	Oid			mtransfn = InvalidOid;	/* can be omitted */
92 	Oid			minvtransfn = InvalidOid;	/* can be omitted */
93 	Oid			mfinalfn = InvalidOid;	/* can be omitted */
94 	Oid			sortop = InvalidOid;	/* can be omitted */
95 	Oid		   *aggArgTypes = parameterTypes->values;
96 	bool		mtransIsStrict = false;
97 	Oid			rettype;
98 	Oid			finaltype;
99 	Oid			fnArgs[FUNC_MAX_ARGS];
100 	int			nargs_transfn;
101 	int			nargs_finalfn;
102 	Oid			procOid;
103 	TupleDesc	tupDesc;
104 	char	   *detailmsg;
105 	int			i;
106 	ObjectAddress myself,
107 				referenced;
108 	AclResult	aclresult;
109 
110 	/* sanity checks (caller should have caught these) */
111 	if (!aggName)
112 		elog(ERROR, "no aggregate name supplied");
113 
114 	if (!aggtransfnName)
115 		elog(ERROR, "aggregate must have a transition function");
116 
117 	if (numDirectArgs < 0 || numDirectArgs > numArgs)
118 		elog(ERROR, "incorrect number of direct arguments for aggregate");
119 
120 	/*
121 	 * Aggregates can have at most FUNC_MAX_ARGS-1 args, else the transfn
122 	 * and/or finalfn will be unrepresentable in pg_proc.  We must check now
123 	 * to protect fixed-size arrays here and possibly in called functions.
124 	 */
125 	if (numArgs < 0 || numArgs > FUNC_MAX_ARGS - 1)
126 		ereport(ERROR,
127 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
128 				 errmsg_plural("aggregates cannot have more than %d argument",
129 							   "aggregates cannot have more than %d arguments",
130 							   FUNC_MAX_ARGS - 1,
131 							   FUNC_MAX_ARGS - 1)));
132 
133 	/*
134 	 * If transtype is polymorphic, must have polymorphic argument also; else
135 	 * we will have no way to deduce the actual transtype.
136 	 */
137 	detailmsg = check_valid_polymorphic_signature(aggTransType,
138 												  aggArgTypes,
139 												  numArgs);
140 	if (detailmsg)
141 		ereport(ERROR,
142 				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
143 				 errmsg("cannot determine transition data type"),
144 				 errdetail_internal("%s", detailmsg)));
145 
146 	/*
147 	 * Likewise for moving-aggregate transtype, if any
148 	 */
149 	if (OidIsValid(aggmTransType))
150 	{
151 		detailmsg = check_valid_polymorphic_signature(aggmTransType,
152 													  aggArgTypes,
153 													  numArgs);
154 		if (detailmsg)
155 			ereport(ERROR,
156 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
157 					 errmsg("cannot determine transition data type"),
158 					 errdetail_internal("%s", detailmsg)));
159 	}
160 
161 	/*
162 	 * An ordered-set aggregate that is VARIADIC must be VARIADIC ANY.  In
163 	 * principle we could support regular variadic types, but it would make
164 	 * things much more complicated because we'd have to assemble the correct
165 	 * subsets of arguments into array values.  Since no standard aggregates
166 	 * have use for such a case, we aren't bothering for now.
167 	 */
168 	if (AGGKIND_IS_ORDERED_SET(aggKind) && OidIsValid(variadicArgType) &&
169 		variadicArgType != ANYOID)
170 		ereport(ERROR,
171 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
172 				 errmsg("a variadic ordered-set aggregate must use VARIADIC type ANY")));
173 
174 	/*
175 	 * If it's a hypothetical-set aggregate, there must be at least as many
176 	 * direct arguments as aggregated ones, and the last N direct arguments
177 	 * must match the aggregated ones in type.  (We have to check this again
178 	 * when the aggregate is called, in case ANY is involved, but it makes
179 	 * sense to reject the aggregate definition now if the declared arg types
180 	 * don't match up.)  It's unconditionally OK if numDirectArgs == numArgs,
181 	 * indicating that the grammar merged identical VARIADIC entries from both
182 	 * lists.  Otherwise, if the agg is VARIADIC, then we had VARIADIC only on
183 	 * the aggregated side, which is not OK.  Otherwise, insist on the last N
184 	 * parameter types on each side matching exactly.
185 	 */
186 	if (aggKind == AGGKIND_HYPOTHETICAL &&
187 		numDirectArgs < numArgs)
188 	{
189 		int			numAggregatedArgs = numArgs - numDirectArgs;
190 
191 		if (OidIsValid(variadicArgType) ||
192 			numDirectArgs < numAggregatedArgs ||
193 			memcmp(aggArgTypes + (numDirectArgs - numAggregatedArgs),
194 				   aggArgTypes + numDirectArgs,
195 				   numAggregatedArgs * sizeof(Oid)) != 0)
196 			ereport(ERROR,
197 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
198 					 errmsg("a hypothetical-set aggregate must have direct arguments matching its aggregated arguments")));
199 	}
200 
201 	/*
202 	 * Find the transfn.  For ordinary aggs, it takes the transtype plus all
203 	 * aggregate arguments.  For ordered-set aggs, it takes the transtype plus
204 	 * all aggregated args, but not direct args.  However, we have to treat
205 	 * specially the case where a trailing VARIADIC item is considered to
206 	 * cover both direct and aggregated args.
207 	 */
208 	if (AGGKIND_IS_ORDERED_SET(aggKind))
209 	{
210 		if (numDirectArgs < numArgs)
211 			nargs_transfn = numArgs - numDirectArgs + 1;
212 		else
213 		{
214 			/* special case with VARIADIC last arg */
215 			Assert(variadicArgType != InvalidOid);
216 			nargs_transfn = 2;
217 		}
218 		fnArgs[0] = aggTransType;
219 		memcpy(fnArgs + 1, aggArgTypes + (numArgs - (nargs_transfn - 1)),
220 			   (nargs_transfn - 1) * sizeof(Oid));
221 	}
222 	else
223 	{
224 		nargs_transfn = numArgs + 1;
225 		fnArgs[0] = aggTransType;
226 		memcpy(fnArgs + 1, aggArgTypes, numArgs * sizeof(Oid));
227 	}
228 	transfn = lookup_agg_function(aggtransfnName, nargs_transfn,
229 								  fnArgs, variadicArgType,
230 								  &rettype);
231 
232 	/*
233 	 * Return type of transfn (possibly after refinement by
234 	 * enforce_generic_type_consistency, if transtype isn't polymorphic) must
235 	 * exactly match declared transtype.
236 	 *
237 	 * In the non-polymorphic-transtype case, it might be okay to allow a
238 	 * rettype that's binary-coercible to transtype, but I'm not quite
239 	 * convinced that it's either safe or useful.  When transtype is
240 	 * polymorphic we *must* demand exact equality.
241 	 */
242 	if (rettype != aggTransType)
243 		ereport(ERROR,
244 				(errcode(ERRCODE_DATATYPE_MISMATCH),
245 				 errmsg("return type of transition function %s is not %s",
246 						NameListToString(aggtransfnName),
247 						format_type_be(aggTransType))));
248 
249 	tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(transfn));
250 	if (!HeapTupleIsValid(tup))
251 		elog(ERROR, "cache lookup failed for function %u", transfn);
252 	proc = (Form_pg_proc) GETSTRUCT(tup);
253 
254 	/*
255 	 * If the transfn is strict and the initval is NULL, make sure first input
256 	 * type and transtype are the same (or at least binary-compatible), so
257 	 * that it's OK to use the first input value as the initial transValue.
258 	 */
259 	if (proc->proisstrict && agginitval == NULL)
260 	{
261 		if (numArgs < 1 ||
262 			!IsBinaryCoercible(aggArgTypes[0], aggTransType))
263 			ereport(ERROR,
264 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
265 					 errmsg("must not omit initial value when transition function is strict and transition type is not compatible with input type")));
266 	}
267 
268 	ReleaseSysCache(tup);
269 
270 	/* handle moving-aggregate transfn, if supplied */
271 	if (aggmtransfnName)
272 	{
273 		/*
274 		 * The arguments are the same as for the regular transfn, except that
275 		 * the transition data type might be different.  So re-use the fnArgs
276 		 * values set up above, except for that one.
277 		 */
278 		Assert(OidIsValid(aggmTransType));
279 		fnArgs[0] = aggmTransType;
280 
281 		mtransfn = lookup_agg_function(aggmtransfnName, nargs_transfn,
282 									   fnArgs, variadicArgType,
283 									   &rettype);
284 
285 		/* As above, return type must exactly match declared mtranstype. */
286 		if (rettype != aggmTransType)
287 			ereport(ERROR,
288 					(errcode(ERRCODE_DATATYPE_MISMATCH),
289 					 errmsg("return type of transition function %s is not %s",
290 							NameListToString(aggmtransfnName),
291 							format_type_be(aggmTransType))));
292 
293 		tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(mtransfn));
294 		if (!HeapTupleIsValid(tup))
295 			elog(ERROR, "cache lookup failed for function %u", mtransfn);
296 		proc = (Form_pg_proc) GETSTRUCT(tup);
297 
298 		/*
299 		 * If the mtransfn is strict and the minitval is NULL, check first
300 		 * input type and mtranstype are binary-compatible.
301 		 */
302 		if (proc->proisstrict && aggminitval == NULL)
303 		{
304 			if (numArgs < 1 ||
305 				!IsBinaryCoercible(aggArgTypes[0], aggmTransType))
306 				ereport(ERROR,
307 						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
308 						 errmsg("must not omit initial value when transition function is strict and transition type is not compatible with input type")));
309 		}
310 
311 		/* Remember if mtransfn is strict; we may need this below */
312 		mtransIsStrict = proc->proisstrict;
313 
314 		ReleaseSysCache(tup);
315 	}
316 
317 	/* handle minvtransfn, if supplied */
318 	if (aggminvtransfnName)
319 	{
320 		/*
321 		 * This must have the same number of arguments with the same types as
322 		 * the forward transition function, so just re-use the fnArgs data.
323 		 */
324 		Assert(aggmtransfnName);
325 
326 		minvtransfn = lookup_agg_function(aggminvtransfnName, nargs_transfn,
327 										  fnArgs, variadicArgType,
328 										  &rettype);
329 
330 		/* As above, return type must exactly match declared mtranstype. */
331 		if (rettype != aggmTransType)
332 			ereport(ERROR,
333 					(errcode(ERRCODE_DATATYPE_MISMATCH),
334 					 errmsg("return type of inverse transition function %s is not %s",
335 							NameListToString(aggminvtransfnName),
336 							format_type_be(aggmTransType))));
337 
338 		tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(minvtransfn));
339 		if (!HeapTupleIsValid(tup))
340 			elog(ERROR, "cache lookup failed for function %u", minvtransfn);
341 		proc = (Form_pg_proc) GETSTRUCT(tup);
342 
343 		/*
344 		 * We require the strictness settings of the forward and inverse
345 		 * transition functions to agree.  This saves having to handle
346 		 * assorted special cases at execution time.
347 		 */
348 		if (proc->proisstrict != mtransIsStrict)
349 			ereport(ERROR,
350 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
351 					 errmsg("strictness of aggregate's forward and inverse transition functions must match")));
352 
353 		ReleaseSysCache(tup);
354 	}
355 
356 	/* handle finalfn, if supplied */
357 	if (aggfinalfnName)
358 	{
359 		/*
360 		 * If finalfnExtraArgs is specified, the transfn takes the transtype
361 		 * plus all args; otherwise, it just takes the transtype plus any
362 		 * direct args.  (Non-direct args are useless at runtime, and are
363 		 * actually passed as NULLs, but we may need them in the function
364 		 * signature to allow resolution of a polymorphic agg's result type.)
365 		 */
366 		Oid			ffnVariadicArgType = variadicArgType;
367 
368 		fnArgs[0] = aggTransType;
369 		memcpy(fnArgs + 1, aggArgTypes, numArgs * sizeof(Oid));
370 		if (finalfnExtraArgs)
371 			nargs_finalfn = numArgs + 1;
372 		else
373 		{
374 			nargs_finalfn = numDirectArgs + 1;
375 			if (numDirectArgs < numArgs)
376 			{
377 				/* variadic argument doesn't affect finalfn */
378 				ffnVariadicArgType = InvalidOid;
379 			}
380 		}
381 
382 		finalfn = lookup_agg_function(aggfinalfnName, nargs_finalfn,
383 									  fnArgs, ffnVariadicArgType,
384 									  &finaltype);
385 
386 		/*
387 		 * When finalfnExtraArgs is specified, the finalfn will certainly be
388 		 * passed at least one null argument, so complain if it's strict.
389 		 * Nothing bad would happen at runtime (you'd just get a null result),
390 		 * but it's surely not what the user wants, so let's complain now.
391 		 */
392 		if (finalfnExtraArgs && func_strict(finalfn))
393 			ereport(ERROR,
394 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
395 					 errmsg("final function with extra arguments must not be declared STRICT")));
396 	}
397 	else
398 	{
399 		/*
400 		 * If no finalfn, aggregate result type is type of the state value
401 		 */
402 		finaltype = aggTransType;
403 	}
404 	Assert(OidIsValid(finaltype));
405 
406 	/* handle the combinefn, if supplied */
407 	if (aggcombinefnName)
408 	{
409 		Oid			combineType;
410 
411 		/*
412 		 * Combine function must have 2 arguments, each of which is the trans
413 		 * type.  VARIADIC doesn't affect it.
414 		 */
415 		fnArgs[0] = aggTransType;
416 		fnArgs[1] = aggTransType;
417 
418 		combinefn = lookup_agg_function(aggcombinefnName, 2,
419 										fnArgs, InvalidOid,
420 										&combineType);
421 
422 		/* Ensure the return type matches the aggregate's trans type */
423 		if (combineType != aggTransType)
424 			ereport(ERROR,
425 					(errcode(ERRCODE_DATATYPE_MISMATCH),
426 					 errmsg("return type of combine function %s is not %s",
427 							NameListToString(aggcombinefnName),
428 							format_type_be(aggTransType))));
429 
430 		/*
431 		 * A combine function to combine INTERNAL states must accept nulls and
432 		 * ensure that the returned state is in the correct memory context. We
433 		 * cannot directly check the latter, but we can check the former.
434 		 */
435 		if (aggTransType == INTERNALOID && func_strict(combinefn))
436 			ereport(ERROR,
437 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
438 					 errmsg("combine function with transition type %s must not be declared STRICT",
439 							format_type_be(aggTransType))));
440 	}
441 
442 	/*
443 	 * Validate the serialization function, if present.
444 	 */
445 	if (aggserialfnName)
446 	{
447 		/* signature is always serialize(internal) returns bytea */
448 		fnArgs[0] = INTERNALOID;
449 
450 		serialfn = lookup_agg_function(aggserialfnName, 1,
451 									   fnArgs, InvalidOid,
452 									   &rettype);
453 
454 		if (rettype != BYTEAOID)
455 			ereport(ERROR,
456 					(errcode(ERRCODE_DATATYPE_MISMATCH),
457 					 errmsg("return type of serialization function %s is not %s",
458 							NameListToString(aggserialfnName),
459 							format_type_be(BYTEAOID))));
460 	}
461 
462 	/*
463 	 * Validate the deserialization function, if present.
464 	 */
465 	if (aggdeserialfnName)
466 	{
467 		/* signature is always deserialize(bytea, internal) returns internal */
468 		fnArgs[0] = BYTEAOID;
469 		fnArgs[1] = INTERNALOID;	/* dummy argument for type safety */
470 
471 		deserialfn = lookup_agg_function(aggdeserialfnName, 2,
472 										 fnArgs, InvalidOid,
473 										 &rettype);
474 
475 		if (rettype != INTERNALOID)
476 			ereport(ERROR,
477 					(errcode(ERRCODE_DATATYPE_MISMATCH),
478 					 errmsg("return type of deserialization function %s is not %s",
479 							NameListToString(aggdeserialfnName),
480 							format_type_be(INTERNALOID))));
481 	}
482 
483 	/*
484 	 * If finaltype (i.e. aggregate return type) is polymorphic, inputs must
485 	 * be polymorphic also, else parser will fail to deduce result type.
486 	 * (Note: given the previous test on transtype and inputs, this cannot
487 	 * happen, unless someone has snuck a finalfn definition into the catalogs
488 	 * that itself violates the rule against polymorphic result with no
489 	 * polymorphic input.)
490 	 */
491 	detailmsg = check_valid_polymorphic_signature(finaltype,
492 												  aggArgTypes,
493 												  numArgs);
494 	if (detailmsg)
495 		ereport(ERROR,
496 				(errcode(ERRCODE_DATATYPE_MISMATCH),
497 				 errmsg("cannot determine result data type"),
498 				 errdetail_internal("%s", detailmsg)));
499 
500 	/*
501 	 * Also, the return type can't be INTERNAL unless there's at least one
502 	 * INTERNAL argument.  This is the same type-safety restriction we enforce
503 	 * for regular functions, but at the level of aggregates.  We must test
504 	 * this explicitly because we allow INTERNAL as the transtype.
505 	 */
506 	detailmsg = check_valid_internal_signature(finaltype,
507 											   aggArgTypes,
508 											   numArgs);
509 	if (detailmsg)
510 		ereport(ERROR,
511 				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
512 				 errmsg("unsafe use of pseudo-type \"internal\""),
513 				 errdetail_internal("%s", detailmsg)));
514 
515 	/*
516 	 * If a moving-aggregate implementation is supplied, look up its finalfn
517 	 * if any, and check that the implied aggregate result type matches the
518 	 * plain implementation.
519 	 */
520 	if (OidIsValid(aggmTransType))
521 	{
522 		/* handle finalfn, if supplied */
523 		if (aggmfinalfnName)
524 		{
525 			/*
526 			 * The arguments are figured the same way as for the regular
527 			 * finalfn, but using aggmTransType and mfinalfnExtraArgs.
528 			 */
529 			Oid			ffnVariadicArgType = variadicArgType;
530 
531 			fnArgs[0] = aggmTransType;
532 			memcpy(fnArgs + 1, aggArgTypes, numArgs * sizeof(Oid));
533 			if (mfinalfnExtraArgs)
534 				nargs_finalfn = numArgs + 1;
535 			else
536 			{
537 				nargs_finalfn = numDirectArgs + 1;
538 				if (numDirectArgs < numArgs)
539 				{
540 					/* variadic argument doesn't affect finalfn */
541 					ffnVariadicArgType = InvalidOid;
542 				}
543 			}
544 
545 			mfinalfn = lookup_agg_function(aggmfinalfnName, nargs_finalfn,
546 										   fnArgs, ffnVariadicArgType,
547 										   &rettype);
548 
549 			/* As above, check strictness if mfinalfnExtraArgs is given */
550 			if (mfinalfnExtraArgs && func_strict(mfinalfn))
551 				ereport(ERROR,
552 						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
553 						 errmsg("final function with extra arguments must not be declared STRICT")));
554 		}
555 		else
556 		{
557 			/*
558 			 * If no finalfn, aggregate result type is type of the state value
559 			 */
560 			rettype = aggmTransType;
561 		}
562 		Assert(OidIsValid(rettype));
563 		if (rettype != finaltype)
564 			ereport(ERROR,
565 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
566 					 errmsg("moving-aggregate implementation returns type %s, but plain implementation returns type %s",
567 							format_type_be(rettype),
568 							format_type_be(finaltype))));
569 	}
570 
571 	/* handle sortop, if supplied */
572 	if (aggsortopName)
573 	{
574 		if (numArgs != 1)
575 			ereport(ERROR,
576 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
577 					 errmsg("sort operator can only be specified for single-argument aggregates")));
578 		sortop = LookupOperName(NULL, aggsortopName,
579 								aggArgTypes[0], aggArgTypes[0],
580 								false, -1);
581 	}
582 
583 	/*
584 	 * permission checks on used types
585 	 */
586 	for (i = 0; i < numArgs; i++)
587 	{
588 		aclresult = pg_type_aclcheck(aggArgTypes[i], GetUserId(), ACL_USAGE);
589 		if (aclresult != ACLCHECK_OK)
590 			aclcheck_error_type(aclresult, aggArgTypes[i]);
591 	}
592 
593 	aclresult = pg_type_aclcheck(aggTransType, GetUserId(), ACL_USAGE);
594 	if (aclresult != ACLCHECK_OK)
595 		aclcheck_error_type(aclresult, aggTransType);
596 
597 	if (OidIsValid(aggmTransType))
598 	{
599 		aclresult = pg_type_aclcheck(aggmTransType, GetUserId(), ACL_USAGE);
600 		if (aclresult != ACLCHECK_OK)
601 			aclcheck_error_type(aclresult, aggmTransType);
602 	}
603 
604 	aclresult = pg_type_aclcheck(finaltype, GetUserId(), ACL_USAGE);
605 	if (aclresult != ACLCHECK_OK)
606 		aclcheck_error_type(aclresult, finaltype);
607 
608 
609 	/*
610 	 * Everything looks okay.  Try to create the pg_proc entry for the
611 	 * aggregate.  (This could fail if there's already a conflicting entry.)
612 	 */
613 
614 	myself = ProcedureCreate(aggName,
615 							 aggNamespace,
616 							 replace,	/* maybe replacement */
617 							 false, /* doesn't return a set */
618 							 finaltype, /* returnType */
619 							 GetUserId(),	/* proowner */
620 							 INTERNALlanguageId,	/* languageObjectId */
621 							 InvalidOid,	/* no validator */
622 							 "aggregate_dummy", /* placeholder proc */
623 							 NULL,	/* probin */
624 							 PROKIND_AGGREGATE,
625 							 false, /* security invoker (currently not
626 									 * definable for agg) */
627 							 false, /* isLeakProof */
628 							 false, /* isStrict (not needed for agg) */
629 							 PROVOLATILE_IMMUTABLE, /* volatility (not needed
630 													 * for agg) */
631 							 proparallel,
632 							 parameterTypes,	/* paramTypes */
633 							 allParameterTypes, /* allParamTypes */
634 							 parameterModes,	/* parameterModes */
635 							 parameterNames,	/* parameterNames */
636 							 parameterDefaults, /* parameterDefaults */
637 							 PointerGetDatum(NULL), /* trftypes */
638 							 PointerGetDatum(NULL), /* proconfig */
639 							 InvalidOid,	/* no prosupport */
640 							 1, /* procost */
641 							 0);	/* prorows */
642 	procOid = myself.objectId;
643 
644 	/*
645 	 * Okay to create the pg_aggregate entry.
646 	 */
647 	aggdesc = table_open(AggregateRelationId, RowExclusiveLock);
648 	tupDesc = aggdesc->rd_att;
649 
650 	/* initialize nulls and values */
651 	for (i = 0; i < Natts_pg_aggregate; i++)
652 	{
653 		nulls[i] = false;
654 		values[i] = (Datum) NULL;
655 		replaces[i] = true;
656 	}
657 	values[Anum_pg_aggregate_aggfnoid - 1] = ObjectIdGetDatum(procOid);
658 	values[Anum_pg_aggregate_aggkind - 1] = CharGetDatum(aggKind);
659 	values[Anum_pg_aggregate_aggnumdirectargs - 1] = Int16GetDatum(numDirectArgs);
660 	values[Anum_pg_aggregate_aggtransfn - 1] = ObjectIdGetDatum(transfn);
661 	values[Anum_pg_aggregate_aggfinalfn - 1] = ObjectIdGetDatum(finalfn);
662 	values[Anum_pg_aggregate_aggcombinefn - 1] = ObjectIdGetDatum(combinefn);
663 	values[Anum_pg_aggregate_aggserialfn - 1] = ObjectIdGetDatum(serialfn);
664 	values[Anum_pg_aggregate_aggdeserialfn - 1] = ObjectIdGetDatum(deserialfn);
665 	values[Anum_pg_aggregate_aggmtransfn - 1] = ObjectIdGetDatum(mtransfn);
666 	values[Anum_pg_aggregate_aggminvtransfn - 1] = ObjectIdGetDatum(minvtransfn);
667 	values[Anum_pg_aggregate_aggmfinalfn - 1] = ObjectIdGetDatum(mfinalfn);
668 	values[Anum_pg_aggregate_aggfinalextra - 1] = BoolGetDatum(finalfnExtraArgs);
669 	values[Anum_pg_aggregate_aggmfinalextra - 1] = BoolGetDatum(mfinalfnExtraArgs);
670 	values[Anum_pg_aggregate_aggfinalmodify - 1] = CharGetDatum(finalfnModify);
671 	values[Anum_pg_aggregate_aggmfinalmodify - 1] = CharGetDatum(mfinalfnModify);
672 	values[Anum_pg_aggregate_aggsortop - 1] = ObjectIdGetDatum(sortop);
673 	values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType);
674 	values[Anum_pg_aggregate_aggtransspace - 1] = Int32GetDatum(aggTransSpace);
675 	values[Anum_pg_aggregate_aggmtranstype - 1] = ObjectIdGetDatum(aggmTransType);
676 	values[Anum_pg_aggregate_aggmtransspace - 1] = Int32GetDatum(aggmTransSpace);
677 	if (agginitval)
678 		values[Anum_pg_aggregate_agginitval - 1] = CStringGetTextDatum(agginitval);
679 	else
680 		nulls[Anum_pg_aggregate_agginitval - 1] = true;
681 	if (aggminitval)
682 		values[Anum_pg_aggregate_aggminitval - 1] = CStringGetTextDatum(aggminitval);
683 	else
684 		nulls[Anum_pg_aggregate_aggminitval - 1] = true;
685 
686 	if (replace)
687 		oldtup = SearchSysCache1(AGGFNOID, ObjectIdGetDatum(procOid));
688 	else
689 		oldtup = NULL;
690 
691 	if (HeapTupleIsValid(oldtup))
692 	{
693 		Form_pg_aggregate oldagg = (Form_pg_aggregate) GETSTRUCT(oldtup);
694 
695 		/*
696 		 * If we're replacing an existing entry, we need to validate that
697 		 * we're not changing anything that would break callers. Specifically
698 		 * we must not change aggkind or aggnumdirectargs, which affect how an
699 		 * aggregate call is treated in parse analysis.
700 		 */
701 		if (aggKind != oldagg->aggkind)
702 			ereport(ERROR,
703 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
704 					 errmsg("cannot change routine kind"),
705 					 (oldagg->aggkind == AGGKIND_NORMAL ?
706 					  errdetail("\"%s\" is an ordinary aggregate function.", aggName) :
707 					  oldagg->aggkind == AGGKIND_ORDERED_SET ?
708 					  errdetail("\"%s\" is an ordered-set aggregate.", aggName) :
709 					  oldagg->aggkind == AGGKIND_HYPOTHETICAL ?
710 					  errdetail("\"%s\" is a hypothetical-set aggregate.", aggName) :
711 					  0)));
712 		if (numDirectArgs != oldagg->aggnumdirectargs)
713 			ereport(ERROR,
714 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
715 					 errmsg("cannot change number of direct arguments of an aggregate function")));
716 
717 		replaces[Anum_pg_aggregate_aggfnoid - 1] = false;
718 		replaces[Anum_pg_aggregate_aggkind - 1] = false;
719 		replaces[Anum_pg_aggregate_aggnumdirectargs - 1] = false;
720 
721 		tup = heap_modify_tuple(oldtup, tupDesc, values, nulls, replaces);
722 		CatalogTupleUpdate(aggdesc, &tup->t_self, tup);
723 		ReleaseSysCache(oldtup);
724 	}
725 	else
726 	{
727 		tup = heap_form_tuple(tupDesc, values, nulls);
728 		CatalogTupleInsert(aggdesc, tup);
729 	}
730 
731 	table_close(aggdesc, RowExclusiveLock);
732 
733 	/*
734 	 * Create dependencies for the aggregate (above and beyond those already
735 	 * made by ProcedureCreate).  Note: we don't need an explicit dependency
736 	 * on aggTransType since we depend on it indirectly through transfn.
737 	 * Likewise for aggmTransType using the mtransfn, if it exists.
738 	 *
739 	 * If we're replacing an existing definition, ProcedureCreate deleted all
740 	 * our existing dependencies, so we have to do the same things here either
741 	 * way.
742 	 */
743 
744 	/* Depends on transition function */
745 	referenced.classId = ProcedureRelationId;
746 	referenced.objectId = transfn;
747 	referenced.objectSubId = 0;
748 	recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
749 
750 	/* Depends on final function, if any */
751 	if (OidIsValid(finalfn))
752 	{
753 		referenced.classId = ProcedureRelationId;
754 		referenced.objectId = finalfn;
755 		referenced.objectSubId = 0;
756 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
757 	}
758 
759 	/* Depends on combine function, if any */
760 	if (OidIsValid(combinefn))
761 	{
762 		referenced.classId = ProcedureRelationId;
763 		referenced.objectId = combinefn;
764 		referenced.objectSubId = 0;
765 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
766 	}
767 
768 	/* Depends on serialization function, if any */
769 	if (OidIsValid(serialfn))
770 	{
771 		referenced.classId = ProcedureRelationId;
772 		referenced.objectId = serialfn;
773 		referenced.objectSubId = 0;
774 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
775 	}
776 
777 	/* Depends on deserialization function, if any */
778 	if (OidIsValid(deserialfn))
779 	{
780 		referenced.classId = ProcedureRelationId;
781 		referenced.objectId = deserialfn;
782 		referenced.objectSubId = 0;
783 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
784 	}
785 
786 	/* Depends on forward transition function, if any */
787 	if (OidIsValid(mtransfn))
788 	{
789 		referenced.classId = ProcedureRelationId;
790 		referenced.objectId = mtransfn;
791 		referenced.objectSubId = 0;
792 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
793 	}
794 
795 	/* Depends on inverse transition function, if any */
796 	if (OidIsValid(minvtransfn))
797 	{
798 		referenced.classId = ProcedureRelationId;
799 		referenced.objectId = minvtransfn;
800 		referenced.objectSubId = 0;
801 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
802 	}
803 
804 	/* Depends on final function, if any */
805 	if (OidIsValid(mfinalfn))
806 	{
807 		referenced.classId = ProcedureRelationId;
808 		referenced.objectId = mfinalfn;
809 		referenced.objectSubId = 0;
810 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
811 	}
812 
813 	/* Depends on sort operator, if any */
814 	if (OidIsValid(sortop))
815 	{
816 		referenced.classId = OperatorRelationId;
817 		referenced.objectId = sortop;
818 		referenced.objectSubId = 0;
819 		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
820 	}
821 
822 	return myself;
823 }
824 
825 /*
826  * lookup_agg_function
827  * common code for finding aggregate support functions
828  *
829  * fnName: possibly-schema-qualified function name
830  * nargs, input_types: expected function argument types
831  * variadicArgType: type of variadic argument if any, else InvalidOid
832  *
833  * Returns OID of function, and stores its return type into *rettype
834  *
835  * NB: must not scribble on input_types[], as we may re-use those
836  */
837 static Oid
lookup_agg_function(List * fnName,int nargs,Oid * input_types,Oid variadicArgType,Oid * rettype)838 lookup_agg_function(List *fnName,
839 					int nargs,
840 					Oid *input_types,
841 					Oid variadicArgType,
842 					Oid *rettype)
843 {
844 	Oid			fnOid;
845 	bool		retset;
846 	int			nvargs;
847 	Oid			vatype;
848 	Oid		   *true_oid_array;
849 	FuncDetailCode fdresult;
850 	AclResult	aclresult;
851 	int			i;
852 
853 	/*
854 	 * func_get_detail looks up the function in the catalogs, does
855 	 * disambiguation for polymorphic functions, handles inheritance, and
856 	 * returns the funcid and type and set or singleton status of the
857 	 * function's return value.  it also returns the true argument types to
858 	 * the function.
859 	 */
860 	fdresult = func_get_detail(fnName, NIL, NIL,
861 							   nargs, input_types, false, false,
862 							   &fnOid, rettype, &retset,
863 							   &nvargs, &vatype,
864 							   &true_oid_array, NULL);
865 
866 	/* only valid case is a normal function not returning a set */
867 	if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid))
868 		ereport(ERROR,
869 				(errcode(ERRCODE_UNDEFINED_FUNCTION),
870 				 errmsg("function %s does not exist",
871 						func_signature_string(fnName, nargs,
872 											  NIL, input_types))));
873 	if (retset)
874 		ereport(ERROR,
875 				(errcode(ERRCODE_DATATYPE_MISMATCH),
876 				 errmsg("function %s returns a set",
877 						func_signature_string(fnName, nargs,
878 											  NIL, input_types))));
879 
880 	/*
881 	 * If the agg is declared to take VARIADIC ANY, the underlying functions
882 	 * had better be declared that way too, else they may receive too many
883 	 * parameters; but func_get_detail would have been happy with plain ANY.
884 	 * (Probably nothing very bad would happen, but it wouldn't work as the
885 	 * user expects.)  Other combinations should work without any special
886 	 * pushups, given that we told func_get_detail not to expand VARIADIC.
887 	 */
888 	if (variadicArgType == ANYOID && vatype != ANYOID)
889 		ereport(ERROR,
890 				(errcode(ERRCODE_DATATYPE_MISMATCH),
891 				 errmsg("function %s must accept VARIADIC ANY to be used in this aggregate",
892 						func_signature_string(fnName, nargs,
893 											  NIL, input_types))));
894 
895 	/*
896 	 * If there are any polymorphic types involved, enforce consistency, and
897 	 * possibly refine the result type.  It's OK if the result is still
898 	 * polymorphic at this point, though.
899 	 */
900 	*rettype = enforce_generic_type_consistency(input_types,
901 												true_oid_array,
902 												nargs,
903 												*rettype,
904 												true);
905 
906 	/*
907 	 * func_get_detail will find functions requiring run-time argument type
908 	 * coercion, but nodeAgg.c isn't prepared to deal with that
909 	 */
910 	for (i = 0; i < nargs; i++)
911 	{
912 		if (!IsBinaryCoercible(input_types[i], true_oid_array[i]))
913 			ereport(ERROR,
914 					(errcode(ERRCODE_DATATYPE_MISMATCH),
915 					 errmsg("function %s requires run-time type coercion",
916 							func_signature_string(fnName, nargs,
917 												  NIL, true_oid_array))));
918 	}
919 
920 	/* Check aggregate creator has permission to call the function */
921 	aclresult = pg_proc_aclcheck(fnOid, GetUserId(), ACL_EXECUTE);
922 	if (aclresult != ACLCHECK_OK)
923 		aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(fnOid));
924 
925 	return fnOid;
926 }
927