PostgreSQL Source Code: src/backend/commands/functioncmds.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
34
74
75
76
77
78
79
80
81
82
83
84
85
86
87static void
89 Oid *prorettype_p, bool *returnsSet_p)
90{
91 Oid rettype;
94
95 typtup = LookupTypeName(NULL, returnType, NULL, false);
96
97 if (typtup)
98 {
100 {
101 if (languageOid == SQLlanguageId)
103 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
104 errmsg("SQL function cannot return shell type %s",
106 else
108 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
109 errmsg("return type %s is only a shell",
111 }
114 }
115 else
116 {
118 Oid namespaceId;
121
122
123
124
125
126
127
128 if (languageOid != INTERNALlanguageId &&
129 languageOid != ClanguageId)
131 (errcode(ERRCODE_UNDEFINED_OBJECT),
132 errmsg("type \"%s\" does not exist", typnam)));
133
134
137 (errcode(ERRCODE_SYNTAX_ERROR),
138 errmsg("type modifier cannot be specified for shell type \"%s\"",
139 typnam)));
140
141
143 (errcode(ERRCODE_UNDEFINED_OBJECT),
144 errmsg("type \"%s\" is not yet defined", typnam),
145 errdetail("Creating a shell type definition.")));
156
158 }
159
163
164 *prorettype_p = rettype;
165 *returnsSet_p = returnType->setof;
166}
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184void
186 List *parameters,
187 Oid languageOid,
190 List **parameterTypes_list,
194 List **inParameterNames_list,
195 List **parameterDefaults,
196 Oid *variadicArgType,
197 Oid *requiredResultType)
198{
199 int parameterCount = list_length(parameters);
200 Oid *inTypes;
201 int inCount = 0;
203 Datum *paramModes;
204 Datum *paramNames;
205 int outCount = 0;
206 int varCount = 0;
207 bool have_names = false;
208 bool have_defaults = false;
210 int i;
211
212 *variadicArgType = InvalidOid;
213 *requiredResultType = InvalidOid;
214
215 inTypes = (Oid *) palloc(parameterCount * sizeof(Oid));
217 paramModes = (Datum *) palloc(parameterCount * sizeof(Datum));
219 *parameterDefaults = NIL;
220
221
222 i = 0;
223 foreach(x, parameters)
224 {
228 bool isinput = false;
229 Oid toid;
232
233
236
238 if (typtup)
239 {
241 {
242
243 if (languageOid == SQLlanguageId)
245 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
246 errmsg("SQL function cannot accept shell type %s",
249
252 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
253 errmsg("aggregate cannot accept shell type %s",
256 else
258 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
259 errmsg("argument type %s is only a shell",
262 }
265 }
266 else
267 {
269 (errcode(ERRCODE_UNDEFINED_OBJECT),
270 errmsg("type %s does not exist",
273 toid = InvalidOid;
274 }
275
279
281 {
284 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
285 errmsg("aggregates cannot accept set arguments"),
289 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
290 errmsg("procedures cannot accept set arguments"),
292 else
294 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
295 errmsg("functions cannot accept set arguments"),
297 }
298
299
301 {
302
303 if (varCount > 0)
305 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
306 errmsg("VARIADIC parameter must be the last input parameter"),
308 inTypes[inCount++] = toid;
309 isinput = true;
310 if (parameterTypes_list)
311 *parameterTypes_list = lappend_oid(*parameterTypes_list, toid);
312 }
313
314
316 {
318 {
319
320
321
322
323
324 if (varCount > 0)
326 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
327 errmsg("VARIADIC parameter must be the last parameter"),
329
330 *requiredResultType = RECORDOID;
331 }
332 else if (outCount == 0)
333 *requiredResultType = toid;
334 outCount++;
335 }
336
338 {
339 *variadicArgType = toid;
340 varCount++;
341
342 switch (toid)
343 {
344 case ANYARRAYOID:
345 case ANYCOMPATIBLEARRAYOID:
346 case ANYOID:
347
348 break;
349 default:
352 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
353 errmsg("VARIADIC parameter must be an array"),
355 break;
356 }
357 }
358
360
362
364 {
366
367
368
369
370
371
372
373 foreach(px, parameters)
374 {
377
378 if (prevfp == fp)
379 break;
380
381 prevfpmode = prevfp->mode;
384
389 continue;
394 continue;
395 if (prevfp->name && prevfp->name[0] &&
396 strcmp(prevfp->name, fp->name) == 0)
398 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
399 errmsg("parameter name \"%s\" used more than once",
402 }
403
405 have_names = true;
406 }
407
408 if (inParameterNames_list)
410
412 {
414
415 if (!isinput)
417 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
418 errmsg("only input parameters can have default values"),
420
425
426
427
428
429
433 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
434 errmsg("cannot use table references in parameter default value"),
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451 *parameterDefaults = lappend(*parameterDefaults, def);
452 have_defaults = true;
453 }
454 else
455 {
456 if (isinput && have_defaults)
458 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
459 errmsg("input parameters after one with a default value must also have defaults"),
461
462
463
464
465
466
469 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
470 errmsg("procedure OUT parameters cannot appear after one with a default value"),
472 }
473
474 i++;
475 }
476
477
479
480 if (outCount > 0 || varCount > 0)
481 {
484 if (outCount > 1)
485 *requiredResultType = RECORDOID;
486
487 }
488 else
489 {
490 *allParameterTypes = NULL;
491 *parameterModes = NULL;
492 }
493
494 if (have_names)
495 {
496 for (i = 0; i < parameterCount; i++)
497 {
500 }
502 }
503 else
504 *parameterNames = NULL;
505}
506
507
508
509
510
511
512
513
514
515
516static bool
518 bool is_procedure,
520 DefElem **volatility_item,
523 DefElem **leakproof_item,
524 List **set_items,
529{
530 if (strcmp(defel->defname, "volatility") == 0)
531 {
532 if (is_procedure)
533 goto procedure_error;
534 if (*volatility_item)
536
537 *volatility_item = defel;
538 }
539 else if (strcmp(defel->defname, "strict") == 0)
540 {
541 if (is_procedure)
542 goto procedure_error;
543 if (*strict_item)
545
546 *strict_item = defel;
547 }
548 else if (strcmp(defel->defname, "security") == 0)
549 {
550 if (*security_item)
552
553 *security_item = defel;
554 }
555 else if (strcmp(defel->defname, "leakproof") == 0)
556 {
557 if (is_procedure)
558 goto procedure_error;
559 if (*leakproof_item)
561
562 *leakproof_item = defel;
563 }
564 else if (strcmp(defel->defname, "set") == 0)
565 {
566 *set_items = lappend(*set_items, defel->arg);
567 }
568 else if (strcmp(defel->defname, "cost") == 0)
569 {
570 if (is_procedure)
571 goto procedure_error;
572 if (*cost_item)
574
575 *cost_item = defel;
576 }
577 else if (strcmp(defel->defname, "rows") == 0)
578 {
579 if (is_procedure)
580 goto procedure_error;
581 if (*rows_item)
583
584 *rows_item = defel;
585 }
586 else if (strcmp(defel->defname, "support") == 0)
587 {
588 if (is_procedure)
589 goto procedure_error;
590 if (*support_item)
592
593 *support_item = defel;
594 }
595 else if (strcmp(defel->defname, "parallel") == 0)
596 {
597 if (is_procedure)
598 goto procedure_error;
599 if (*parallel_item)
601
602 *parallel_item = defel;
603 }
604 else
605 return false;
606
607
608 return true;
609
610procedure_error:
612 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
613 errmsg("invalid attribute in procedure definition"),
615 return false;
616}
617
618static char
620{
622
623 if (strcmp(str, "immutable") == 0)
624 return PROVOLATILE_IMMUTABLE;
625 else if (strcmp(str, "stable") == 0)
626 return PROVOLATILE_STABLE;
627 else if (strcmp(str, "volatile") == 0)
628 return PROVOLATILE_VOLATILE;
629 else
630 {
631 elog(ERROR, "invalid volatility \"%s\"", str);
632 return 0;
633 }
634}
635
636static char
638{
640
641 if (strcmp(str, "safe") == 0)
642 return PROPARALLEL_SAFE;
643 else if (strcmp(str, "unsafe") == 0)
644 return PROPARALLEL_UNSAFE;
645 else if (strcmp(str, "restricted") == 0)
646 return PROPARALLEL_RESTRICTED;
647 else
648 {
650 (errcode(ERRCODE_SYNTAX_ERROR),
651 errmsg("parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));
652 return PROPARALLEL_UNSAFE;
653 }
654}
655
656
657
658
659
660
663{
665
666 foreach(l, set_items)
667 {
669
671 a = NULL;
672 else
673 {
675
676 if (valuestr)
678 else
680 }
681 }
682
683 return a;
684}
685
686static Oid
688{
690 Oid procOid;
691 Oid argList[1];
692
693
694
695
696
697 argList[0] = INTERNALOID;
698
699 procOid = LookupFuncName(procName, 1, argList, true);
702 (errcode(ERRCODE_UNDEFINED_FUNCTION),
703 errmsg("function %s does not exist",
705
708 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
709 errmsg("support function %s must return type %s",
711
712
713
714
715
716
719 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
720 errmsg("must be superuser to specify a support function")));
721
722 return procOid;
723}
724
725
726
727
728
729
730static void
732 bool is_procedure,
735 char **language,
736 Node **transform,
737 bool *windowfunc_p,
738 char *volatility_p,
739 bool *strict_p,
740 bool *security_definer,
741 bool *leakproof_p,
745 Oid *prosupport,
746 char *parallel_p)
747{
750 DefElem *language_item = NULL;
751 DefElem *transform_item = NULL;
752 DefElem *windowfunc_item = NULL;
753 DefElem *volatility_item = NULL;
754 DefElem *strict_item = NULL;
755 DefElem *security_item = NULL;
756 DefElem *leakproof_item = NULL;
758 DefElem *cost_item = NULL;
759 DefElem *rows_item = NULL;
760 DefElem *support_item = NULL;
761 DefElem *parallel_item = NULL;
762
764 {
766
767 if (strcmp(defel->defname, "as") == 0)
768 {
769 if (as_item)
771 as_item = defel;
772 }
773 else if (strcmp(defel->defname, "language") == 0)
774 {
775 if (language_item)
777 language_item = defel;
778 }
779 else if (strcmp(defel->defname, "transform") == 0)
780 {
781 if (transform_item)
783 transform_item = defel;
784 }
785 else if (strcmp(defel->defname, "window") == 0)
786 {
787 if (windowfunc_item)
789 if (is_procedure)
791 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
792 errmsg("invalid attribute in procedure definition"),
794 windowfunc_item = defel;
795 }
797 is_procedure,
798 defel,
799 &volatility_item,
800 &strict_item,
801 &security_item,
802 &leakproof_item,
803 &set_items,
804 &cost_item,
805 &rows_item,
806 &support_item,
807 ¶llel_item))
808 {
809
810 continue;
811 }
812 else
813 elog(ERROR, "option \"%s\" not recognized",
815 }
816
817 if (as_item)
818 *as = (List *) as_item->arg;
819 if (language_item)
820 *language = strVal(language_item->arg);
821 if (transform_item)
822 *transform = transform_item->arg;
823 if (windowfunc_item)
824 *windowfunc_p = boolVal(windowfunc_item->arg);
825 if (volatility_item)
827 if (strict_item)
828 *strict_p = boolVal(strict_item->arg);
829 if (security_item)
830 *security_definer = boolVal(security_item->arg);
831 if (leakproof_item)
832 *leakproof_p = boolVal(leakproof_item->arg);
833 if (set_items)
835 if (cost_item)
836 {
838 if (*procost <= 0)
840 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
841 errmsg("COST must be positive")));
842 }
843 if (rows_item)
844 {
846 if (*prorows <= 0)
848 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
849 errmsg("ROWS must be positive")));
850 }
851 if (support_item)
853 if (parallel_item)
855}
856
857
858
859
860
861
862
863
864
865
866
867static void
870 List *parameterTypes, List *inParameterNames,
871 char **prosrc_str_p, char **probin_str_p,
872 Node **sql_body_out,
873 const char *queryString)
874{
875 if (!sql_body_in && !as)
877 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
878 errmsg("no function body specified")));
879
880 if (sql_body_in && as)
882 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
883 errmsg("duplicate function body specified")));
884
885 if (sql_body_in && languageOid != SQLlanguageId)
887 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
888 errmsg("inline SQL function body only valid for language SQL")));
889
890 *sql_body_out = NULL;
891
892 if (languageOid == ClanguageId)
893 {
894
895
896
897
898
899
900
901
905 else
906 {
908 if (strcmp(*prosrc_str_p, "-") == 0)
910 }
911 }
912 else if (sql_body_in)
913 {
915
917
922 for (int i = 0; i < list_length(parameterTypes); i++)
923 {
925
927 if (IsPolymorphicType(pinfo->argtypes[i]))
929 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
930 errmsg("SQL function with unquoted function body cannot have polymorphic arguments")));
931
932 if (s[0] != '\0')
934 else
936 }
937
938 if (IsA(sql_body_in, List))
939 {
942 List *transformed_stmts = NIL;
943
944 foreach(lc, stmts)
945 {
949
955 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
956 errmsg("%s is not yet supported in unquoted SQL function body",
958 transformed_stmts = lappend(transformed_stmts, q);
960 }
961
962 *sql_body_out = (Node *) list_make1(transformed_stmts);
963 }
964 else
965 {
968
974 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
975 errmsg("%s is not yet supported in unquoted SQL function body",
978
979 *sql_body_out = (Node *) q;
980 }
981
982
983
984
985
986
987
988
989 *prosrc_str_p = pstrdup("");
990
991
992 *probin_str_p = NULL;
993 }
994 else
995 {
996
998 *probin_str_p = NULL;
999
1002 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1003 errmsg("only one AS item needed for language \"%s\"",
1004 languageName)));
1005
1006 if (languageOid == INTERNALlanguageId)
1007 {
1008
1009
1010
1011
1012
1013
1014
1015
1016 if (strlen(*prosrc_str_p) == 0)
1018 }
1019 }
1020}
1021
1022
1023
1024
1025
1026
1029{
1030 char *probin_str;
1031 char *prosrc_str;
1032 Node *prosqlbody;
1033 Oid prorettype;
1034 bool returnsSet;
1035 char *language;
1036 Oid languageOid;
1037 Oid languageValidator;
1038 Node *transformDefElem = NULL;
1040 Oid namespaceId;
1043 List *parameterTypes_list = NIL;
1047 List *inParameterNames_list = NIL;
1048 List *parameterDefaults;
1049 Oid variadicArgType;
1050 List *trftypes_list = NIL;
1051 List *trfoids_list = NIL;
1053 Oid requiredResultType;
1054 bool isWindowFunc,
1055 isStrict,
1056 security,
1057 isLeakProof;
1058 char volatility;
1062 Oid prosupport;
1065 List *as_clause;
1066 char parallel;
1067
1068
1071
1072
1077
1078
1079 as_clause = NIL;
1080 language = NULL;
1081 isWindowFunc = false;
1082 isStrict = false;
1083 security = false;
1084 isLeakProof = false;
1085 volatility = PROVOLATILE_VOLATILE;
1086 proconfig = NULL;
1087 procost = -1;
1088 prorows = -1;
1090 parallel = PROPARALLEL_UNSAFE;
1091
1092
1094 stmt->is_procedure,
1095 stmt->options,
1096 &as_clause, &language, &transformDefElem,
1097 &isWindowFunc, &volatility,
1098 &isStrict, &security, &isLeakProof,
1099 &proconfig, &procost, &prorows,
1100 &prosupport, ¶llel);
1101
1102 if (!language)
1103 {
1104 if (stmt->sql_body)
1105 language = "sql";
1106 else
1108 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1109 errmsg("no language specified")));
1110 }
1111
1112
1116 (errcode(ERRCODE_UNDEFINED_OBJECT),
1117 errmsg("language \"%s\" does not exist", language),
1119 errhint("Use CREATE EXTENSION to load the language into the database.") : 0)));
1120
1122 languageOid = languageStruct->oid;
1123
1124 if (languageStruct->lanpltrusted)
1125 {
1126
1130 NameStr(languageStruct->lanname));
1131 }
1132 else
1133 {
1134
1137 NameStr(languageStruct->lanname));
1138 }
1139
1140 languageValidator = languageStruct->lanvalidator;
1141
1143
1144
1145
1146
1147
1148
1149 if (isLeakProof && ())
1151 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1152 errmsg("only superuser can define a leakproof function")));
1153
1154 if (transformDefElem)
1155 {
1157
1158 foreach(lc, castNode(List, transformDefElem))
1159 {
1163 Oid transformid;
1164
1165 typeid = elt ? elt : typeid;
1167 trftypes_list = lappend_oid(trftypes_list, typeid);
1168 trfoids_list = lappend_oid(trfoids_list, transformid);
1169 }
1170 }
1171
1172
1173
1174
1175
1177 stmt->parameters,
1178 languageOid,
1180 ¶meterTypes,
1181 ¶meterTypes_list,
1182 &allParameterTypes,
1183 ¶meterModes,
1184 ¶meterNames,
1185 &inParameterNames_list,
1186 ¶meterDefaults,
1187 &variadicArgType,
1188 &requiredResultType);
1189
1190 if (stmt->is_procedure)
1191 {
1193 prorettype = requiredResultType ? requiredResultType : VOIDOID;
1194 returnsSet = false;
1195 }
1196 else if (stmt->returnType)
1197 {
1198
1200 &prorettype, &returnsSet);
1201 if (OidIsValid(requiredResultType) && prorettype != requiredResultType)
1203 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1204 errmsg("function result type must be %s because of OUT parameters",
1206 }
1207 else if (OidIsValid(requiredResultType))
1208 {
1209
1210 prorettype = requiredResultType;
1211 returnsSet = false;
1212 }
1213 else
1214 {
1216 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1217 errmsg("function result type must be specified")));
1218
1219 prorettype = VOIDOID;
1220 returnsSet = false;
1221 }
1222
1223 if (trftypes_list != NIL)
1224 {
1227 int i;
1228
1230 i = 0;
1231 foreach(lc, trftypes_list)
1234 }
1235 else
1236 {
1237
1238 trftypes = NULL;
1239 }
1240
1242 parameterTypes_list, inParameterNames_list,
1243 &prosrc_str, &probin_str, &prosqlbody,
1245
1246
1247
1248
1249
1250
1251 if (procost < 0)
1252 {
1253
1254 if (languageOid == INTERNALlanguageId ||
1255 languageOid == ClanguageId)
1256 procost = 1;
1257 else
1258 procost = 100;
1259 }
1260 if (prorows < 0)
1261 {
1262 if (returnsSet)
1263 prorows = 1000;
1264 else
1265 prorows = 0;
1266 }
1267 else if (!returnsSet)
1269 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1270 errmsg("ROWS is not applicable when function does not return a set")));
1271
1272
1273
1274
1275
1277 namespaceId,
1278 stmt->replace,
1279 returnsSet,
1280 prorettype,
1282 languageOid,
1283 languageValidator,
1284 prosrc_str,
1285 probin_str,
1286 prosqlbody,
1287 stmt->is_procedure ? PROKIND_PROCEDURE : (isWindowFunc ? PROKIND_WINDOW : PROKIND_FUNCTION),
1288 security,
1289 isLeakProof,
1290 isStrict,
1291 volatility,
1292 parallel,
1293 parameterTypes,
1297 parameterDefaults,
1299 trfoids_list,
1301 prosupport,
1302 procost,
1303 prorows);
1304}
1305
1306
1307
1308
1309
1310
1311
1312void
1314{
1317 char prokind;
1318
1319
1320
1321
1323
1326 elog(ERROR, "cache lookup failed for function %u", funcOid);
1327
1329
1331
1333
1335
1337
1338
1339
1340
1341 if (prokind == PROKIND_AGGREGATE)
1342 {
1344
1347 elog(ERROR, "cache lookup failed for pg_aggregate tuple for function %u", funcOid);
1348
1350
1352
1354 }
1355}
1356
1357
1358
1359
1360
1361
1364{
1366 Oid funcOid;
1368 bool is_procedure;
1371 DefElem *volatility_item = NULL;
1372 DefElem *strict_item = NULL;
1373 DefElem *security_def_item = NULL;
1374 DefElem *leakproof_item = NULL;
1376 DefElem *cost_item = NULL;
1377 DefElem *rows_item = NULL;
1378 DefElem *support_item = NULL;
1379 DefElem *parallel_item = NULL;
1381
1383
1385
1387
1390 elog(ERROR, "cache lookup failed for function %u", funcOid);
1391
1393
1394
1398
1399 if (procForm->prokind == PROKIND_AGGREGATE)
1401 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1402 errmsg("\"%s\" is an aggregate function",
1404
1405 is_procedure = (procForm->prokind == PROKIND_PROCEDURE);
1406
1407
1408 foreach(l, stmt->actions)
1409 {
1411
1413 is_procedure,
1414 defel,
1415 &volatility_item,
1416 &strict_item,
1417 &security_def_item,
1418 &leakproof_item,
1419 &set_items,
1420 &cost_item,
1421 &rows_item,
1422 &support_item,
1423 ¶llel_item) == false)
1424 elog(ERROR, "option \"%s\" not recognized", defel->defname);
1425 }
1426
1427 if (volatility_item)
1429 if (strict_item)
1430 procForm->proisstrict = boolVal(strict_item->arg);
1431 if (security_def_item)
1432 procForm->prosecdef = boolVal(security_def_item->arg);
1433 if (leakproof_item)
1434 {
1435 procForm->proleakproof = boolVal(leakproof_item->arg);
1436 if (procForm->proleakproof && ())
1438 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1439 errmsg("only superuser can define a leakproof function")));
1440 }
1441 if (cost_item)
1442 {
1444 if (procForm->procost <= 0)
1446 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1447 errmsg("COST must be positive")));
1448 }
1449 if (rows_item)
1450 {
1452 if (procForm->prorows <= 0)
1454 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1455 errmsg("ROWS must be positive")));
1456 if (!procForm->proretset)
1458 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1459 errmsg("ROWS is not applicable when function does not return a set")));
1460 }
1461 if (support_item)
1462 {
1463
1465
1466
1467 if (OidIsValid(procForm->prosupport))
1468 {
1470 ProcedureRelationId, procForm->prosupport,
1471 newsupport) != 1)
1472 elog(ERROR, "could not change support dependency for function %s",
1474 }
1475 else
1476 {
1478
1479 referenced.classId = ProcedureRelationId;
1480 referenced.objectId = newsupport;
1483 }
1484
1485 procForm->prosupport = newsupport;
1486 }
1487 if (parallel_item)
1489 if (set_items)
1490 {
1492 bool isnull;
1494 Datum repl_val[Natts_pg_proc];
1495 bool repl_null[Natts_pg_proc];
1496 bool repl_repl[Natts_pg_proc];
1497
1498
1499 datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_proconfig, &isnull);
1501
1502
1504
1505
1506 memset(repl_repl, false, sizeof(repl_repl));
1507 repl_repl[Anum_pg_proc_proconfig - 1] = true;
1508
1509 if (a == NULL)
1510 {
1511 repl_val[Anum_pg_proc_proconfig - 1] = (Datum) 0;
1512 repl_null[Anum_pg_proc_proconfig - 1] = true;
1513 }
1514 else
1515 {
1517 repl_null[Anum_pg_proc_proconfig - 1] = false;
1518 }
1519
1521 repl_val, repl_null, repl_repl);
1522 }
1523
1524
1525
1527
1529
1532
1533 return address;
1534}
1535
1536
1537
1538
1539
1542{
1543 Oid sourcetypeid;
1544 Oid targettypeid;
1545 char sourcetyptype;
1546 char targettyptype;
1547 Oid funcid;
1550 int nargs;
1551 char castcontext;
1552 char castmethod;
1556
1559 sourcetyptype = get_typtype(sourcetypeid);
1560 targettyptype = get_typtype(targettypeid);
1561
1562
1563 if (sourcetyptype == TYPTYPE_PSEUDO)
1565 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1566 errmsg("source data type %s is a pseudo-type",
1568
1569 if (targettyptype == TYPTYPE_PSEUDO)
1571 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1572 errmsg("target data type %s is a pseudo-type",
1574
1575
1579 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1580 errmsg("must be owner of type %s or type %s",
1583
1587
1591
1592
1593 if (sourcetyptype == TYPTYPE_DOMAIN)
1595 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1596 errmsg("cast will be ignored because the source data type is a domain")));
1597
1598 else if (targettyptype == TYPTYPE_DOMAIN)
1600 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1601 errmsg("cast will be ignored because the target data type is a domain")));
1602
1603
1604 if (stmt->func != NULL)
1605 castmethod = COERCION_METHOD_FUNCTION;
1606 else if (stmt->inout)
1607 castmethod = COERCION_METHOD_INOUT;
1608 else
1609 castmethod = COERCION_METHOD_BINARY;
1610
1611 if (castmethod == COERCION_METHOD_FUNCTION)
1612 {
1614
1616
1619 elog(ERROR, "cache lookup failed for function %u", funcid);
1620
1622 nargs = procstruct->pronargs;
1623 if (nargs < 1 || nargs > 3)
1625 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1626 errmsg("cast function must take one to three arguments")));
1628 procstruct->proargtypes.values[0],
1629 &incastid))
1631 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1632 errmsg("argument of cast function must match or be binary-coercible from source data type")));
1633 if (nargs > 1 && procstruct->proargtypes.values[1] != INT4OID)
1635 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1636 errmsg("second argument of cast function must be type %s",
1637 "integer")));
1638 if (nargs > 2 && procstruct->proargtypes.values[2] != BOOLOID)
1640 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1641 errmsg("third argument of cast function must be type %s",
1642 "boolean")));
1644 targettypeid,
1645 &outcastid))
1647 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1648 errmsg("return data type of cast function must match or be binary-coercible to target data type")));
1649
1650
1651
1652
1653
1654
1655#ifdef NOT_USED
1656 if (procstruct->provolatile == PROVOLATILE_VOLATILE)
1658 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1659 errmsg("cast function must not be volatile")));
1660#endif
1661 if (procstruct->prokind != PROKIND_FUNCTION)
1663 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1664 errmsg("cast function must be a normal function")));
1665 if (procstruct->proretset)
1667 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1668 errmsg("cast function must not return a set")));
1669
1671 }
1672 else
1673 {
1675 nargs = 0;
1676 }
1677
1678 if (castmethod == COERCION_METHOD_BINARY)
1679 {
1682 bool typ1byval;
1683 bool typ2byval;
1684 char typ1align;
1685 char typ2align;
1686
1687
1688
1689
1690
1693 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1694 errmsg("must be superuser to create a cast WITHOUT FUNCTION")));
1695
1696
1697
1698
1699
1700
1701
1704 if (typ1len != typ2len ||
1705 typ1byval != typ2byval ||
1706 typ1align != typ2align)
1708 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1709 errmsg("source and target data types are not physically compatible")));
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725 if (sourcetyptype == TYPTYPE_COMPOSITE ||
1726 targettyptype == TYPTYPE_COMPOSITE)
1728 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1729 errmsg("composite data types are not binary-compatible")));
1730
1734 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1735 errmsg("array data types are not binary-compatible")));
1736
1737 if (sourcetyptype == TYPTYPE_RANGE ||
1738 targettyptype == TYPTYPE_RANGE ||
1739 sourcetyptype == TYPTYPE_MULTIRANGE ||
1740 targettyptype == TYPTYPE_MULTIRANGE)
1742 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1743 errmsg("range data types are not binary-compatible")));
1744
1745 if (sourcetyptype == TYPTYPE_ENUM ||
1746 targettyptype == TYPTYPE_ENUM)
1748 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1749 errmsg("enum data types are not binary-compatible")));
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762 if (sourcetyptype == TYPTYPE_DOMAIN ||
1763 targettyptype == TYPTYPE_DOMAIN)
1765 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1766 errmsg("domain data types must not be marked binary-compatible")));
1767 }
1768
1769
1770
1771
1772
1773 if (sourcetypeid == targettypeid && nargs < 2)
1775 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1776 errmsg("source data type and target data type are the same")));
1777
1778
1779 switch (stmt->context)
1780 {
1782 castcontext = COERCION_CODE_IMPLICIT;
1783 break;
1785 castcontext = COERCION_CODE_ASSIGNMENT;
1786 break;
1787
1789 castcontext = COERCION_CODE_EXPLICIT;
1790 break;
1791 default:
1792 elog(ERROR, "unrecognized CoercionContext: %d", stmt->context);
1793 castcontext = 0;
1794 break;
1795 }
1796
1797 myself = CastCreate(sourcetypeid, targettypeid, funcid, incastid, outcastid,
1799 return myself;
1800}
1801
1802
1803static void
1805{
1806 if (procstruct->provolatile == PROVOLATILE_VOLATILE)
1808 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1809 errmsg("transform function must not be volatile")));
1810 if (procstruct->prokind != PROKIND_FUNCTION)
1812 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1813 errmsg("transform function must be a normal function")));
1814 if (procstruct->proretset)
1816 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1817 errmsg("transform function must not return a set")));
1818 if (procstruct->pronargs != 1)
1820 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1821 errmsg("transform function must take one argument")));
1822 if (procstruct->proargtypes.values[0] != INTERNALOID)
1824 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1825 errmsg("first argument of transform function must be type %s",
1826 "internal")));
1827}
1828
1829
1830
1831
1832
1835{
1836 Oid typeid;
1837 char typtype;
1838 Oid langid;
1839 Oid fromsqlfuncid;
1840 Oid tosqlfuncid;
1844 bool nulls[Natts_pg_transform] = {0};
1845 bool replaces[Natts_pg_transform] = {0};
1846 Oid transformid;
1851 referenced;
1853 bool is_replace;
1854
1855
1856
1857
1860
1861 if (typtype == TYPTYPE_PSEUDO)
1863 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1864 errmsg("data type %s is a pseudo-type",
1866
1867 if (typtype == TYPTYPE_DOMAIN)
1869 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1870 errmsg("data type %s is a domain",
1872
1875
1879
1880
1881
1882
1884
1888
1889
1890
1891
1892 if (stmt->fromsql)
1893 {
1895
1898
1902
1905 elog(ERROR, "cache lookup failed for function %u", fromsqlfuncid);
1907 if (procstruct->prorettype != INTERNALOID)
1909 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1910 errmsg("return data type of FROM SQL function must be %s",
1911 "internal")));
1914 }
1915 else
1917
1918 if (stmt->tosql)
1919 {
1921
1924
1928
1931 elog(ERROR, "cache lookup failed for function %u", tosqlfuncid);
1933 if (procstruct->prorettype != typeid)
1935 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1936 errmsg("return data type of TO SQL function must be the transform data type")));
1939 }
1940 else
1942
1943
1944
1945
1950
1952
1957 {
1959
1960 if (->replace)
1963 errmsg("transform for type %s language \"%s\" already exists",
1965 stmt->lang)));
1966
1967 replaces[Anum_pg_transform_trffromsql - 1] = true;
1968 replaces[Anum_pg_transform_trftosql - 1] = true;
1969
1972
1973 transformid = form->oid;
1975 is_replace = true;
1976 }
1977 else
1978 {
1980 Anum_pg_transform_oid);
1984 is_replace = false;
1985 }
1986
1987 if (is_replace)
1989
1991
1992
1994
1995
1998
1999
2002
2003
2005 {
2006 ObjectAddressSet(referenced, ProcedureRelationId, fromsqlfuncid);
2008 }
2010 {
2011 ObjectAddressSet(referenced, ProcedureRelationId, tosqlfuncid);
2013 }
2014
2017
2018
2020
2021
2023
2025
2027
2028 return myself;
2029}
2030
2031
2032
2033
2034
2035
2036
2037
2040{
2041 Oid oid;
2042
2043 oid = GetSysCacheOid2(TRFTYPELANG, Anum_pg_transform_oid,
2046 if ((oid) && !missing_ok)
2048 (errcode(ERRCODE_UNDEFINED_OBJECT),
2049 errmsg("transform for type %s language \"%s\" does not exist",
2052 return oid;
2053}
2054
2055
2056
2057
2058
2059
2060
2061
2062void
2065{
2066
2072 (errcode(ERRCODE_DUPLICATE_FUNCTION),
2073 errmsg("function %s already exists in schema \"%s\"",
2077}
2078
2079
2080
2081
2082
2083
2084
2085void
2087{
2090 DefElem *as_item = NULL;
2091 DefElem *language_item = NULL;
2092 char *language;
2093 Oid laninline;
2096
2097
2099 {
2101
2102 if (strcmp(defel->defname, "as") == 0)
2103 {
2104 if (as_item)
2106 as_item = defel;
2107 }
2108 else if (strcmp(defel->defname, "language") == 0)
2109 {
2110 if (language_item)
2112 language_item = defel;
2113 }
2114 else
2115 elog(ERROR, "option \"%s\" not recognized",
2117 }
2118
2119 if (as_item)
2121 else
2123 (errcode(ERRCODE_SYNTAX_ERROR),
2124 errmsg("no inline code specified")));
2125
2126
2127 if (language_item)
2128 language = strVal(language_item->arg);
2129 else
2130 language = "plpgsql";
2131
2132
2136 (errcode(ERRCODE_UNDEFINED_OBJECT),
2137 errmsg("language \"%s\" does not exist", language),
2139 errhint("Use CREATE EXTENSION to load the language into the database.") : 0)));
2140
2142 codeblock->langOid = languageStruct->oid;
2143 codeblock->langIsTrusted = languageStruct->lanpltrusted;
2144 codeblock->atomic = atomic;
2145
2146 if (languageStruct->lanpltrusted)
2147 {
2148
2150
2155 NameStr(languageStruct->lanname));
2156 }
2157 else
2158 {
2159
2162 NameStr(languageStruct->lanname));
2163 }
2164
2165
2166 laninline = languageStruct->laninline;
2169 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2170 errmsg("language \"%s\" does not support inline code execution",
2171 NameStr(languageStruct->lanname))));
2172
2174
2175
2177}
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207void
2209{
2213 int nargs;
2214 int i;
2223
2224 fexpr = stmt->funcexpr;
2227
2231
2232
2234 callcontext->atomic = atomic;
2235
2238 elog(ERROR, "cache lookup failed for function %u", fexpr->funcid);
2239
2240
2241
2242
2243
2244
2245
2246 if ((tp, Anum_pg_proc_proconfig, NULL))
2247 callcontext->atomic = true;
2248
2249
2250
2251
2252
2253
2254
2256 callcontext->atomic = true;
2257
2259
2260
2264 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2265 errmsg_plural("cannot pass more than %d argument to a procedure",
2266 "cannot pass more than %d arguments to a procedure",
2269
2270
2275 (Node *) callcontext, NULL);
2276
2277
2278
2279
2280
2284
2285
2286
2287
2288
2289
2290
2291
2292 if (!atomic)
2294
2295 i = 0;
2296 foreach(lc, fexpr->args)
2297 {
2300 bool isnull;
2301
2303
2305
2306 fcinfo->args[i].value = val;
2307 fcinfo->args[i].isnull = isnull;
2308
2309 i++;
2310 }
2311
2312
2313 if (!atomic)
2315
2316
2320
2321
2322 if (fexpr->funcresulttype == VOIDOID)
2323 {
2324
2325 }
2326 else if (fexpr->funcresulttype == RECORDOID)
2327 {
2328
2330 Oid tupType;
2331 int32 tupTypmod;
2336
2337 if (fcinfo->isnull)
2338 elog(ERROR, "procedure returned null record");
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2353
2358
2361
2365 rettupdata.t_data = td;
2366
2369
2371
2373 }
2374 else
2375 elog(ERROR, "unexpected result type for procedure: %u",
2376 fexpr->funcresulttype);
2377
2379}
2380
2381
2382
2383
2386{
2390
2391 fexpr = stmt->funcexpr;
2392
2395 elog(ERROR, "cache lookup failed for procedure %u", fexpr->funcid);
2396
2398
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411 if (tupdesc)
2412 {
2414 for (int i = 0; i < tupdesc->natts; i++)
2415 {
2418
2420 i + 1,
2423 -1,
2424 0);
2425 }
2426 }
2427
2428 return tupdesc;
2429}
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)
#define palloc0_object(type)
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)
char * format_type_be(Oid type_oid)
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)
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, const ItemPointerData *otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *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
FormData_pg_transform * Form_pg_transform
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)
void CommandCounterIncrement(void)