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 || IsA(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

2075 args_res[i] = (Datum) 0;

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)