PostgreSQL Source Code: src/backend/utils/fmgr/funcapi.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
15
33
34
36{
42
45 Node *call_expr,
47 Oid *resultTypeId,
55 Node *call_expr);
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75void
77{
78 bool random_access;
82 per_query_ctx;
84
85
88 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
89 errmsg("set-valued function called in context that cannot accept a set")));
93 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
94 errmsg("materialize mode required, but it is not allowed in this context")));
95
96
97
98
99
102
103
106 else
107 {
109 elog(ERROR, "return type must be a row type");
110 }
111
112
115
117
121 rsinfo->setDesc = stored_tupdesc;
123}
124
125
126
127
128
129
130
131
134{
136
137
138
139
140 if (fcinfo->resultinfo == NULL || (fcinfo->resultinfo, ReturnSetInfo))
142 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
143 errmsg("set-valued function called in context that cannot accept a set")));
144
145 if (fcinfo->flinfo->fn_extra == NULL)
146 {
147
148
149
152
153
154
155
157 "SRF multi-call context",
159
160
161
162
166
167
168
169
176
177
178
179
180 fcinfo->flinfo->fn_extra = retval;
181
182
183
184
185
189 }
190 else
191 {
192
193 elog(ERROR, "init_MultiFuncCall cannot be called more than once");
194
195
196 retval = NULL;
197 }
198
199 return retval;
200}
201
202
203
204
205
206
209{
211
212 return retval;
213}
214
215
216
217
218
219void
221{
223
224
228
229
231}
232
233
234
235
236
237static void
239{
242
243
245
246
247
248
249
251}
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
277 Oid *resultTypeId,
279{
283 resultTypeId,
284 resultTupleDesc);
285}
286
287
288
289
290
291
292
293
294
295
296
297
300 Oid *resultTypeId,
302{
304
307 expr,
308 NULL,
309 resultTypeId,
310 resultTupleDesc);
311 else if (expr && IsA(expr, OpExpr))
313 expr,
314 NULL,
315 resultTypeId,
316 resultTupleDesc);
317 else if (expr && IsA(expr, RowExpr) &&
318 ((RowExpr *) expr)->row_typeid == RECORDOID)
319 {
320
325 *lcn;
326
329 forboth(lcc, rexpr->args, lcn, rexpr->colnames)
330 {
333
335 colname,
338 0);
341 i++;
342 }
343 if (resultTypeId)
344 *resultTypeId = rexpr->row_typeid;
345 if (resultTupleDesc)
348 }
349 else if (expr && IsA(expr, Const) &&
350 ((Const *) expr)->consttype == RECORDOID &&
351 !((Const *) expr)->constisnull)
352 {
353
354
355
356
357
359 Oid tupType;
361
365 if (resultTypeId)
366 *resultTypeId = tupType;
367 if (tupType != RECORDOID || tupTypmod >= 0)
368 {
369
370 if (resultTupleDesc)
372 tupTypmod);
374 }
375 else
376 {
377
378 if (resultTupleDesc)
379 *resultTupleDesc = NULL;
381 }
382 }
383 else
384 {
385
387 Oid base_typid;
388
389 if (resultTypeId)
390 *resultTypeId = typid;
391 if (resultTupleDesc)
392 *resultTupleDesc = NULL;
396 resultTupleDesc)
398 }
399
400 return result;
401}
402
403
404
405
406
407
408
411 Oid *resultTypeId,
413{
415 NULL,
416 NULL,
417 resultTypeId,
418 resultTupleDesc);
419}
420
421
422
423
424
425
426
427
428
431 Node *call_expr,
433 Oid *resultTypeId,
435{
439 Oid rettype;
440 Oid base_rettype;
442
443
446 elog(ERROR, "cache lookup failed for function %u", funcid);
448
449 rettype = procform->prorettype;
450
451
453 if (tupdesc)
454 {
455
456
457
458
459
460 if (resultTypeId)
461 *resultTypeId = rettype;
462
464 &procform->proargtypes,
465 call_expr))
466 {
467 if (tupdesc->tdtypeid == RECORDOID &&
470 if (resultTupleDesc)
471 *resultTupleDesc = tupdesc;
473 }
474 else
475 {
476 if (resultTupleDesc)
477 *resultTupleDesc = NULL;
479 }
480
482
483 return result;
484 }
485
486
487
488
489 if (IsPolymorphicType(rettype))
490 {
492
493 if (newrettype == InvalidOid)
495 (errcode(ERRCODE_DATATYPE_MISMATCH),
496 errmsg("could not determine actual result type for function \"%s\" declared to return type %s",
497 NameStr(procform->proname),
499 rettype = newrettype;
500 }
501
502 if (resultTypeId)
503 *resultTypeId = rettype;
504 if (resultTupleDesc)
505 *resultTupleDesc = NULL;
506
507
509 switch (result)
510 {
513 if (resultTupleDesc)
515
516 break;
518 break;
520
523 {
525 if (resultTupleDesc)
527
528 }
529 break;
530 default:
531 break;
532 }
533
535
536 return result;
537}
538
539
540
541
542
543
544
545
546
547
548
549
552{
555
557
560 return tupleDesc;
561
562 if (!noError)
563 {
565
566 if (exprTypeId != RECORDOID)
568 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
569 errmsg("type %s is not composite",
571 else
573 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
574 errmsg("record type has not been registered")));
575 }
576
577 return NULL;
578}
579
580
581
582
583
584
585
586
587
588static void
590{
592 {
593
596
599 (errcode(ERRCODE_DATATYPE_MISMATCH),
600 errmsg("argument declared %s is not an array but type %s",
601 "anyarray",
604 }
606 {
607
610
613 (errcode(ERRCODE_DATATYPE_MISMATCH),
614 errmsg("argument declared %s is not a range type but type %s",
615 "anyrange",
618 }
620 {
621
622 Oid multirange_base_type;
623 Oid multirange_typelem;
624 Oid range_base_type;
625 Oid range_typelem;
626
631 (errcode(ERRCODE_DATATYPE_MISMATCH),
632 errmsg("argument declared %s is not a multirange type but type %s",
633 "anymultirange",
635
636 range_base_type = getBaseType(multirange_typelem);
638
641 (errcode(ERRCODE_DATATYPE_MISMATCH),
642 errmsg("argument declared %s does not contain a range type but type %s",
643 "anymultirange",
646 }
647 else
648 elog(ERROR, "could not determine polymorphic type");
649}
650
651
652
653
654static void
656{
657
660
662 {
663
665
668 (errcode(ERRCODE_UNDEFINED_OBJECT),
669 errmsg("could not find array type for data type %s",
672 }
673 else
674 elog(ERROR, "could not determine polymorphic type");
675}
676
677
678
679
680static void
682{
683
684
685
686
687
689 {
690
693
696 (errcode(ERRCODE_DATATYPE_MISMATCH),
697 errmsg("argument declared %s is not a multirange type but type %s",
698 "anymultirange",
701 }
702 else
703 elog(ERROR, "could not determine polymorphic type");
704}
705
706
707
708
709static void
711{
712
713
714
715
716
718 {
721
724 (errcode(ERRCODE_UNDEFINED_OBJECT),
725 errmsg("could not find multirange type for data type %s",
728 }
729 else
730 elog(ERROR, "could not determine polymorphic type");
731}
732
733
734
735
736
737
738
739
740
741
742
743static bool
745 Node *call_expr)
746{
747 int natts = tupdesc->natts;
748 int nargs = declared_args->dim1;
749 bool have_polymorphic_result = false;
750 bool have_anyelement_result = false;
751 bool have_anyarray_result = false;
752 bool have_anyrange_result = false;
753 bool have_anymultirange_result = false;
754 bool have_anycompatible_result = false;
755 bool have_anycompatible_array_result = false;
756 bool have_anycompatible_range_result = false;
757 bool have_anycompatible_multirange_result = false;
762 int i;
763
764
765 for (i = 0; i < natts; i++)
766 {
768 {
769 case ANYELEMENTOID:
770 case ANYNONARRAYOID:
771 case ANYENUMOID:
772 have_polymorphic_result = true;
773 have_anyelement_result = true;
774 break;
775 case ANYARRAYOID:
776 have_polymorphic_result = true;
777 have_anyarray_result = true;
778 break;
779 case ANYRANGEOID:
780 have_polymorphic_result = true;
781 have_anyrange_result = true;
782 break;
783 case ANYMULTIRANGEOID:
784 have_polymorphic_result = true;
785 have_anymultirange_result = true;
786 break;
787 case ANYCOMPATIBLEOID:
788 case ANYCOMPATIBLENONARRAYOID:
789 have_polymorphic_result = true;
790 have_anycompatible_result = true;
791 break;
792 case ANYCOMPATIBLEARRAYOID:
793 have_polymorphic_result = true;
794 have_anycompatible_array_result = true;
795 break;
796 case ANYCOMPATIBLERANGEOID:
797 have_polymorphic_result = true;
798 have_anycompatible_range_result = true;
799 break;
800 case ANYCOMPATIBLEMULTIRANGEOID:
801 have_polymorphic_result = true;
802 have_anycompatible_multirange_result = true;
803 break;
804 default:
805 break;
806 }
807 }
808 if (!have_polymorphic_result)
809 return true;
810
811
812
813
814
815
816
817
818 if (!call_expr)
819 return false;
820
821 memset(&poly_actuals, 0, sizeof(poly_actuals));
822 memset(&anyc_actuals, 0, sizeof(anyc_actuals));
823
824 for (i = 0; i < nargs; i++)
825 {
826 switch (declared_args->values[i])
827 {
828 case ANYELEMENTOID:
829 case ANYNONARRAYOID:
830 case ANYENUMOID:
832 {
836 return false;
837 }
838 break;
839 case ANYARRAYOID:
841 {
845 return false;
846 }
847 break;
848 case ANYRANGEOID:
850 {
854 return false;
855 }
856 break;
857 case ANYMULTIRANGEOID:
859 {
863 return false;
864 }
865 break;
866 case ANYCOMPATIBLEOID:
867 case ANYCOMPATIBLENONARRAYOID:
869 {
873 return false;
874 }
875 break;
876 case ANYCOMPATIBLEARRAYOID:
878 {
882 return false;
883 }
884 break;
885 case ANYCOMPATIBLERANGEOID:
887 {
891 return false;
892 }
893 break;
894 case ANYCOMPATIBLEMULTIRANGEOID:
896 {
900 return false;
901 }
902 break;
903 default:
904 break;
905 }
906 }
907
908
911
914
917
920
923
926
929
932
933
934
935
936
937
938
939
944
949
951 {
952
953
954
955
956
958
960 {
962 anycollation = inputcollation;
964 anycompatcollation = inputcollation;
965 }
966 }
967
968
969 for (i = 0; i < natts; i++)
970 {
972
973 switch (att->atttypid)
974 {
975 case ANYELEMENTOID:
976 case ANYNONARRAYOID:
977 case ANYENUMOID:
981 -1,
982 0);
984 break;
985 case ANYARRAYOID:
989 -1,
990 0);
992 break;
993 case ANYRANGEOID:
997 -1,
998 0);
999
1000 break;
1001 case ANYMULTIRANGEOID:
1005 -1,
1006 0);
1007
1008 break;
1009 case ANYCOMPATIBLEOID:
1010 case ANYCOMPATIBLENONARRAYOID:
1014 -1,
1015 0);
1017 break;
1018 case ANYCOMPATIBLEARRAYOID:
1022 -1,
1023 0);
1025 break;
1026 case ANYCOMPATIBLERANGEOID:
1030 -1,
1031 0);
1032
1033 break;
1034 case ANYCOMPATIBLEMULTIRANGEOID:
1038 -1,
1039 0);
1040
1041 break;
1042 default:
1043 break;
1044 }
1045 }
1046
1047 return true;
1048}
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063bool
1065 Node *call_expr)
1066{
1067 bool have_polymorphic_result = false;
1068 bool have_anyelement_result = false;
1069 bool have_anyarray_result = false;
1070 bool have_anyrange_result = false;
1071 bool have_anymultirange_result = false;
1072 bool have_anycompatible_result = false;
1073 bool have_anycompatible_array_result = false;
1074 bool have_anycompatible_range_result = false;
1075 bool have_anycompatible_multirange_result = false;
1078 int inargno;
1079 int i;
1080
1081
1082
1083
1084
1085
1086 memset(&poly_actuals, 0, sizeof(poly_actuals));
1087 memset(&anyc_actuals, 0, sizeof(anyc_actuals));
1088 inargno = 0;
1089 for (i = 0; i < numargs; i++)
1090 {
1091 char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
1092
1093 switch (argtypes[i])
1094 {
1095 case ANYELEMENTOID:
1096 case ANYNONARRAYOID:
1097 case ANYENUMOID:
1098 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1099 {
1100 have_polymorphic_result = true;
1101 have_anyelement_result = true;
1102 }
1103 else
1104 {
1106 {
1110 return false;
1111 }
1113 }
1114 break;
1115 case ANYARRAYOID:
1116 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1117 {
1118 have_polymorphic_result = true;
1119 have_anyarray_result = true;
1120 }
1121 else
1122 {
1124 {
1128 return false;
1129 }
1131 }
1132 break;
1133 case ANYRANGEOID:
1134 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1135 {
1136 have_polymorphic_result = true;
1137 have_anyrange_result = true;
1138 }
1139 else
1140 {
1142 {
1146 return false;
1147 }
1149 }
1150 break;
1151 case ANYMULTIRANGEOID:
1152 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1153 {
1154 have_polymorphic_result = true;
1155 have_anymultirange_result = true;
1156 }
1157 else
1158 {
1160 {
1164 return false;
1165 }
1167 }
1168 break;
1169 case ANYCOMPATIBLEOID:
1170 case ANYCOMPATIBLENONARRAYOID:
1171 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1172 {
1173 have_polymorphic_result = true;
1174 have_anycompatible_result = true;
1175 }
1176 else
1177 {
1179 {
1183 return false;
1184 }
1186 }
1187 break;
1188 case ANYCOMPATIBLEARRAYOID:
1189 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1190 {
1191 have_polymorphic_result = true;
1192 have_anycompatible_array_result = true;
1193 }
1194 else
1195 {
1197 {
1201 return false;
1202 }
1204 }
1205 break;
1206 case ANYCOMPATIBLERANGEOID:
1207 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1208 {
1209 have_polymorphic_result = true;
1210 have_anycompatible_range_result = true;
1211 }
1212 else
1213 {
1215 {
1219 return false;
1220 }
1222 }
1223 break;
1224 case ANYCOMPATIBLEMULTIRANGEOID:
1225 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1226 {
1227 have_polymorphic_result = true;
1228 have_anycompatible_multirange_result = true;
1229 }
1230 else
1231 {
1233 {
1237 return false;
1238 }
1240 }
1241 break;
1242 default:
1243 break;
1244 }
1245 if (argmode != PROARGMODE_OUT && argmode != PROARGMODE_TABLE)
1246 inargno++;
1247 }
1248
1249
1250 if (!have_polymorphic_result)
1251 return true;
1252
1253
1256
1259
1262
1265
1268
1271
1274
1277
1278
1279 for (i = 0; i < numargs; i++)
1280 {
1281 switch (argtypes[i])
1282 {
1283 case ANYELEMENTOID:
1284 case ANYNONARRAYOID:
1285 case ANYENUMOID:
1287 break;
1288 case ANYARRAYOID:
1290 break;
1291 case ANYRANGEOID:
1293 break;
1294 case ANYMULTIRANGEOID:
1296 break;
1297 case ANYCOMPATIBLEOID:
1298 case ANYCOMPATIBLENONARRAYOID:
1300 break;
1301 case ANYCOMPATIBLEARRAYOID:
1303 break;
1304 case ANYCOMPATIBLERANGEOID:
1306 break;
1307 case ANYCOMPATIBLEMULTIRANGEOID:
1309 break;
1310 default:
1311 break;
1312 }
1313 }
1314
1315 return true;
1316}
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1329{
1330 *base_typeid = typid;
1331
1333 {
1334 case TYPTYPE_COMPOSITE:
1336 case TYPTYPE_BASE:
1337 case TYPTYPE_ENUM:
1338 case TYPTYPE_RANGE:
1339 case TYPTYPE_MULTIRANGE:
1341 case TYPTYPE_DOMAIN:
1342 *base_typeid = typid = getBaseType(typid);
1343 if (get_typtype(typid) == TYPTYPE_COMPOSITE)
1345 else
1347 case TYPTYPE_PSEUDO:
1348 if (typid == RECORDOID)
1350
1351
1352
1353
1354
1355
1356
1357 if (typid == VOIDOID || typid == CSTRINGOID)
1360 }
1361
1363}
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378int
1380 Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
1381{
1383 Datum proallargtypes;
1384 Datum proargmodes;
1385 Datum proargnames;
1386 bool isNull;
1388 int numargs;
1390 int nelems;
1391 int i;
1392
1393
1395 Anum_pg_proc_proallargtypes,
1396 &isNull);
1397 if (!isNull)
1398 {
1399
1400
1401
1402
1403
1404
1408 numargs < 0 ||
1411 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1412 Assert(numargs >= procStruct->pronargs);
1413 *p_argtypes = (Oid *) palloc(numargs * sizeof(Oid));
1415 numargs * sizeof(Oid));
1416 }
1417 else
1418 {
1419
1420 numargs = procStruct->proargtypes.dim1;
1421 Assert(numargs == procStruct->pronargs);
1422 *p_argtypes = (Oid *) palloc(numargs * sizeof(Oid));
1423 memcpy(*p_argtypes, procStruct->proargtypes.values,
1424 numargs * sizeof(Oid));
1425 }
1426
1427
1429 Anum_pg_proc_proargnames,
1430 &isNull);
1431 if (isNull)
1432 *p_argnames = NULL;
1433 else
1434 {
1436 &elems, NULL, &nelems);
1437 if (nelems != numargs)
1438 elog(ERROR, "proargnames must have the same number of elements as the function has arguments");
1439 *p_argnames = palloc_array(char *, numargs);
1440 for (i = 0; i < numargs; i++)
1442 }
1443
1444
1446 Anum_pg_proc_proargmodes,
1447 &isNull);
1448 if (isNull)
1449 *p_argmodes = NULL;
1450 else
1451 {
1454 ARR_DIMS(arr)[0] != numargs ||
1457 elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
1458 numargs);
1459 *p_argmodes = (char *) palloc(numargs * sizeof(char));
1461 numargs * sizeof(char));
1462 }
1463
1464 return numargs;
1465}
1466
1467
1468
1469
1470
1471
1472
1473
1474int
1476 Oid **p_trftypes)
1477{
1478 Datum protrftypes;
1480 int nelems;
1481 bool isNull;
1482
1484 Anum_pg_proc_protrftypes,
1485 &isNull);
1486 if (!isNull)
1487 {
1488
1489
1490
1491
1492
1493
1497 nelems < 0 ||
1500 elog(ERROR, "protrftypes is not a 1-D Oid array or it contains nulls");
1501 *p_trftypes = (Oid *) palloc(nelems * sizeof(Oid));
1503 nelems * sizeof(Oid));
1504
1505 return nelems;
1506 }
1507 else
1508 return 0;
1509}
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521int
1523 char ***arg_names)
1524{
1526 int numargs;
1527 Datum *argnames;
1528 char *argmodes;
1529 char **inargnames;
1530 int numinargs;
1531 int i;
1532
1533
1535 {
1536 *arg_names = NULL;
1537 return 0;
1538 }
1539
1540
1541
1542
1543
1544
1549 elog(ERROR, "proargnames is not a 1-D text array or it contains nulls");
1552 {
1555 ARR_DIMS(arr)[0] != numargs ||
1558 elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
1559 numargs);
1561 }
1562 else
1563 argmodes = NULL;
1564
1565
1566 if (numargs <= 0)
1567 {
1568 *arg_names = NULL;
1569 return 0;
1570 }
1571
1572
1573 inargnames = (char **) palloc(numargs * sizeof(char *));
1574 numinargs = 0;
1575 for (i = 0; i < numargs; i++)
1576 {
1577 if (argmodes == NULL ||
1578 argmodes[i] == PROARGMODE_IN ||
1579 argmodes[i] == PROARGMODE_INOUT ||
1580 argmodes[i] == PROARGMODE_VARIADIC)
1581 {
1583
1584 if (pname[0] != '\0')
1585 inargnames[numinargs] = pname;
1586 else
1587 inargnames[numinargs] = NULL;
1588 numinargs++;
1589 }
1590 }
1591
1592 *arg_names = inargnames;
1593 return numinargs;
1594}
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606char *
1608{
1609 char *result;
1611 Datum proargmodes;
1612 Datum proargnames;
1614 int numargs;
1615 char *argmodes;
1616 Datum *argnames;
1617 int numoutargs;
1618 int nargnames;
1619 int i;
1620
1621
1624 elog(ERROR, "cache lookup failed for function %u", functionId);
1625
1626
1627 if (heap_attisnull(procTuple, Anum_pg_proc_proargmodes, NULL) ||
1628 heap_attisnull(procTuple, Anum_pg_proc_proargnames, NULL))
1629 result = NULL;
1630 else
1631 {
1632
1634 Anum_pg_proc_proargmodes);
1636 Anum_pg_proc_proargnames);
1637
1638
1639
1640
1641
1642
1643
1647 numargs < 0 ||
1650 elog(ERROR, "proargmodes is not a 1-D char array or it contains nulls");
1654 ARR_DIMS(arr)[0] != numargs ||
1657 elog(ERROR, "proargnames is not a 1-D text array of length %d or it contains nulls",
1658 numargs);
1660 Assert(nargnames == numargs);
1661
1662
1663 result = NULL;
1664 numoutargs = 0;
1665 for (i = 0; i < numargs; i++)
1666 {
1667 if (argmodes[i] == PROARGMODE_IN ||
1668 argmodes[i] == PROARGMODE_VARIADIC)
1669 continue;
1670 Assert(argmodes[i] == PROARGMODE_OUT ||
1671 argmodes[i] == PROARGMODE_INOUT ||
1672 argmodes[i] == PROARGMODE_TABLE);
1673 if (++numoutargs > 1)
1674 {
1675
1676 result = NULL;
1677 break;
1678 }
1680 if (result == NULL || result[0] == '\0')
1681 {
1682
1683 result = NULL;
1684 break;
1685 }
1686 }
1687 }
1688
1690
1691 return result;
1692}
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1706{
1708 Datum proallargtypes;
1709 Datum proargmodes;
1710 Datum proargnames;
1711 bool isnull;
1712
1713
1714 if (procform->prorettype != RECORDOID)
1715 return NULL;
1716
1717
1718 if (heap_attisnull(procTuple, Anum_pg_proc_proallargtypes, NULL) ||
1719 heap_attisnull(procTuple, Anum_pg_proc_proargmodes, NULL))
1720 return NULL;
1721
1722
1724 Anum_pg_proc_proallargtypes);
1726 Anum_pg_proc_proargmodes);
1728 Anum_pg_proc_proargnames,
1729 &isnull);
1730 if (isnull)
1731 proargnames = PointerGetDatum(NULL);
1732
1734 proallargtypes,
1735 proargmodes,
1736 proargnames);
1737}
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1752 Datum proallargtypes,
1753 Datum proargmodes,
1754 Datum proargnames)
1755{
1758 int numargs;
1759 Oid *argtypes;
1760 char *argmodes;
1761 Datum *argnames = NULL;
1762 Oid *outargtypes;
1763 char **outargnames;
1764 int numoutargs;
1765 int nargnames;
1766 int i;
1767
1768
1771 return NULL;
1772
1773
1774
1775
1776
1777
1781 numargs < 0 ||
1784 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1788 ARR_DIMS(arr)[0] != numargs ||
1791 elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
1792 numargs);
1795 {
1798 ARR_DIMS(arr)[0] != numargs ||
1801 elog(ERROR, "proargnames is not a 1-D text array of length %d or it contains nulls",
1802 numargs);
1804 Assert(nargnames == numargs);
1805 }
1806
1807
1808 if (numargs <= 0)
1809 return NULL;
1810
1811
1812 outargtypes = (Oid *) palloc(numargs * sizeof(Oid));
1813 outargnames = (char **) palloc(numargs * sizeof(char *));
1814 numoutargs = 0;
1815 for (i = 0; i < numargs; i++)
1816 {
1817 char *pname;
1818
1819 if (argmodes[i] == PROARGMODE_IN ||
1820 argmodes[i] == PROARGMODE_VARIADIC)
1821 continue;
1822 Assert(argmodes[i] == PROARGMODE_OUT ||
1823 argmodes[i] == PROARGMODE_INOUT ||
1824 argmodes[i] == PROARGMODE_TABLE);
1825 outargtypes[numoutargs] = argtypes[i];
1826 if (argnames)
1828 else
1829 pname = NULL;
1830 if (pname == NULL || pname[0] == '\0')
1831 {
1832
1833 pname = psprintf("column%d", numoutargs + 1);
1834 }
1835 outargnames[numoutargs] = pname;
1836 numoutargs++;
1837 }
1838
1839
1840
1841
1842
1843 if (numoutargs < 2 && prokind != PROKIND_PROCEDURE)
1844 return NULL;
1845
1847 for (i = 0; i < numoutargs; i++)
1848 {
1850 outargnames[i],
1851 outargtypes[i],
1852 -1,
1853 0);
1854 }
1855
1856 return desc;
1857}
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1871{
1875 List *relname_list;
1876
1877
1883
1884 return tupdesc;
1885}
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1904{
1905 Oid base_typeoid;
1908
1909
1910
1911
1912
1913
1914
1916 {
1917
1919
1920 if (colaliases != NIL)
1921 {
1922 int natts = tupdesc->natts;
1923 int varattno;
1924
1925
1928 (errcode(ERRCODE_DATATYPE_MISMATCH),
1929 errmsg("number of aliases does not match number of columns")));
1930
1931
1932 for (varattno = 0; varattno < natts; varattno++)
1933 {
1936
1937 if (label != NULL)
1939 }
1940
1941
1942 tupdesc->tdtypeid = RECORDOID;
1944 }
1945 }
1947 {
1948
1950
1951
1952 if (colaliases == NIL)
1954 (errcode(ERRCODE_DATATYPE_MISMATCH),
1955 errmsg("no column alias was provided")));
1956
1957
1960 (errcode(ERRCODE_DATATYPE_MISMATCH),
1961 errmsg("number of aliases does not match number of columns")));
1962
1963
1965
1970 typeoid,
1971 -1,
1972 0);
1973 }
1975 {
1976
1978 (errcode(ERRCODE_DATATYPE_MISMATCH),
1979 errmsg("could not determine row description for function returning record")));
1980 }
1981 else
1982 {
1983
1984 elog(ERROR, "function in FROM has unsupported return type");
1985 }
1986
1987 return tupdesc;
1988}
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004int
2007 bool **nulls)
2008{
2010 Datum *args_res;
2011 bool *nulls_res;
2012 Oid *types_res;
2013 int nargs,
2014 i;
2015
2016 *args = NULL;
2018 *nulls = NULL;
2019
2020 if (variadic)
2021 {
2023 Oid element_type;
2024 bool typbyval;
2027
2029
2031 return -1;
2032
2035
2037 &typlen, &typbyval, &typalign);
2039 typalign, &args_res, &nulls_res,
2040 &nargs);
2041
2042
2043 types_res = (Oid *) palloc0(nargs * sizeof(Oid));
2044 for (i = 0; i < nargs; i++)
2045 types_res[i] = element_type;
2046 }
2047 else
2048 {
2049 nargs = PG_NARGS() - variadic_start;
2051 nulls_res = (bool *) palloc0(nargs * sizeof(bool));
2053 types_res = (Oid *) palloc0(nargs * sizeof(Oid));
2054
2055 for (i = 0; i < nargs; i++)
2056 {
2059 i + variadic_start);
2060
2061
2062
2063
2064
2065
2066
2067
2068 if (convert_unknown &&
2069 types_res[i] == UNKNOWNOID &&
2071 {
2072 types_res[i] = TEXTOID;
2073
2076 else
2077 args_res[i] =
2079 }
2080 else
2081 {
2082
2084 }
2085
2087 (convert_unknown && types_res[i] == UNKNOWNOID))
2089 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2090 errmsg("could not determine data type for argument %d",
2091 i + 1)));
2092 }
2093 }
2094
2095
2096 *args = args_res;
2097 *nulls = nulls_res;
2098 *types = types_res;
2099
2100 return nargs;
2101}
#define PG_GETARG_ARRAYTYPE_P(n)
#define DatumGetArrayTypeP(X)
Datum array_in(PG_FUNCTION_ARGS)
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
#define CStringGetTextDatum(s)
#define TextDatumGetCString(d)
#define OidIsValid(objectId)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
@ SFRM_Materialize_Random
#define palloc_array(type, count)
bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Oid get_call_expr_argtype(Node *expr, int argnum)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
#define DatumGetHeapTupleHeader(X)
#define PG_GETARG_POINTER(n)
#define PG_GETARG_DATUM(n)
char * format_type_be(Oid type_oid)
static TypeFuncClass get_type_func_class(Oid typid, Oid *base_typeid)
struct polymorphic_actuals polymorphic_actuals
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
static TypeFuncClass internal_get_result_type(Oid funcid, Node *call_expr, ReturnSetInfo *rsinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
int get_func_trftypes(HeapTuple procTup, Oid **p_trftypes)
TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple)
char * get_func_result_name(Oid functionId)
TupleDesc build_function_result_tupdesc_d(char prokind, Datum proallargtypes, Datum proargmodes, Datum proargnames)
bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
static void resolve_anyelement_from_others(polymorphic_actuals *actuals)
int get_func_input_arg_names(Datum proargnames, Datum proargmodes, char ***arg_names)
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
static bool resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, Node *call_expr)
FuncCallContext * per_MultiFuncCall(PG_FUNCTION_ARGS)
FuncCallContext * init_MultiFuncCall(PG_FUNCTION_ARGS)
TupleDesc RelationNameGetTupleDesc(const char *relname)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
static void resolve_anyrange_from_others(polymorphic_actuals *actuals)
static void shutdown_MultiFuncCall(Datum arg)
TupleDesc get_expr_result_tupdesc(Node *expr, bool noError)
static void resolve_anymultirange_from_others(polymorphic_actuals *actuals)
TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)
TypeFuncClass get_func_result_type(Oid functionId, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static void resolve_anyarray_from_others(polymorphic_actuals *actuals)
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
@ TYPEFUNC_COMPOSITE_DOMAIN
#define MAT_SRF_USE_EXPECTED_DESC
Assert(PointerIsAligned(start, uint64))
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
#define HeapTupleIsValid(tuple)
static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)
static void * GETSTRUCT(const HeapTupleData *tuple)
static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)
if(TABLE==NULL||TABLE_index==NULL)
Oid get_range_subtype(Oid rangeOid)
Oid get_element_type(Oid typid)
Oid get_multirange_range(Oid multirangeOid)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
RegProcedure get_opcode(Oid opno)
Oid get_typcollation(Oid typid)
Oid get_range_multirange(Oid rangeOid)
char get_typtype(Oid typid)
Oid getBaseType(Oid typid)
Oid get_array_type(Oid typid)
void * MemoryContextAllocZero(MemoryContext context, Size size)
void * palloc0(Size size)
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
void namestrcpy(Name name, const char *str)
RangeVar * makeRangeVarFromNameList(const List *names)
Oid exprType(const Node *expr)
Oid exprInputCollation(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_attribute * Form_pg_attribute
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
static void * list_nth(const List *list, int n)
FormData_pg_proc * Form_pg_proc
static Datum PointerGetDatum(const void *X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
char * psprintf(const char *fmt,...)
List * stringToQualifiedNameList(const char *string, Node *escontext)
#define RelationGetDescr(relation)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
MemoryContext ecxt_per_query_memory
AttInMetadata * attinmeta
MemoryContext multi_call_memory_ctx
SetFunctionReturnMode returnMode
Tuplestorestate * setResult
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)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
TupleDesc CreateTemplateTupleDesc(int natts)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
void assign_record_type_typmod(TupleDesc tupDesc)
TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod)