66 #include "utils/fmgroids.h" 88 Oid *prorettype_p,
bool *returnsSet_p)
100 if (languageOid == SQLlanguageId)
102 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
103 errmsg(
"SQL function cannot return shell type %s",
107 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
108 errmsg(
"return type %s is only a shell",
128 if (languageOid != INTERNALlanguageId &&
129 languageOid != ClanguageId)
131 (
errcode(ERRCODE_UNDEFINED_OBJECT),
132 errmsg(
"type \"%s\" does not exist", typnam)));
137 (
errcode(ERRCODE_SYNTAX_ERROR),
138 errmsg(
"type modifier cannot be specified for shell type \"%s\"",
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;
191 List **parameterDefaults,
192 Oid *variadicArgType,
193 Oid *requiredResultType)
203 bool have_names =
false;
204 bool have_defaults =
false;
215 *parameterDefaults =
NIL;
219 foreach(x, parameters)
223 bool isinput =
false;
234 if (languageOid == SQLlanguageId)
236 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
237 errmsg(
"SQL function cannot accept shell type %s",
242 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
243 errmsg(
"aggregate cannot accept shell type %s",
247 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
248 errmsg(
"argument type %s is only a shell",
257 (
errcode(ERRCODE_UNDEFINED_OBJECT),
258 errmsg(
"type %s does not exist",
271 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
272 errmsg(
"aggregates cannot accept set arguments")));
275 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
276 errmsg(
"procedures cannot accept set arguments")));
279 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
280 errmsg(
"functions cannot accept set arguments")));
287 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
288 (
errmsg(
"procedures cannot have OUT arguments"),
289 errhint(
"INOUT arguments are permitted."))));
298 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
299 errmsg(
"VARIADIC parameter must be the last input parameter")));
300 inTypes[inCount++] = toid;
308 *requiredResultType = RECORDOID;
309 else if (outCount == 0)
310 *requiredResultType = toid;
316 *variadicArgType = toid;
328 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
329 errmsg(
"VARIADIC parameter must be an array")));
348 foreach(px, parameters)
365 if (prevfp->
name && prevfp->
name[0] &&
366 strcmp(prevfp->
name, fp->
name) == 0)
368 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
369 errmsg(
"parameter name \"%s\" used more than once",
383 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
384 errmsg(
"only input parameters can have default values")));
398 (
errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
399 errmsg(
"cannot use table references in parameter default value")));
415 *parameterDefaults =
lappend(*parameterDefaults, def);
416 have_defaults =
true;
420 if (isinput && have_defaults)
422 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
423 errmsg(
"input parameters after one with a default value must also have defaults")));
432 if (outCount > 0 || varCount > 0)
435 sizeof(
Oid),
true,
'i');
439 *requiredResultType = RECORDOID;
444 *allParameterTypes = NULL;
445 *parameterModes = NULL;
450 for (i = 0; i < parameterCount; i++)
459 *parameterNames = NULL;
485 if (strcmp(defel->
defname,
"volatility") == 0)
488 goto procedure_error;
489 if (*volatility_item)
490 goto duplicate_error;
492 *volatility_item = defel;
494 else if (strcmp(defel->
defname,
"strict") == 0)
497 goto procedure_error;
499 goto duplicate_error;
501 *strict_item = defel;
503 else if (strcmp(defel->
defname,
"security") == 0)
506 goto duplicate_error;
508 *security_item = defel;
510 else if (strcmp(defel->
defname,
"leakproof") == 0)
513 goto procedure_error;
515 goto duplicate_error;
517 *leakproof_item = defel;
519 else if (strcmp(defel->
defname,
"set") == 0)
523 else if (strcmp(defel->
defname,
"cost") == 0)
526 goto procedure_error;
528 goto duplicate_error;
532 else if (strcmp(defel->
defname,
"rows") == 0)
535 goto procedure_error;
537 goto duplicate_error;
541 else if (strcmp(defel->
defname,
"support") == 0)
544 goto procedure_error;
546 goto duplicate_error;
548 *support_item = defel;
550 else if (strcmp(defel->
defname,
"parallel") == 0)
553 goto procedure_error;
555 goto duplicate_error;
557 *parallel_item = defel;
567 (
errcode(ERRCODE_SYNTAX_ERROR),
568 errmsg(
"conflicting or redundant options"),
574 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
575 errmsg(
"invalid attribute in procedure definition"),
585 if (strcmp(str,
"immutable") == 0)
586 return PROVOLATILE_IMMUTABLE;
587 else if (strcmp(str,
"stable") == 0)
588 return PROVOLATILE_STABLE;
589 else if (strcmp(str,
"volatile") == 0)
590 return PROVOLATILE_VOLATILE;
593 elog(
ERROR,
"invalid volatility \"%s\"", str);
603 if (strcmp(str,
"safe") == 0)
604 return PROPARALLEL_SAFE;
605 else if (strcmp(str,
"unsafe") == 0)
606 return PROPARALLEL_UNSAFE;
607 else if (strcmp(str,
"restricted") == 0)
608 return PROPARALLEL_RESTRICTED;
612 (
errcode(ERRCODE_SYNTAX_ERROR),
613 errmsg(
"parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));
614 return PROPARALLEL_UNSAFE;
628 foreach(l, set_items)
659 argList[0] = INTERNALOID;
664 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
665 errmsg(
"function %s does not exist",
670 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
671 errmsg(
"support function %s must return type %s",
681 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
682 errmsg(
"must be superuser to specify a support function")));
702 bool *security_definer,
713 DefElem *transform_item = NULL;
714 DefElem *windowfunc_item = NULL;
715 DefElem *volatility_item = NULL;
718 DefElem *leakproof_item = NULL;
725 foreach(option, options)
729 if (strcmp(defel->
defname,
"as") == 0)
733 (
errcode(ERRCODE_SYNTAX_ERROR),
734 errmsg(
"conflicting or redundant options"),
738 else if (strcmp(defel->
defname,
"language") == 0)
742 (
errcode(ERRCODE_SYNTAX_ERROR),
743 errmsg(
"conflicting or redundant options"),
745 language_item = defel;
747 else if (strcmp(defel->
defname,
"transform") == 0)
751 (
errcode(ERRCODE_SYNTAX_ERROR),
752 errmsg(
"conflicting or redundant options"),
754 transform_item = defel;
756 else if (strcmp(defel->
defname,
"window") == 0)
760 (
errcode(ERRCODE_SYNTAX_ERROR),
761 errmsg(
"conflicting or redundant options"),
765 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
766 errmsg(
"invalid attribute in procedure definition"),
768 windowfunc_item = defel;
787 elog(
ERROR,
"option \"%s\" not recognized",
797 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
798 errmsg(
"no function body specified")));
803 *language =
strVal(language_item->arg);
807 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
808 errmsg(
"no language specified")));
814 *transform = transform_item->arg;
816 *windowfunc_p =
intVal(windowfunc_item->arg);
820 *strict_p =
intVal(strict_item->arg);
822 *security_definer =
intVal(security_item->arg);
824 *leakproof_p =
intVal(leakproof_item->arg);
832 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
833 errmsg(
"COST must be positive")));
840 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
841 errmsg(
"ROWS must be positive")));
861 char *funcname,
List *as,
862 char **prosrc_str_p,
char **probin_str_p)
866 if (languageOid == ClanguageId)
878 *prosrc_str_p = funcname;
882 if (strcmp(*prosrc_str_p,
"-") == 0)
883 *prosrc_str_p = funcname;
890 *probin_str_p = NULL;
894 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
895 errmsg(
"only one AS item needed for language \"%s\"",
898 if (languageOid == INTERNALlanguageId)
908 if (strlen(*prosrc_str_p) == 0)
909 *prosrc_str_p = funcname;
928 Oid languageValidator;
929 Node *transformDefElem = NULL;
937 List *parameterDefaults;
941 Oid requiredResultType;
967 isWindowFunc =
false;
971 volatility = PROVOLATILE_VOLATILE;
976 parallel = PROPARALLEL_UNSAFE;
982 &as_clause, &language, &transformDefElem,
983 &isWindowFunc, &volatility,
984 &isStrict, &security, &isLeakProof,
985 &proconfig, &procost, &prorows,
986 &prosupport, ¶llel);
992 (
errcode(ERRCODE_UNDEFINED_OBJECT),
993 errmsg(
"language \"%s\" does not exist", language),
995 errhint(
"Use CREATE EXTENSION to load the language into the database.") : 0)));
998 languageOid = languageStruct->oid;
1000 if (languageStruct->lanpltrusted)
1008 NameStr(languageStruct->lanname));
1015 NameStr(languageStruct->lanname));
1018 languageValidator = languageStruct->lanvalidator;
1029 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1030 errmsg(
"only superuser can define a leakproof function")));
1032 if (transformDefElem)
1042 typeid = elt ? elt :
typeid;
1045 trftypes_list =
lappend_oid(trftypes_list,
typeid);
1063 &requiredResultType);
1068 prorettype = requiredResultType ? requiredResultType : VOIDOID;
1075 &prorettype, &returnsSet);
1076 if (
OidIsValid(requiredResultType) && prorettype != requiredResultType)
1078 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1079 errmsg(
"function result type must be %s because of OUT parameters",
1085 prorettype = requiredResultType;
1091 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1092 errmsg(
"function result type must be specified")));
1094 prorettype = VOIDOID;
1106 foreach(lc, trftypes_list)
1109 OIDOID,
sizeof(
Oid),
true,
'i');
1118 &prosrc_str, &probin_str);
1128 if (languageOid == INTERNALlanguageId ||
1129 languageOid == ClanguageId)
1141 else if (!returnsSet)
1143 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1144 errmsg(
"ROWS is not applicable when function does not return a set")));
1160 stmt->
is_procedure ? PROKIND_PROCEDURE : (isWindowFunc ? PROKIND_WINDOW : PROKIND_FUNCTION),
1198 elog(
ERROR,
"cache lookup failed for function %u", funcOid);
1211 if (prokind == PROKIND_AGGREGATE)
1217 elog(
ERROR,
"cache lookup failed for pg_aggregate tuple for function %u", funcOid);
1241 DefElem *volatility_item = NULL;
1243 DefElem *security_def_item = NULL;
1244 DefElem *leakproof_item = NULL;
1249 DefElem *parallel_item = NULL;
1260 elog(
ERROR,
"cache lookup failed for function %u", funcOid);
1269 if (procForm->prokind == PROKIND_AGGREGATE)
1271 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1272 errmsg(
"\"%s\" is an aggregate function",
1275 is_procedure = (procForm->prokind == PROKIND_PROCEDURE);
1293 ¶llel_item) ==
false)
1297 if (volatility_item)
1300 procForm->proisstrict =
intVal(strict_item->
arg);
1301 if (security_def_item)
1302 procForm->prosecdef =
intVal(security_def_item->
arg);
1305 procForm->proleakproof =
intVal(leakproof_item->
arg);
1306 if (procForm->proleakproof && !
superuser())
1308 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1309 errmsg(
"only superuser can define a leakproof function")));
1314 if (procForm->procost <= 0)
1316 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1317 errmsg(
"COST must be positive")));
1322 if (procForm->prorows <= 0)
1324 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1325 errmsg(
"ROWS must be positive")));
1326 if (!procForm->proretset)
1328 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1329 errmsg(
"ROWS is not applicable when function does not return a set")));
1339 ProcedureRelationId, procForm->prosupport,
1345 referenced.
classId = ProcedureRelationId;
1351 procForm->prosupport = newsupport;
1358 Datum repl_val[Natts_pg_proc];
1359 bool repl_null[Natts_pg_proc];
1360 bool repl_repl[Natts_pg_proc];
1370 memset(repl_repl,
false,
sizeof(repl_repl));
1371 repl_repl[Anum_pg_proc_proconfig - 1] =
true;
1375 repl_val[Anum_pg_proc_proconfig - 1] = (
Datum) 0;
1376 repl_null[Anum_pg_proc_proconfig - 1] =
true;
1381 repl_null[Anum_pg_proc_proconfig - 1] =
false;
1385 repl_val, repl_null, repl_repl);
1421 elog(
ERROR,
"cache lookup failed for function %u", funcOid);
1424 if (procForm->prorettype != OPAQUEOID)
1425 elog(
ERROR,
"function %u doesn't return OPAQUE", funcOid);
1428 procForm->prorettype = newRetType;
1463 elog(
ERROR,
"cache lookup failed for function %u", funcOid);
1466 if (argIndex < 0 || argIndex >= procForm->pronargs ||
1467 procForm->proargtypes.values[argIndex] != OPAQUEOID)
1468 elog(
ERROR,
"function %u doesn't take OPAQUE", funcOid);
1471 procForm->proargtypes.values[argIndex] = newArgType;
1507 bool nulls[Natts_pg_cast];
1518 if (sourcetyptype == TYPTYPE_PSEUDO)
1520 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1521 errmsg(
"source data type %s is a pseudo-type",
1524 if (targettyptype == TYPTYPE_PSEUDO)
1526 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1527 errmsg(
"target data type %s is a pseudo-type",
1534 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1535 errmsg(
"must be owner of type %s or type %s",
1548 if (sourcetyptype == TYPTYPE_DOMAIN)
1550 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1551 errmsg(
"cast will be ignored because the source data type is a domain")));
1553 else if (targettyptype == TYPTYPE_DOMAIN)
1555 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1556 errmsg(
"cast will be ignored because the target data type is a domain")));
1559 if (stmt->
func != NULL)
1560 castmethod = COERCION_METHOD_FUNCTION;
1561 else if (stmt->
inout)
1562 castmethod = COERCION_METHOD_INOUT;
1564 castmethod = COERCION_METHOD_BINARY;
1566 if (castmethod == COERCION_METHOD_FUNCTION)
1574 elog(
ERROR,
"cache lookup failed for function %u", funcid);
1577 nargs = procstruct->pronargs;
1578 if (nargs < 1 || nargs > 3)
1580 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1581 errmsg(
"cast function must take one to three arguments")));
1584 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1585 errmsg(
"argument of cast function must match or be binary-coercible from source data type")));
1586 if (nargs > 1 && procstruct->proargtypes.values[1] != INT4OID)
1588 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1589 errmsg(
"second argument of cast function must be type %s",
1591 if (nargs > 2 && procstruct->proargtypes.values[2] != BOOLOID)
1593 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1594 errmsg(
"third argument of cast function must be type %s",
1598 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1599 errmsg(
"return data type of cast function must match or be binary-coercible to target data type")));
1607 if (procstruct->provolatile == PROVOLATILE_VOLATILE)
1609 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1610 errmsg(
"cast function must not be volatile")));
1612 if (procstruct->prokind != PROKIND_FUNCTION)
1614 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1615 errmsg(
"cast function must be a normal function")));
1616 if (procstruct->proretset)
1618 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1619 errmsg(
"cast function must not return a set")));
1629 if (castmethod == COERCION_METHOD_BINARY)
1644 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1645 errmsg(
"must be superuser to create a cast WITHOUT FUNCTION")));
1655 if (typ1len != typ2len ||
1656 typ1byval != typ2byval ||
1657 typ1align != typ2align)
1659 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1660 errmsg(
"source and target data types are not physically compatible")));
1671 if (sourcetyptype == TYPTYPE_COMPOSITE ||
1672 targettyptype == TYPTYPE_COMPOSITE)
1674 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1675 errmsg(
"composite data types are not binary-compatible")));
1677 if (sourcetyptype == TYPTYPE_ENUM ||
1678 targettyptype == TYPTYPE_ENUM)
1680 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1681 errmsg(
"enum data types are not binary-compatible")));
1686 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1687 errmsg(
"array data types are not binary-compatible")));
1700 if (sourcetyptype == TYPTYPE_DOMAIN ||
1701 targettyptype == TYPTYPE_DOMAIN)
1703 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1704 errmsg(
"domain data types must not be marked binary-compatible")));
1711 if (sourcetypeid == targettypeid && nargs < 2)
1713 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1714 errmsg(
"source data type and target data type are the same")));
1720 castcontext = COERCION_CODE_IMPLICIT;
1723 castcontext = COERCION_CODE_ASSIGNMENT;
1726 castcontext = COERCION_CODE_EXPLICIT;
1747 errmsg(
"cast from type %s to type %s already exists",
1757 values[Anum_pg_cast_castcontext - 1] =
CharGetDatum(castcontext);
1758 values[Anum_pg_cast_castmethod - 1] =
CharGetDatum(castmethod);
1760 MemSet(nulls,
false,
sizeof(nulls));
1767 myself.
classId = CastRelationId;
1772 referenced.
classId = TypeRelationId;
1773 referenced.
objectId = sourcetypeid;
1778 referenced.
classId = TypeRelationId;
1779 referenced.
objectId = targettypeid;
1786 referenced.
classId = ProcedureRelationId;
1821 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1822 errmsg(
"cast from type %s to type %s does not exist",
1847 elog(
ERROR,
"could not find tuple for cast %u", castOid);
1858 if (procstruct->provolatile == PROVOLATILE_VOLATILE)
1860 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1861 errmsg(
"transform function must not be volatile")));
1862 if (procstruct->prokind != PROKIND_FUNCTION)
1864 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1865 errmsg(
"transform function must be a normal function")));
1866 if (procstruct->proretset)
1868 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1869 errmsg(
"transform function must not return a set")));
1870 if (procstruct->pronargs != 1)
1872 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1873 errmsg(
"transform function must take one argument")));
1874 if (procstruct->proargtypes.values[0] != INTERNALOID)
1876 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1877 errmsg(
"first argument of transform function must be type %s",
1896 bool nulls[Natts_pg_transform];
1897 bool replaces[Natts_pg_transform];
1912 if (typtype == TYPTYPE_PSEUDO)
1914 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1915 errmsg(
"data type %s is a pseudo-type",
1918 if (typtype == TYPTYPE_DOMAIN)
1920 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1921 errmsg(
"data type %s is a domain",
1956 elog(
ERROR,
"cache lookup failed for function %u", fromsqlfuncid);
1958 if (procstruct->prorettype != INTERNALOID)
1960 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1961 errmsg(
"return data type of FROM SQL function must be %s",
1982 elog(
ERROR,
"cache lookup failed for function %u", tosqlfuncid);
1984 if (procstruct->prorettype !=
typeid)
1986 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1987 errmsg(
"return data type of TO SQL function must be the transform data type")));
1999 values[Anum_pg_transform_trffromsql - 1] =
ObjectIdGetDatum(fromsqlfuncid);
2002 MemSet(nulls,
false,
sizeof(nulls));
2016 errmsg(
"transform for type %s language \"%s\" already exists",
2020 MemSet(replaces,
false,
sizeof(replaces));
2021 replaces[Anum_pg_transform_trffromsql - 1] =
true;
2022 replaces[Anum_pg_transform_trftosql - 1] =
true;
2027 transformid = form->oid;
2034 Anum_pg_transform_oid);
2045 myself.
classId = TransformRelationId;
2050 referenced.
classId = LanguageRelationId;
2056 referenced.
classId = TypeRelationId;
2064 referenced.
classId = ProcedureRelationId;
2065 referenced.
objectId = fromsqlfuncid;
2071 referenced.
classId = ProcedureRelationId;
2107 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2108 errmsg(
"transform for type %s language \"%s\" does not exist",
2126 Anum_pg_transform_oid,
2134 elog(
ERROR,
"could not find tuple for transform %u", transformOid);
2158 (
errcode(ERRCODE_DUPLICATE_FUNCTION),
2159 errmsg(
"function %s already exists in schema \"%s\"",
2177 DefElem *language_item = NULL;
2184 foreach(arg, stmt->
args)
2188 if (strcmp(defel->
defname,
"as") == 0)
2192 (
errcode(ERRCODE_SYNTAX_ERROR),
2193 errmsg(
"conflicting or redundant options")));
2196 else if (strcmp(defel->
defname,
"language") == 0)
2200 (
errcode(ERRCODE_SYNTAX_ERROR),
2201 errmsg(
"conflicting or redundant options")));
2202 language_item = defel;
2205 elog(
ERROR,
"option \"%s\" not recognized",
2213 (
errcode(ERRCODE_SYNTAX_ERROR),
2214 errmsg(
"no inline code specified")));
2220 language =
"plpgsql";
2226 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2227 errmsg(
"language \"%s\" does not exist", language),
2229 errhint(
"Use CREATE EXTENSION to load the language into the database.") : 0)));
2232 codeblock->
langOid = languageStruct->oid;
2234 codeblock->
atomic = atomic;
2236 if (languageStruct->lanpltrusted)
2245 NameStr(languageStruct->lanname));
2252 NameStr(languageStruct->lanname));
2256 laninline = languageStruct->laninline;
2259 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2260 errmsg(
"language \"%s\" does not support inline code execution",
2261 NameStr(languageStruct->lanname))));
2324 callcontext->
atomic = atomic;
2337 callcontext->
atomic =
true;
2346 callcontext->
atomic =
true;
2357 memcpy(nexpr, fexpr,
sizeof(
FuncExpr));
2371 (
errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2372 errmsg_plural(
"cannot pass more than %d argument to a procedure",
2373 "cannot pass more than %d arguments to a procedure",
2382 (
Node *) callcontext, NULL);
2393 foreach(lc, fexpr->args)
2403 fcinfo->args[
i].value =
val;
2404 fcinfo->args[
i].isnull = isnull;
2413 if (fexpr->funcresulttype == VOIDOID)
2417 else if (fexpr->funcresulttype == RECORDOID)
2432 elog(
ERROR,
"procedure returned null record");
2455 elog(
ERROR,
"unexpected result type for procedure: %u",
2456 fexpr->funcresulttype);
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
#define IsA(nodeptr, _type_)
ArrayType * GUCArrayAdd(ArrayType *array, const char *name, const char *value)
ObjectAddress CreateTransform(CreateTransformStmt *stmt)
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
void table_close(Relation relation, LOCKMODE lockmode)
int errhint(const char *fmt,...)
static void check_transform_function(Form_pg_proc procstruct)
void systable_endscan(SysScanDesc sysscan)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
List * expand_function_arguments(List *args, Oid result_type, HeapTuple func_tuple)
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
char * get_language_name(Oid langoid, bool missing_ok)
ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
#define RelationGetDescr(relation)
void DropTransformById(Oid transformOid)
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
#define castNode(_type_, nodeptr)
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Oid get_element_type(Oid typid)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
#define PointerGetDatum(X)
char * TypeNameToString(const TypeName *typeName)
double defGetNumeric(DefElem *def)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
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, 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, Datum proconfig, Oid prosupport, float4 procost, float4 prorows)
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Oid get_language_oid(const char *langname, bool missing_ok)
static void compute_return_type(TypeName *returnType, Oid languageOid, Oid *prorettype_p, bool *returnsSet_p)
TupleDesc CallStmtResultDesc(CallStmt *stmt)
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest)
int errcode(int sqlerrcode)
char get_typtype(Oid typid)
#define MemSet(start, val, len)
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
static void interpret_AS_clause(Oid languageOid, const char *languageName, char *funcname, List *as, char **prosrc_str_p, char **probin_str_p)
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
bool contain_var_clause(Node *node)
void heap_freetuple(HeapTuple htup)
ObjectAddress TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
bool pg_type_ownercheck(Oid type_oid, Oid roleid)
List * lappend_oid(List *list, Oid datum)
#define OidIsValid(objectId)
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
#define DatumGetHeapTupleHeader(X)
AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Oid get_func_rettype(Oid funcid)
#define HeapTupleHeaderGetTypMod(tup)
void assign_expr_collations(ParseState *pstate, Node *expr)
void FreeExecutorState(EState *estate)
Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
HeapTuple systable_getnext(SysScanDesc sysscan)
TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple)
void end_tup_output(TupOutputState *tstate)
#define ObjectIdGetDatum(X)
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
char * get_func_name(Oid funcid)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
static Oid interpret_func_support(DefElem *defel)
TupOutputState * begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
#define OidFunctionCall1(functionId, arg1)
#define lfirst_node(type, lc)
void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType)
char * get_namespace_name(Oid nspid)
#define FunctionCallInvoke(fcinfo)
Oid values[FLEXIBLE_ARRAY_MEMBER]
int errdetail(const char *fmt,...)
#define fmgr_info_set_expr(expr, finfo)
#define CStringGetDatum(X)
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)
#define TransformOidIndexId
const char * funcname_signature_string(const char *funcname, int nargs, List *argnames, const Oid *argtypes)
void ExecuteDoStmt(DoStmt *stmt, bool atomic)
#define ereport(elevel, rest)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
static char interpret_func_volatility(DefElem *defel)
EState * CreateExecutorState(void)
#define InvokeFunctionExecuteHook(objectId)
const char * func_signature_string(List *funcname, int nargs, List *argnames, const Oid *argtypes)
bool IsBinaryCoercible(Oid srctype, Oid targettype)
List * lappend(List *list, void *datum)
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
char * NameListToString(List *names)
ArrayType * GUCArrayDelete(ArrayType *array, const char *name)
void * palloc0(Size size)
void ReleaseSysCache(HeapTuple tuple)
static ArrayType * update_proconfig_value(ArrayType *a, List *set_items)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
#define HeapTupleHeaderGetTypeId(tup)
void SetFunctionReturnType(Oid funcOid, Oid newRetType)
bool PLTemplateExists(const char *languageName)
FormData_pg_proc * Form_pg_proc
void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
ObjectAddress CreateCast(CreateCastStmt *stmt)
#define LOCAL_FCINFO(name, nargs)
#define HeapTupleIsValid(tuple)
#define Assert(condition)
oidvector * buildoidvector(const Oid *oids, int n)
void interpret_function_parameter_list(ParseState *pstate, List *parameters, Oid languageOid, ObjectType objtype, oidvector **parameterTypes, ArrayType **allParameterTypes, ArrayType **parameterModes, ArrayType **parameterNames, List **parameterDefaults, Oid *variadicArgType, Oid *requiredResultType)
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
List * defGetQualifiedName(DefElem *def)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
FormData_pg_type * Form_pg_type
static int list_length(const List *l)
int parser_errposition(ParseState *pstate, int location)
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
#define ObjectAddressSet(addr, class_id, object_id)
void RemoveFunctionById(Oid funcOid)
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
static Datum values[MAXATTR]
Oid get_base_element_type(Oid typid)
#define SearchSysCacheCopy1(cacheId, key1)
#define ItemPointerSetInvalid(pointer)
FormData_pg_language * Form_pg_language
int errmsg(const char *fmt,...)
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok)
const TupleTableSlotOps TTSOpsHeapTuple
ExprContext * CreateExprContext(EState *estate)
Node * coerce_to_specific_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *constructName)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
#define CStringGetTextDatum(s)
Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
ParamListInfo es_param_list_info
void DropCastById(Oid castOid)
FunctionParameterMode mode
AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode)
#define ReleaseTupleDesc(tupdesc)
Relation table_open(Oid relationId, LOCKMODE lockmode)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
char * ExtractSetVariableArgs(VariableSetStmt *stmt)
#define ERRCODE_DUPLICATE_OBJECT
ObjectAddress AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
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)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
TupleTableSlot * ExecStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
#define BTEqualStrategyNumber
bool pg_proc_ownercheck(Oid proc_oid, Oid roleid)
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
#define HeapTupleHeaderGetDatumLength(tup)
static char interpret_func_parallel(DefElem *defel)
#define DatumGetArrayTypeP(X)