1/*-------------------------------------------------------------------------
5 * Routines for CREATE and DROP FUNCTION commands and CREATE and DROP
8 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/commands/functioncmds.c
16 * These routines take the parse tree and pick out the
17 * appropriate arguments/flags, and pass the results to the
18 * corresponding "FooCreate" routines (in src/backend/catalog) that do
19 * the actual catalog-munging. These routines also verify permission
20 * of the user to execute the command.
23 * These things must be defined and committed in the following order:
25 * input/output, recv/send procedures
31 *-------------------------------------------------------------------------
76 * Examine the RETURNS clause of the CREATE FUNCTION statement
77 * and return information about it as *prorettype_p and *returnsSet_p.
79 * This is more complex than the average typename lookup because we want to
80 * allow a shell type to be used, or even created if the specified return type
81 * doesn't exist yet. (Without this, there's no way to define the I/O procs
82 * for a new type.) But SQL function creation won't cope, so error out if
83 * the target language is SQL. (We do this here, not in the SQL-function
84 * validator, so as not to produce a NOTICE and then an ERROR for the same
89 Oid *prorettype_p,
bool *returnsSet_p)
101 if (languageOid == SQLlanguageId)
103 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
104 errmsg(
"SQL function cannot return shell type %s",
108 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
109 errmsg(
"return type %s is only a shell",
123 * Only C-coded functions can be I/O functions. We enforce this
124 * restriction here mainly to prevent littering the catalogs with
125 * shell types due to simple typos in user-defined function
128 if (languageOid != INTERNALlanguageId &&
129 languageOid != ClanguageId)
131 (
errcode(ERRCODE_UNDEFINED_OBJECT),
132 errmsg(
"type \"%s\" does not exist", typnam)));
134 /* Reject if there's typmod decoration, too */
137 (
errcode(ERRCODE_SYNTAX_ERROR),
138 errmsg(
"type modifier cannot be specified for shell type \"%s\"",
141 /* Otherwise, go ahead and make a shell type */
143 (
errcode(ERRCODE_UNDEFINED_OBJECT),
144 errmsg(
"type \"%s\" is not yet defined", typnam),
145 errdetail(
"Creating a shell type definition.")));
162 *prorettype_p = rettype;
163 *returnsSet_p = returnType->
setof;
167 * Interpret the function parameter list of a CREATE FUNCTION,
168 * CREATE PROCEDURE, or CREATE AGGREGATE statement.
171 * parameters: list of FunctionParameter structs
172 * languageOid: OID of function language (InvalidOid if it's CREATE AGGREGATE)
173 * objtype: identifies type of object being created
175 * Results are stored into output parameters. parameterTypes must always
176 * be created, but the other arrays/lists can be NULL pointers if not needed.
177 * variadicArgType is set to the variadic array type if there's a VARIADIC
178 * parameter (there can be only one); or to InvalidOid if not.
179 * requiredResultType is set to InvalidOid if there are no OUT parameters,
180 * else it is set to the OID of the implied result type.
188 List **parameterTypes_list,
192 List **inParameterNames_list,
193 List **parameterDefaults,
194 Oid *variadicArgType,
195 Oid *requiredResultType)
205 bool have_names =
false;
206 bool have_defaults =
false;
210 *variadicArgType =
InvalidOid;
/* default result */
211 *requiredResultType =
InvalidOid;
/* default result */
217 *parameterDefaults =
NIL;
219 /* Scan the list and extract data into work arrays */
221 foreach(
x, parameters)
226 bool isinput =
false;
231 /* For our purposes here, a defaulted mode spec is identical to IN */
240 /* As above, hard error if language is SQL */
241 if (languageOid == SQLlanguageId)
243 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
244 errmsg(
"SQL function cannot accept shell type %s",
247 /* We don't allow creating aggregates on shell types either */
250 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
251 errmsg(
"aggregate cannot accept shell type %s",
256 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
257 errmsg(
"argument type %s is only a shell",
267 (
errcode(ERRCODE_UNDEFINED_OBJECT),
268 errmsg(
"type %s does not exist",
282 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
283 errmsg(
"aggregates cannot accept set arguments"),
287 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
288 errmsg(
"procedures cannot accept set arguments"),
292 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
293 errmsg(
"functions cannot accept set arguments"),
297 /* handle input parameters */
300 /* other input parameters can't follow a VARIADIC parameter */
303 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
304 errmsg(
"VARIADIC parameter must be the last input parameter"),
306 inTypes[inCount++] = toid;
308 if (parameterTypes_list)
309 *parameterTypes_list =
lappend_oid(*parameterTypes_list, toid);
312 /* handle output parameters */
318 * We disallow OUT-after-VARIADIC only for procedures. While
319 * such a case causes no confusion in ordinary function calls,
320 * it would cause confusion in a CALL statement.
324 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
325 errmsg(
"VARIADIC parameter must be the last parameter"),
327 /* Procedures with output parameters always return RECORD */
328 *requiredResultType = RECORDOID;
330 else if (outCount == 0)
/* save first output param's type */
331 *requiredResultType = toid;
337 *variadicArgType = toid;
339 /* validate variadic parameter type */
343 case ANYCOMPATIBLEARRAYOID:
350 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
351 errmsg(
"VARIADIC parameter must be an array"),
366 * As of Postgres 9.0 we disallow using the same name for two
367 * input or two output function parameters. Depending on the
368 * function's language, conflicting input and output names might
369 * be bad too, but we leave it to the PL to complain if so.
371 foreach(
px, parameters)
378 /* as above, default mode is IN */
379 prevfpmode = prevfp->
mode;
382 /* pure in doesn't conflict with pure out */
393 if (prevfp->
name && prevfp->
name[0] &&
394 strcmp(prevfp->
name, fp->
name) == 0)
396 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
397 errmsg(
"parameter name \"%s\" used more than once",
406 if (inParameterNames_list)
415 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
416 errmsg(
"only input parameters can have default values"),
425 * Make sure no variables are referred to (this is probably dead
426 * code now that add_missing_from is history).
431 (
errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
432 errmsg(
"cannot use table references in parameter default value"),
436 * transformExpr() should have already rejected subqueries,
437 * aggregates, and window functions, based on the EXPR_KIND_ for a
438 * default expression.
440 * It can't return a set either --- but coerce_to_specific_type
441 * already checked that for us.
443 * Note: the point of these restrictions is to ensure that an
444 * expression that, on its face, hasn't got subplans, aggregates,
445 * etc cannot suddenly have them after function default arguments
449 *parameterDefaults =
lappend(*parameterDefaults, def);
450 have_defaults =
true;
454 if (isinput && have_defaults)
456 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
457 errmsg(
"input parameters after one with a default value must also have defaults"),
461 * For procedures, we also can't allow OUT parameters after one
462 * with a default, because the same sort of confusion arises in a
467 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
468 errmsg(
"procedure OUT parameters cannot appear after one with a default value"),
475 /* Now construct the proper outputs as needed */
478 if (outCount > 0 || varCount > 0)
483 *requiredResultType = RECORDOID;
484 /* otherwise we set requiredResultType correctly above */
488 *allParameterTypes = NULL;
489 *parameterModes = NULL;
494 for (
i = 0;
i < parameterCount;
i++)
502 *parameterNames = NULL;
507 * Recognize one of the options that can be passed to both CREATE
508 * FUNCTION and ALTER FUNCTION and return it via one of the out
509 * parameters. Returns true if the passed option was recognized. If
510 * the out parameter we were going to assign to points to non-NULL,
511 * raise a duplicate-clause error. (We don't try to detect duplicate
512 * SET parameters though --- if you're redundant, the last one wins.)
528 if (strcmp(defel->
defname,
"volatility") == 0)
531 goto procedure_error;
532 if (*volatility_item)
535 *volatility_item = defel;
537 else if (strcmp(defel->
defname,
"strict") == 0)
540 goto procedure_error;
544 *strict_item = defel;
546 else if (strcmp(defel->
defname,
"security") == 0)
551 *security_item = defel;
553 else if (strcmp(defel->
defname,
"leakproof") == 0)
556 goto procedure_error;
560 *leakproof_item = defel;
562 else if (strcmp(defel->
defname,
"set") == 0)
566 else if (strcmp(defel->
defname,
"cost") == 0)
569 goto procedure_error;
575 else if (strcmp(defel->
defname,
"rows") == 0)
578 goto procedure_error;
584 else if (strcmp(defel->
defname,
"support") == 0)
587 goto procedure_error;
591 *support_item = defel;
593 else if (strcmp(defel->
defname,
"parallel") == 0)
596 goto procedure_error;
600 *parallel_item = defel;
605 /* Recognized an option */
610 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
611 errmsg(
"invalid attribute in procedure definition"),
621 if (strcmp(
str,
"immutable") == 0)
622 return PROVOLATILE_IMMUTABLE;
623 else if (strcmp(
str,
"stable") == 0)
624 return PROVOLATILE_STABLE;
625 else if (strcmp(
str,
"volatile") == 0)
626 return PROVOLATILE_VOLATILE;
630 return 0;
/* keep compiler quiet */
639 if (strcmp(
str,
"safe") == 0)
640 return PROPARALLEL_SAFE;
641 else if (strcmp(
str,
"unsafe") == 0)
642 return PROPARALLEL_UNSAFE;
643 else if (strcmp(
str,
"restricted") == 0)
644 return PROPARALLEL_RESTRICTED;
648 (
errcode(ERRCODE_SYNTAX_ERROR),
649 errmsg(
"parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));
650 return PROPARALLEL_UNSAFE;
/* keep compiler quiet */
655 * Update a proconfig value according to a list of VariableSetStmt items.
657 * The input and result may be NULL to signify a null entry.
664 foreach(l, set_items)
692 * Support functions always take one INTERNAL argument and return
695 argList[0] = INTERNALOID;
700 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
701 errmsg(
"function %s does not exist",
706 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
707 errmsg(
"support function %s must return type %s",
711 * Someday we might want an ACL check here; but for now, we insist that
712 * you be superuser to specify a support function, so privilege on the
713 * support function is moot.
717 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
718 errmsg(
"must be superuser to specify a support function")));
725 * Dissect the list of options assembled in gram.y into function
738 bool *security_definer,
749 DefElem *transform_item = NULL;
750 DefElem *windowfunc_item = NULL;
751 DefElem *volatility_item = NULL;
754 DefElem *leakproof_item = NULL;
765 if (strcmp(defel->
defname,
"as") == 0)
771 else if (strcmp(defel->
defname,
"language") == 0)
775 language_item = defel;
777 else if (strcmp(defel->
defname,
"transform") == 0)
781 transform_item = defel;
783 else if (strcmp(defel->
defname,
"window") == 0)
789 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
790 errmsg(
"invalid attribute in procedure definition"),
792 windowfunc_item = defel;
807 /* recognized common option */
811 elog(
ERROR,
"option \"%s\" not recognized",
820 *transform = transform_item->
arg;
822 *windowfunc_p =
boolVal(windowfunc_item->
arg);
828 *security_definer =
boolVal(security_item->
arg);
838 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
839 errmsg(
"COST must be positive")));
846 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
847 errmsg(
"ROWS must be positive")));
857 * For a dynamically linked C language object, the form of the clause is
859 * AS <object file name> [, <link symbol name> ]
863 * AS <object reference, or sql code>
868 List *parameterTypes,
List *inParameterNames,
869 char **prosrc_str_p,
char **probin_str_p,
871 const char *queryString)
873 if (!sql_body_in && !as)
875 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
876 errmsg(
"no function body specified")));
878 if (sql_body_in && as)
880 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
881 errmsg(
"duplicate function body specified")));
883 if (sql_body_in && languageOid != SQLlanguageId)
885 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
886 errmsg(
"inline SQL function body only valid for language SQL")));
888 *sql_body_out = NULL;
890 if (languageOid == ClanguageId)
893 * For "C" language, store the file name in probin and, when given,
894 * the link symbol name in prosrc. If link symbol is omitted,
895 * substitute procedure name. We also allow link symbol to be
896 * specified as "-", since that was the habit in PG versions before
897 * 8.4, and there might be dump files out there that don't translate
898 * that back to "omitted".
906 if (strcmp(*prosrc_str_p,
"-") == 0)
910 else if (sql_body_in)
925 if (IsPolymorphicType(pinfo->
argtypes[
i]))
927 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
928 errmsg(
"SQL function with unquoted function body cannot have polymorphic arguments")));
953 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
954 errmsg(
"%s is not yet supported in unquoted SQL function body",
956 transformed_stmts =
lappend(transformed_stmts, q);
972 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
973 errmsg(
"%s is not yet supported in unquoted SQL function body",
977 *sql_body_out = (
Node *) q;
981 * We must put something in prosrc. For the moment, just record an
982 * empty string. It might be useful to store the original text of the
983 * CREATE FUNCTION statement --- but to make actual use of that in
984 * error reports, we'd also have to adjust readfuncs.c to not throw
985 * away node location fields when reading prosqlbody.
989 /* But we definitely don't need probin. */
990 *probin_str_p = NULL;
994 /* Everything else wants the given string in prosrc. */
996 *probin_str_p = NULL;
1000 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1001 errmsg(
"only one AS item needed for language \"%s\"",
1004 if (languageOid == INTERNALlanguageId)
1007 * In PostgreSQL versions before 6.5, the SQL name of the created
1008 * function could not be different from the internal name, and
1009 * "prosrc" wasn't used. So there is code out there that does
1010 * CREATE FUNCTION xyz AS '' LANGUAGE internal. To preserve some
1011 * modicum of backwards compatibility, accept an empty "prosrc"
1012 * value as meaning the supplied SQL function name.
1014 if (strlen(*prosrc_str_p) == 0)
1023 * Execute a CREATE FUNCTION (or CREATE PROCEDURE) utility statement.
1035 Oid languageValidator;
1036 Node *transformDefElem = NULL;
1041 List *parameterTypes_list =
NIL;
1045 List *inParameterNames_list =
NIL;
1046 List *parameterDefaults;
1047 Oid variadicArgType;
1051 Oid requiredResultType;
1066 /* Convert list of names to a name and namespace */
1070 /* Check we have creation rights in target namespace */
1076 /* Set default attributes */
1079 isWindowFunc =
false;
1082 isLeakProof =
false;
1083 volatility = PROVOLATILE_VOLATILE;
1085 procost = -1;
/* indicates not set */
1086 prorows = -1;
/* indicates not set */
1088 parallel = PROPARALLEL_UNSAFE;
1090 /* Extract non-default attributes from stmt->options list */
1094 &as_clause, &language, &transformDefElem,
1095 &isWindowFunc, &volatility,
1096 &isStrict, &security, &isLeakProof,
1097 &proconfig, &procost, &prorows,
1098 &prosupport, ¶llel);
1106 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1107 errmsg(
"no language specified")));
1110 /* Look up the language and validate permissions */
1114 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1115 errmsg(
"language \"%s\" does not exist", language),
1117 errhint(
"Use CREATE EXTENSION to load the language into the database.") : 0)));
1120 languageOid = languageStruct->oid;
1122 if (languageStruct->lanpltrusted)
1124 /* if trusted language, need USAGE privilege */
1128 NameStr(languageStruct->lanname));
1132 /* if untrusted language, must be superuser */
1135 NameStr(languageStruct->lanname));
1138 languageValidator = languageStruct->lanvalidator;
1143 * Only superuser is allowed to create leakproof functions because
1144 * leakproof functions can see tuples which have not yet been filtered out
1145 * by security barrier views or row-level security policies.
1149 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1150 errmsg(
"only superuser can define a leakproof function")));
1152 if (transformDefElem)
1163 typeid = elt ? elt :
typeid;
1165 trftypes_list =
lappend_oid(trftypes_list,
typeid);
1166 trfoids_list =
lappend_oid(trfoids_list, transformid);
1171 * Convert remaining parameters of CREATE to form wanted by
1179 ¶meterTypes_list,
1183 &inParameterNames_list,
1186 &requiredResultType);
1188 if (
stmt->is_procedure)
1191 prorettype = requiredResultType ? requiredResultType : VOIDOID;
1194 else if (
stmt->returnType)
1196 /* explicit RETURNS clause */
1198 &prorettype, &returnsSet);
1199 if (
OidIsValid(requiredResultType) && prorettype != requiredResultType)
1201 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1202 errmsg(
"function result type must be %s because of OUT parameters",
1207 /* default RETURNS clause from OUT parameters */
1208 prorettype = requiredResultType;
1214 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1215 errmsg(
"function result type must be specified")));
1216 /* Alternative possibility: default to RETURNS VOID */
1217 prorettype = VOIDOID;
1221 if (trftypes_list !=
NIL)
1229 foreach(lc, trftypes_list)
1235 /* store SQL NULL instead of empty array */
1240 parameterTypes_list, inParameterNames_list,
1241 &prosrc_str, &probin_str, &prosqlbody,
1245 * Set default values for COST and ROWS depending on other parameters;
1246 * reject ROWS if it's not returnsSet. NB: pg_dump knows these default
1247 * values, keep it in sync if you change them.
1251 /* SQL and PL-language functions are assumed more expensive */
1252 if (languageOid == INTERNALlanguageId ||
1253 languageOid == ClanguageId)
1263 prorows = 0;
/* dummy value if not returnsSet */
1265 else if (!returnsSet)
1267 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1268 errmsg(
"ROWS is not applicable when function does not return a set")));
1271 * And now that we have all the parameters, and know we're permitted to do
1272 * so, go ahead and create the function.
1282 prosrc_str,
/* converted to text later */
1283 probin_str,
/* converted to text later */
1285 stmt->is_procedure ? PROKIND_PROCEDURE : (isWindowFunc ? PROKIND_WINDOW : PROKIND_FUNCTION),
1305 * Guts of function deletion.
1307 * Note: this is also used for aggregate deletion, since the OIDs of
1308 * both functions and aggregates point to pg_proc.
1318 * Delete the pg_proc tuple.
1324 elog(
ERROR,
"cache lookup failed for function %u", funcOid);
1337 * If there's a pg_aggregate tuple, delete that too.
1339 if (prokind == PROKIND_AGGREGATE)
1345 elog(
ERROR,
"cache lookup failed for pg_aggregate tuple for function %u", funcOid);
1356 * Implements the ALTER FUNCTION utility command (except for the
1357 * RENAME and OWNER clauses, which are handled as part of the generic
1369 DefElem *volatility_item = NULL;
1371 DefElem *security_def_item = NULL;
1372 DefElem *leakproof_item = NULL;
1377 DefElem *parallel_item = NULL;
1388 elog(
ERROR,
"cache lookup failed for function %u", funcOid);
1392 /* Permission check: must own function */
1397 if (procForm->prokind == PROKIND_AGGREGATE)
1399 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1400 errmsg(
"\"%s\" is an aggregate function",
1403 is_procedure = (procForm->prokind == PROKIND_PROCEDURE);
1405 /* Examine requested actions. */
1406 foreach(l,
stmt->actions)
1421 ¶llel_item) ==
false)
1425 if (volatility_item)
1428 procForm->proisstrict =
boolVal(strict_item->
arg);
1429 if (security_def_item)
1430 procForm->prosecdef =
boolVal(security_def_item->
arg);
1433 procForm->proleakproof =
boolVal(leakproof_item->
arg);
1434 if (procForm->proleakproof && !
superuser())
1436 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1437 errmsg(
"only superuser can define a leakproof function")));
1442 if (procForm->procost <= 0)
1444 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1445 errmsg(
"COST must be positive")));
1450 if (procForm->prorows <= 0)
1452 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1453 errmsg(
"ROWS must be positive")));
1454 if (!procForm->proretset)
1456 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1457 errmsg(
"ROWS is not applicable when function does not return a set")));
1461 /* interpret_func_support handles the privilege check */
1464 /* Add or replace dependency on support function */
1468 ProcedureRelationId, procForm->prosupport,
1470 elog(
ERROR,
"could not change support dependency for function %s",
1477 referenced.
classId = ProcedureRelationId;
1483 procForm->prosupport = newsupport;
1492 Datum repl_val[Natts_pg_proc];
1493 bool repl_null[Natts_pg_proc];
1494 bool repl_repl[Natts_pg_proc];
1496 /* extract existing proconfig setting */
1497 datum =
SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_proconfig, &isnull);
1500 /* update according to each SET or RESET item, left to right */
1503 /* update the tuple */
1504 memset(repl_repl,
false,
sizeof(repl_repl));
1505 repl_repl[Anum_pg_proc_proconfig - 1] =
true;
1509 repl_val[Anum_pg_proc_proconfig - 1] = (
Datum) 0;
1510 repl_null[Anum_pg_proc_proconfig - 1] =
true;
1515 repl_null[Anum_pg_proc_proconfig - 1] =
false;
1519 repl_val, repl_null, repl_repl);
1521 /* DO NOT put more touches of procForm below here; it's now dangling. */
1560 /* No pseudo-types allowed */
1561 if (sourcetyptype == TYPTYPE_PSEUDO)
1563 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1564 errmsg(
"source data type %s is a pseudo-type",
1567 if (targettyptype == TYPTYPE_PSEUDO)
1569 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1570 errmsg(
"target data type %s is a pseudo-type",
1573 /* Permission check */
1577 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1578 errmsg(
"must be owner of type %s or type %s",
1590 /* Domains are allowed for historical reasons, but we warn */
1591 if (sourcetyptype == TYPTYPE_DOMAIN)
1593 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1594 errmsg(
"cast will be ignored because the source data type is a domain")));
1596 else if (targettyptype == TYPTYPE_DOMAIN)
1598 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1599 errmsg(
"cast will be ignored because the target data type is a domain")));
1601 /* Determine the cast method */
1602 if (
stmt->func != NULL)
1603 castmethod = COERCION_METHOD_FUNCTION;
1604 else if (
stmt->inout)
1605 castmethod = COERCION_METHOD_INOUT;
1607 castmethod = COERCION_METHOD_BINARY;
1609 if (castmethod == COERCION_METHOD_FUNCTION)
1617 elog(
ERROR,
"cache lookup failed for function %u", funcid);
1620 nargs = procstruct->pronargs;
1621 if (nargs < 1 || nargs > 3)
1623 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1624 errmsg(
"cast function must take one to three arguments")));
1626 procstruct->proargtypes.values[0],
1629 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1630 errmsg(
"argument of cast function must match or be binary-coercible from source data type")));
1631 if (nargs > 1 && procstruct->proargtypes.values[1] != INT4OID)
1633 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1634 errmsg(
"second argument of cast function must be type %s",
1636 if (nargs > 2 && procstruct->proargtypes.values[2] != BOOLOID)
1638 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1639 errmsg(
"third argument of cast function must be type %s",
1645 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1646 errmsg(
"return data type of cast function must match or be binary-coercible to target data type")));
1649 * Restricting the volatility of a cast function may or may not be a
1650 * good idea in the abstract, but it definitely breaks many old
1651 * user-defined types. Disable this check --- tgl 2/1/03
1654 if (procstruct->provolatile == PROVOLATILE_VOLATILE)
1656 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1657 errmsg(
"cast function must not be volatile")));
1659 if (procstruct->prokind != PROKIND_FUNCTION)
1661 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1662 errmsg(
"cast function must be a normal function")));
1663 if (procstruct->proretset)
1665 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1666 errmsg(
"cast function must not return a set")));
1676 if (castmethod == COERCION_METHOD_BINARY)
1686 * Must be superuser to create binary-compatible casts, since
1687 * erroneous casts can easily crash the backend.
1691 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1692 errmsg(
"must be superuser to create a cast WITHOUT FUNCTION")));
1695 * Also, insist that the types match as to size, alignment, and
1696 * pass-by-value attributes; this provides at least a crude check that
1697 * they have similar representations. A pair of types that fail this
1698 * test should certainly not be equated.
1702 if (typ1len != typ2len ||
1703 typ1byval != typ2byval ||
1704 typ1align != typ2align)
1706 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1707 errmsg(
"source and target data types are not physically compatible")));
1710 * We know that composite, array, range and enum types are never
1711 * binary-compatible with each other. They all have OIDs embedded in
1714 * Theoretically you could build a user-defined base type that is
1715 * binary-compatible with such a type. But we disallow it anyway, as
1716 * in practice such a cast is surely a mistake. You can always work
1717 * around that by writing a cast function.
1719 * NOTE: if we ever have a kind of container type that doesn't need to
1720 * be rejected for this reason, we'd likely need to recursively apply
1721 * all of these same checks to the contained type(s).
1723 if (sourcetyptype == TYPTYPE_COMPOSITE ||
1724 targettyptype == TYPTYPE_COMPOSITE)
1726 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1727 errmsg(
"composite data types are not binary-compatible")));
1732 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1733 errmsg(
"array data types are not binary-compatible")));
1735 if (sourcetyptype == TYPTYPE_RANGE ||
1736 targettyptype == TYPTYPE_RANGE ||
1737 sourcetyptype == TYPTYPE_MULTIRANGE ||
1738 targettyptype == TYPTYPE_MULTIRANGE)
1740 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1741 errmsg(
"range data types are not binary-compatible")));
1743 if (sourcetyptype == TYPTYPE_ENUM ||
1744 targettyptype == TYPTYPE_ENUM)
1746 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1747 errmsg(
"enum data types are not binary-compatible")));
1750 * We also disallow creating binary-compatibility casts involving
1751 * domains. Casting from a domain to its base type is already
1752 * allowed, and casting the other way ought to go through domain
1753 * coercion to permit constraint checking. Again, if you're intent on
1754 * having your own semantics for that, create a no-op cast function.
1756 * NOTE: if we were to relax this, the above checks for composites
1757 * etc. would have to be modified to look through domains to their
1760 if (sourcetyptype == TYPTYPE_DOMAIN ||
1761 targettyptype == TYPTYPE_DOMAIN)
1763 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1764 errmsg(
"domain data types must not be marked binary-compatible")));
1768 * Allow source and target types to be same only for length coercion
1769 * functions. We assume a multi-arg function does length coercion.
1771 if (sourcetypeid == targettypeid && nargs < 2)
1773 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1774 errmsg(
"source data type and target data type are the same")));
1776 /* convert CoercionContext enum to char value for castcontext */
1777 switch (
stmt->context)
1780 castcontext = COERCION_CODE_IMPLICIT;
1783 castcontext = COERCION_CODE_ASSIGNMENT;
1785 /* COERCION_PLPGSQL is intentionally not covered here */
1787 castcontext = COERCION_CODE_EXPLICIT;
1790 elog(
ERROR,
"unrecognized CoercionContext: %d",
stmt->context);
1791 castcontext = 0;
/* keep compiler quiet */
1795 myself =
CastCreate(sourcetypeid, targettypeid, funcid, incastid, outcastid,
1804 if (procstruct->provolatile == PROVOLATILE_VOLATILE)
1806 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1807 errmsg(
"transform function must not be volatile")));
1808 if (procstruct->prokind != PROKIND_FUNCTION)
1810 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1811 errmsg(
"transform function must be a normal function")));
1812 if (procstruct->proretset)
1814 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1815 errmsg(
"transform function must not return a set")));
1816 if (procstruct->pronargs != 1)
1818 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1819 errmsg(
"transform function must take one argument")));
1820 if (procstruct->proargtypes.values[0] != INTERNALOID)
1822 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1823 errmsg(
"first argument of transform function must be type %s",
1842 bool nulls[Natts_pg_transform] = {0};
1843 bool replaces[Natts_pg_transform] = {0};
1859 if (typtype == TYPTYPE_PSEUDO)
1861 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1862 errmsg(
"data type %s is a pseudo-type",
1865 if (typtype == TYPTYPE_DOMAIN)
1867 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1868 errmsg(
"data type %s is a domain",
1903 elog(
ERROR,
"cache lookup failed for function %u", fromsqlfuncid);
1905 if (procstruct->prorettype != INTERNALOID)
1907 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1908 errmsg(
"return data type of FROM SQL function must be %s",
1929 elog(
ERROR,
"cache lookup failed for function %u", tosqlfuncid);
1931 if (procstruct->prorettype !=
typeid)
1933 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1934 errmsg(
"return data type of TO SQL function must be the transform data type")));
1961 errmsg(
"transform for type %s language \"%s\" already exists",
1965 replaces[Anum_pg_transform_trffromsql - 1] =
true;
1966 replaces[Anum_pg_transform_trftosql - 1] =
true;
1971 transformid = form->oid;
1978 Anum_pg_transform_oid);
1990 /* make dependency entries */
1993 /* dependency on language */
1997 /* dependency on type */
2001 /* dependencies on functions */
2016 /* dependency on extension */
2019 /* Post creation hook for new transform */
2031 * get_transform_oid - given type OID and language OID, look up a transform OID
2033 * If missing_ok is false, throw an error if the transform is not found. If
2034 * true, just return InvalidOid.
2046 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2047 errmsg(
"transform for type %s language \"%s\" does not exist",
2055 * Subroutine for ALTER FUNCTION/AGGREGATE SET SCHEMA/RENAME
2057 * Is there a function with the given name and signature already in the given
2058 * namespace? If so, raise an appropriate error message.
2064 /* check for duplicate name (more friendly than unique-index failure) */
2070 (
errcode(ERRCODE_DUPLICATE_FUNCTION),
2071 errmsg(
"function %s already exists in schema \"%s\"",
2079 * Execute inline procedural-language code
2081 * See at ExecuteCallStmt() about the atomic argument.
2089 DefElem *language_item = NULL;
2095 /* Process options we got from gram.y */
2100 if (strcmp(defel->
defname,
"as") == 0)
2106 else if (strcmp(defel->
defname,
"language") == 0)
2110 language_item = defel;
2113 elog(
ERROR,
"option \"%s\" not recognized",
2121 (
errcode(ERRCODE_SYNTAX_ERROR),
2122 errmsg(
"no inline code specified")));
2124 /* if LANGUAGE option wasn't specified, use the default */
2128 language =
"plpgsql";
2130 /* Look up the language and validate permissions */
2134 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2135 errmsg(
"language \"%s\" does not exist", language),
2137 errhint(
"Use CREATE EXTENSION to load the language into the database.") : 0)));
2140 codeblock->
langOid = languageStruct->oid;
2142 codeblock->
atomic = atomic;
2144 if (languageStruct->lanpltrusted)
2146 /* if trusted language, need USAGE privilege */
2153 NameStr(languageStruct->lanname));
2157 /* if untrusted language, must be superuser */
2160 NameStr(languageStruct->lanname));
2163 /* get the handler function's OID */
2164 laninline = languageStruct->laninline;
2167 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2168 errmsg(
"language \"%s\" does not support inline code execution",
2169 NameStr(languageStruct->lanname))));
2173 /* execute the inline handler */
2178 * Execute CALL statement
2180 * Inside a top-level CALL statement, transaction-terminating commands such as
2181 * COMMIT or a PL-specific equivalent are allowed. The terminology in the SQL
2182 * standard is that CALL establishes a non-atomic execution context. Most
2183 * other commands establish an atomic execution context, in which transaction
2184 * control actions are not allowed. If there are nested executions of CALL,
2185 * we want to track the execution context recursively, so that the nested
2186 * CALLs can also do transaction control. Note, however, that for example in
2187 * CALL -> SELECT -> CALL, the second call cannot do transaction control,
2188 * because the SELECT in between establishes an atomic execution context.
2190 * So when ExecuteCallStmt() is called from the top level, we pass in atomic =
2191 * false (recall that that means transactions = yes). We then create a
2192 * CallContext node with content atomic = false, which is passed in the
2193 * fcinfo->context field to the procedure invocation. The language
2194 * implementation should then take appropriate measures to allow or prevent
2195 * transaction commands based on that information, e.g., call
2196 * SPI_connect_ext(SPI_OPT_NONATOMIC). The language should also pass on the
2197 * atomic flag to any nested invocations to CALL.
2199 * The expression data structures and execution context that we create
2200 * within this function are children of the portalContext of the Portal
2201 * that the CALL utility statement runs in. Therefore, any pass-by-ref
2202 * values that we're passing to the procedure will survive transaction
2203 * commits that might occur inside the procedure.
2222 fexpr =
stmt->funcexpr;
2230 /* Prep the context object we'll pass to the procedure */
2232 callcontext->
atomic = atomic;
2239 * If proconfig is set we can't allow transaction commands because of the
2240 * way the GUC stacking works: The transaction boundary would have to pop
2241 * the proconfig setting off the stack. That restriction could be lifted
2242 * by redesigning the GUC nesting mechanism a bit.
2245 callcontext->
atomic =
true;
2248 * In security definer procedures, we can't allow transaction commands.
2249 * StartTransaction() insists that the security context stack is empty,
2250 * and AbortTransaction() resets the security context. This could be
2251 * reorganized, but right now it doesn't work.
2254 callcontext->
atomic =
true;
2258 /* safety check; see ExecInitFunc() */
2262 (
errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2263 errmsg_plural(
"cannot pass more than %d argument to a procedure",
2264 "cannot pass more than %d arguments to a procedure",
2268 /* Initialize function call structure */
2273 (
Node *) callcontext, NULL);
2276 * Evaluate procedure arguments inside a suitable execution context. Note
2277 * we can't free this context till the procedure returns.
2284 * If we're called in non-atomic context, we also have to ensure that the
2285 * argument expressions run with an up-to-date snapshot. Our caller will
2286 * have provided a current snapshot in atomic contexts, but not in
2287 * non-atomic contexts, because the possibility of a COMMIT/ROLLBACK
2288 * destroying the snapshot makes higher-level management too complicated.
2294 foreach(lc, fexpr->
args)
2304 fcinfo->args[
i].value =
val;
2305 fcinfo->args[
i].isnull = isnull;
2310 /* Get rid of temporary snapshot for arguments, if we made one */
2314 /* Here we actually call the procedure */
2319 /* Handle the procedure's outputs */
2320 if (fexpr->funcresulttype == VOIDOID)
2324 else if (fexpr->funcresulttype == RECORDOID)
2326 /* send tuple to client */
2336 elog(
ERROR,
"procedure returned null record");
2339 * Ensure there's an active snapshot whilst we execute whatever's
2340 * involved here. Note that this is *not* sufficient to make the
2341 * world safe for TOAST pointers to be included in the returned data:
2342 * the referenced data could have gone away while we didn't hold a
2343 * snapshot. Hence, it's incumbent on PLs that can do COMMIT/ROLLBACK
2344 * to not return TOAST pointers, unless those pointers were fetched
2345 * after the last COMMIT/ROLLBACK in the procedure.
2347 * XXX that is a really nasty, hard-to-test requirement. Is there a
2373 elog(
ERROR,
"unexpected result type for procedure: %u",
2374 fexpr->funcresulttype);
2380 * Construct the tuple descriptor for a CALL statement return
2389 fexpr =
stmt->funcexpr;
2400 * The result of build_function_result_tupdesc_t has the right column
2401 * names, but it just has the declared output argument types, which is the
2402 * wrong thing in polymorphic cases. Get the correct types by examining
2403 * stmt->outargs. We intentionally keep the atttypmod as -1 and the
2404 * attcollation as the type's default, since that's always the appropriate
2405 * thing for function outputs; there's no point in considering any
2406 * additional info available from outargs. Note that tupdesc is null if
2407 * there are no outargs.
2412 for (
int i = 0;
i < tupdesc->
natts;
i++)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
#define DatumGetArrayTypeP(X)
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
const char * GetCommandTagName(CommandTag commandTag)
List * defGetQualifiedName(DefElem *def)
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
double defGetNumeric(DefElem *def)
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
ObjectAddresses * new_object_addresses(void)
void free_object_addresses(ObjectAddresses *addrs)
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
void end_tup_output(TupOutputState *tstate)
const TupleTableSlotOps TTSOpsHeapTuple
TupOutputState * begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
TupleTableSlot * ExecStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
ExprContext * CreateExprContext(EState *estate)
void FreeExecutorState(EState *estate)
EState * CreateExecutorState(void)
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
bool extension_file_exists(const char *extensionName)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
#define OidFunctionCall1(functionId, arg1)
#define DatumGetHeapTupleHeader(X)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
#define LOCAL_FCINFO(name, nargs)
#define FunctionCallInvoke(fcinfo)
#define fmgr_info_set_expr(expr, finfo)
TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple)
void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest)
ObjectAddress CreateCast(CreateCastStmt *stmt)
static void compute_return_type(TypeName *returnType, Oid languageOid, Oid *prorettype_p, bool *returnsSet_p)
static Oid interpret_func_support(DefElem *defel)
static void compute_function_attributes(ParseState *pstate, bool is_procedure, List *options, List **as, char **language, Node **transform, bool *windowfunc_p, char *volatility_p, bool *strict_p, bool *security_definer, bool *leakproof_p, ArrayType **proconfig, float4 *procost, float4 *prorows, Oid *prosupport, char *parallel_p)
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)
static bool compute_common_attribute(ParseState *pstate, bool is_procedure, DefElem *defel, DefElem **volatility_item, DefElem **strict_item, DefElem **security_item, DefElem **leakproof_item, List **set_items, DefElem **cost_item, DefElem **rows_item, DefElem **support_item, DefElem **parallel_item)
static char interpret_func_volatility(DefElem *defel)
ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
ObjectAddress AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
TupleDesc CallStmtResultDesc(CallStmt *stmt)
static void interpret_AS_clause(Oid languageOid, const char *languageName, char *funcname, List *as, Node *sql_body_in, List *parameterTypes, List *inParameterNames, char **prosrc_str_p, char **probin_str_p, Node **sql_body_out, const char *queryString)
Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)
void ExecuteDoStmt(ParseState *pstate, DoStmt *stmt, bool atomic)
static void check_transform_function(Form_pg_proc procstruct)
ObjectAddress CreateTransform(CreateTransformStmt *stmt)
static ArrayType * update_proconfig_value(ArrayType *a, List *set_items)
void RemoveFunctionById(Oid funcOid)
static char interpret_func_parallel(DefElem *defel)
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
SQLFunctionParseInfo * SQLFunctionParseInfoPtr
void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
ArrayType * GUCArrayAdd(ArrayType *array, const char *name, const char *value)
ArrayType * GUCArrayDelete(ArrayType *array, const char *name)
char * ExtractSetVariableArgs(VariableSetStmt *stmt)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)
static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)
static void * GETSTRUCT(const HeapTupleData *tuple)
static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
if(TABLE==NULL||TABLE_index==NULL)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
List * lappend(List *list, void *datum)
List * lappend_oid(List *list, Oid datum)
Oid get_element_type(Oid typid)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
char * get_language_name(Oid langoid, bool missing_ok)
char * get_func_name(Oid funcid)
char get_typtype(Oid typid)
Oid get_base_element_type(Oid typid)
char * get_namespace_name(Oid nspid)
Oid get_func_rettype(Oid funcid)
char * pstrdup(const char *in)
void * palloc0(Size size)
char * NameListToString(const List *names)
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
Oid exprType(const Node *expr)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define InvokeFunctionExecuteHook(objectId)
#define ObjectAddressSet(addr, class_id, object_id)
oidvector * buildoidvector(const Oid *oids, int n)
Node * coerce_to_specific_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *constructName)
bool IsBinaryCoercibleWithCast(Oid srctype, Oid targettype, Oid *castoid)
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
const char * funcname_signature_string(const char *funcname, int nargs, List *argnames, const Oid *argtypes)
const char * func_signature_string(List *funcname, int nargs, List *argnames, const Oid *argtypes)
Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok)
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
void free_parsestate(ParseState *pstate)
int parser_errposition(ParseState *pstate, int location)
ParseState * make_parsestate(ParseState *parentParseState)
@ EXPR_KIND_FUNCTION_DEFAULT
char * TypeNameToString(const TypeName *typeName)
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Query * transformStmt(ParseState *pstate, Node *parseTree)
FormData_pg_attribute * Form_pg_attribute
ObjectAddress CastCreate(Oid sourcetypeid, Oid targettypeid, Oid funcid, Oid incastid, Oid outcastid, char castcontext, char castmethod, DependencyType behavior)
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
FormData_pg_language * Form_pg_language
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
static Oid list_nth_oid(const List *list, int n)
static void * list_nth(const List *list, int n)
ObjectAddress ProcedureCreate(const char *procedureName, Oid procNamespace, bool replace, bool returnsSet, Oid returnType, Oid proowner, Oid languageObjectId, Oid languageValidator, const char *prosrc, const char *probin, Node *prosqlbody, char prokind, bool security_definer, bool isLeakProof, bool isStrict, char volatility, char parallel, oidvector *parameterTypes, Datum allParameterTypes, Datum parameterModes, Datum parameterNames, List *parameterDefaults, Datum trftypes, List *trfoids, Datum proconfig, Oid prosupport, float4 procost, float4 prorows)
FormData_pg_proc * Form_pg_proc
ObjectAddress TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
FormData_pg_type * Form_pg_type
void pgstat_drop_function(Oid proid)
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
static Datum PointerGetDatum(const void *X)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
static Datum CharGetDatum(char X)
void EnsurePortalSnapshotExists(void)
Oid get_language_oid(const char *langname, bool missing_ok)
#define RelationGetDescr(relation)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
void PopActiveSnapshot(void)
#define ERRCODE_DUPLICATE_OBJECT
ParamListInfo es_param_list_info
FunctionParameterMode mode
const char * p_sourcetext
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Oid values[FLEXIBLE_ARRAY_MEMBER]
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
#define SearchSysCacheCopy1(cacheId, key1)
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
#define ReleaseTupleDesc(tupdesc)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
CommandTag CreateCommandTag(Node *parsetree)
String * makeString(char *str)
bool contain_var_clause(Node *node)