59{
60 char *aggName;
63 char aggKind = AGGKIND_NORMAL;
72 bool finalfuncExtraArgs = false;
73 bool mfinalfuncExtraArgs = false;
74 char finalfuncModify = 0;
75 char mfinalfuncModify = 0;
81 int32 mtransSpace = 0;
82 char *initval = NULL;
83 char *minitval = NULL;
84 char *parallel = NULL;
85 int numArgs;
86 int numDirectArgs = 0;
91 List *parameterDefaults;
95 char transTypeType;
96 char mtransTypeType = 0;
97 char proparallel = PROPARALLEL_UNSAFE;
99
100
102
103
108
109
110 if (!oldstyle)
111 {
114 if (numDirectArgs >= 0)
115 aggKind = AGGKIND_ORDERED_SET;
116 else
117 numDirectArgs = 0;
119 }
120
121
122 foreach(pl, parameters)
123 {
125
126
127
128
129
130 if (strcmp(defel->
defname,
"sfunc") == 0)
132 else if (strcmp(defel->
defname,
"sfunc1") == 0)
134 else if (strcmp(defel->
defname,
"finalfunc") == 0)
136 else if (strcmp(defel->
defname,
"combinefunc") == 0)
138 else if (strcmp(defel->
defname,
"serialfunc") == 0)
140 else if (strcmp(defel->
defname,
"deserialfunc") == 0)
142 else if (strcmp(defel->
defname,
"msfunc") == 0)
144 else if (strcmp(defel->
defname,
"minvfunc") == 0)
146 else if (strcmp(defel->
defname,
"mfinalfunc") == 0)
148 else if (strcmp(defel->
defname,
"finalfunc_extra") == 0)
150 else if (strcmp(defel->
defname,
"mfinalfunc_extra") == 0)
152 else if (strcmp(defel->
defname,
"finalfunc_modify") == 0)
154 else if (strcmp(defel->
defname,
"mfinalfunc_modify") == 0)
156 else if (strcmp(defel->
defname,
"sortop") == 0)
158 else if (strcmp(defel->
defname,
"basetype") == 0)
160 else if (strcmp(defel->
defname,
"hypothetical") == 0)
161 {
163 {
164 if (aggKind == AGGKIND_NORMAL)
166 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
167 errmsg(
"only ordered-set aggregates can be hypothetical")));
168 aggKind = AGGKIND_HYPOTHETICAL;
169 }
170 }
171 else if (strcmp(defel->
defname,
"stype") == 0)
173 else if (strcmp(defel->
defname,
"stype1") == 0)
175 else if (strcmp(defel->
defname,
"sspace") == 0)
177 else if (strcmp(defel->
defname,
"mstype") == 0)
179 else if (strcmp(defel->
defname,
"msspace") == 0)
181 else if (strcmp(defel->
defname,
"initcond") == 0)
183 else if (strcmp(defel->
defname,
"initcond1") == 0)
185 else if (strcmp(defel->
defname,
"minitcond") == 0)
187 else if (strcmp(defel->
defname,
"parallel") == 0)
189 else
191 (
errcode(ERRCODE_SYNTAX_ERROR),
192 errmsg(
"aggregate attribute \"%s\" not recognized",
194 }
195
196
197
198
199 if (transType == NULL)
201 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
202 errmsg(
"aggregate stype must be specified")));
203 if (transfuncName ==
NIL)
205 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
206 errmsg(
"aggregate sfunc must be specified")));
207
208
209
210
211
212
213 if (mtransType != NULL)
214 {
215 if (mtransfuncName ==
NIL)
217 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
218 errmsg(
"aggregate msfunc must be specified when mstype is specified")));
219 if (minvtransfuncName ==
NIL)
221 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
222 errmsg(
"aggregate minvfunc must be specified when mstype is specified")));
223 }
224 else
225 {
226 if (mtransfuncName !=
NIL)
228 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
229 errmsg(
"aggregate msfunc must not be specified without mstype")));
230 if (minvtransfuncName !=
NIL)
232 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
233 errmsg(
"aggregate minvfunc must not be specified without mstype")));
234 if (mfinalfuncName !=
NIL)
236 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
237 errmsg(
"aggregate mfinalfunc must not be specified without mstype")));
238 if (mtransSpace != 0)
240 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
241 errmsg(
"aggregate msspace must not be specified without mstype")));
242 if (minitval != NULL)
244 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
245 errmsg(
"aggregate minitcond must not be specified without mstype")));
246 }
247
248
249
250
251
252 if (finalfuncModify == 0)
253 finalfuncModify = (aggKind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
254 if (mfinalfuncModify == 0)
255 mfinalfuncModify = (aggKind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
256
257
258
259
260 if (oldstyle)
261 {
262
263
264
265
266
267
268
270
271 if (baseType == NULL)
273 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
274 errmsg(
"aggregate input type must be specified")));
275
277 {
278 numArgs = 0;
280 }
281 else
282 {
283 numArgs = 1;
285 }
287 allParameterTypes = NULL;
288 parameterModes = NULL;
289 parameterNames = NULL;
290 parameterDefaults =
NIL;
292 }
293 else
294 {
295
296
297
298
299 Oid requiredResultType;
300
301 if (baseType != NULL)
303 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
304 errmsg(
"basetype is redundant with aggregate input type specification")));
305
311 ¶meterTypes,
312 NULL,
313 &allParameterTypes,
314 ¶meterModes,
315 ¶meterNames,
316 NULL,
317 ¶meterDefaults,
318 &variadicArgType,
319 &requiredResultType);
320
322
324 }
325
326
327
328
329
330
331
332
333
334
335
336
339 if (transTypeType == TYPTYPE_PSEUDO &&
340 !IsPolymorphicType(transTypeId))
341 {
342 if (transTypeId == INTERNALOID &&
superuser())
343 ;
344 else
346 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
347 errmsg(
"aggregate transition data type cannot be %s",
349 }
350
351 if (serialfuncName && deserialfuncName)
352 {
353
354
355
356 if (transTypeId != INTERNALOID)
358 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
359 errmsg(
"serialization functions may be specified only when the aggregate transition data type is %s",
361 }
362 else if (serialfuncName || deserialfuncName)
363 {
364
365
366
368 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
369 errmsg(
"must specify both or neither of serialization and deserialization functions")));
370 }
371
372
373
374
375
376 if (mtransType)
377 {
380 if (mtransTypeType == TYPTYPE_PSEUDO &&
381 !IsPolymorphicType(mtransTypeId))
382 {
383 if (mtransTypeId == INTERNALOID &&
superuser())
384 ;
385 else
387 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
388 errmsg(
"aggregate transition data type cannot be %s",
390 }
391 }
392
393
394
395
396
397
398
399
400
401
402 if (initval && transTypeType != TYPTYPE_PSEUDO)
403 {
405 typioparam;
406
409 }
410
411
412
413
414 if (minitval && mtransTypeType != TYPTYPE_PSEUDO)
415 {
417 typioparam;
418
421 }
422
423 if (parallel)
424 {
425 if (strcmp(parallel, "safe") == 0)
426 proparallel = PROPARALLEL_SAFE;
427 else if (strcmp(parallel, "restricted") == 0)
428 proparallel = PROPARALLEL_RESTRICTED;
429 else if (strcmp(parallel, "unsafe") == 0)
430 proparallel = PROPARALLEL_UNSAFE;
431 else
433 (
errcode(ERRCODE_SYNTAX_ERROR),
434 errmsg(
"parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));
435 }
436
437
438
439
441 aggNamespace,
442 replace,
443 aggKind,
444 numArgs,
445 numDirectArgs,
446 parameterTypes,
450 parameterDefaults,
451 variadicArgType,
452 transfuncName,
453 finalfuncName,
454 combinefuncName,
455 serialfuncName,
456 deserialfuncName,
457 mtransfuncName,
458 minvtransfuncName,
459 mfinalfuncName,
460 finalfuncExtraArgs,
461 mfinalfuncExtraArgs,
462 finalfuncModify,
463 mfinalfuncModify,
464 sortoperatorName,
465 transTypeId,
466 transSpace,
467 mtransTypeId,
468 mtransSpace,
469 initval,
470 minitval,
471 proparallel);
472}
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
static char extractModify(DefElem *defel)
TypeName * defGetTypeName(DefElem *def)
int32 defGetInt32(DefElem *def)
char * defGetString(DefElem *def)
bool defGetBoolean(DefElem *def)
List * defGetQualifiedName(DefElem *def)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Datum OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
void interpret_function_parameter_list(ParseState *pstate, List *parameters, Oid languageOid, ObjectType objtype, oidvector **parameterTypes, List **parameterTypes_list, ArrayType **allParameterTypes, ArrayType **parameterModes, ArrayType **parameterNames, List **inParameterNames_list, List **parameterDefaults, Oid *variadicArgType, Oid *requiredResultType)
Assert(PointerIsAligned(start, uint64))
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
char get_typtype(Oid typid)
char * get_namespace_name(Oid nspid)
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
oidvector * buildoidvector(const Oid *oids, int n)
char * TypeNameToString(const TypeName *typeName)
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
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)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
int pg_strcasecmp(const char *s1, const char *s2)
static Datum PointerGetDatum(const void *X)