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 }

157

161

162 *prorettype_p = rettype;

163 *returnsSet_p = returnType->setof;

164}

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182void

184 List *parameters,

185 Oid languageOid,

188 List **parameterTypes_list,

192 List **inParameterNames_list,

193 List **parameterDefaults,

194 Oid *variadicArgType,

195 Oid *requiredResultType)

196{

197 int parameterCount = list_length(parameters);

198 Oid *inTypes;

199 int inCount = 0;

201 Datum *paramModes;

202 Datum *paramNames;

203 int outCount = 0;

204 int varCount = 0;

205 bool have_names = false;

206 bool have_defaults = false;

208 int i;

209

210 *variadicArgType = InvalidOid;

211 *requiredResultType = InvalidOid;

212

213 inTypes = (Oid *) palloc(parameterCount * sizeof(Oid));

215 paramModes = (Datum *) palloc(parameterCount * sizeof(Datum));

217 *parameterDefaults = NIL;

218

219

220 i = 0;

221 foreach(x, parameters)

222 {

226 bool isinput = false;

227 Oid toid;

230

231

234

236 if (typtup)

237 {

239 {

240

241 if (languageOid == SQLlanguageId)

243 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

244 errmsg("SQL function cannot accept shell type %s",

247

250 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

251 errmsg("aggregate cannot accept shell type %s",

254 else

256 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

257 errmsg("argument type %s is only a shell",

260 }

263 }

264 else

265 {

267 (errcode(ERRCODE_UNDEFINED_OBJECT),

268 errmsg("type %s does not exist",

271 toid = InvalidOid;

272 }

273

277

279 {

282 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

283 errmsg("aggregates cannot accept set arguments"),

287 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

288 errmsg("procedures cannot accept set arguments"),

290 else

292 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

293 errmsg("functions cannot accept set arguments"),

295 }

296

297

299 {

300

301 if (varCount > 0)

303 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

304 errmsg("VARIADIC parameter must be the last input parameter"),

306 inTypes[inCount++] = toid;

307 isinput = true;

308 if (parameterTypes_list)

309 *parameterTypes_list = lappend_oid(*parameterTypes_list, toid);

310 }

311

312

314 {

316 {

317

318

319

320

321

322 if (varCount > 0)

324 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

325 errmsg("VARIADIC parameter must be the last parameter"),

327

328 *requiredResultType = RECORDOID;

329 }

330 else if (outCount == 0)

331 *requiredResultType = toid;

332 outCount++;

333 }

334

336 {

337 *variadicArgType = toid;

338 varCount++;

339

340 switch (toid)

341 {

342 case ANYARRAYOID:

343 case ANYCOMPATIBLEARRAYOID:

344 case ANYOID:

345

346 break;

347 default:

350 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

351 errmsg("VARIADIC parameter must be an array"),

353 break;

354 }

355 }

356

358

360

362 {

364

365

366

367

368

369

370

371 foreach(px, parameters)

372 {

375

376 if (prevfp == fp)

377 break;

378

379 prevfpmode = prevfp->mode;

382

387 continue;

392 continue;

393 if (prevfp->name && prevfp->name[0] &&

394 strcmp(prevfp->name, fp->name) == 0)

396 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

397 errmsg("parameter name \"%s\" used more than once",

400 }

401

403 have_names = true;

404 }

405

406 if (inParameterNames_list)

408

410 {

412

413 if (!isinput)

415 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

416 errmsg("only input parameters can have default values"),

418

423

424

425

426

427

431 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),

432 errmsg("cannot use table references in parameter default value"),

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449 *parameterDefaults = lappend(*parameterDefaults, def);

450 have_defaults = true;

451 }

452 else

453 {

454 if (isinput && have_defaults)

456 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

457 errmsg("input parameters after one with a default value must also have defaults"),

459

460

461

462

463

464

467 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

468 errmsg("procedure OUT parameters cannot appear after one with a default value"),

470 }

471

472 i++;

473 }

474

475

477

478 if (outCount > 0 || varCount > 0)

479 {

482 if (outCount > 1)

483 *requiredResultType = RECORDOID;

484

485 }

486 else

487 {

488 *allParameterTypes = NULL;

489 *parameterModes = NULL;

490 }

491

492 if (have_names)

493 {

494 for (i = 0; i < parameterCount; i++)

495 {

498 }

500 }

501 else

502 *parameterNames = NULL;

503}

504

505

506

507

508

509

510

511

512

513

514static bool

516 bool is_procedure,

518 DefElem **volatility_item,

521 DefElem **leakproof_item,

522 List **set_items,

527{

528 if (strcmp(defel->defname, "volatility") == 0)

529 {

530 if (is_procedure)

531 goto procedure_error;

532 if (*volatility_item)

534

535 *volatility_item = defel;

536 }

537 else if (strcmp(defel->defname, "strict") == 0)

538 {

539 if (is_procedure)

540 goto procedure_error;

541 if (*strict_item)

543

544 *strict_item = defel;

545 }

546 else if (strcmp(defel->defname, "security") == 0)

547 {

548 if (*security_item)

550

551 *security_item = defel;

552 }

553 else if (strcmp(defel->defname, "leakproof") == 0)

554 {

555 if (is_procedure)

556 goto procedure_error;

557 if (*leakproof_item)

559

560 *leakproof_item = defel;

561 }

562 else if (strcmp(defel->defname, "set") == 0)

563 {

564 *set_items = lappend(*set_items, defel->arg);

565 }

566 else if (strcmp(defel->defname, "cost") == 0)

567 {

568 if (is_procedure)

569 goto procedure_error;

570 if (*cost_item)

572

573 *cost_item = defel;

574 }

575 else if (strcmp(defel->defname, "rows") == 0)

576 {

577 if (is_procedure)

578 goto procedure_error;

579 if (*rows_item)

581

582 *rows_item = defel;

583 }

584 else if (strcmp(defel->defname, "support") == 0)

585 {

586 if (is_procedure)

587 goto procedure_error;

588 if (*support_item)

590

591 *support_item = defel;

592 }

593 else if (strcmp(defel->defname, "parallel") == 0)

594 {

595 if (is_procedure)

596 goto procedure_error;

597 if (*parallel_item)

599

600 *parallel_item = defel;

601 }

602 else

603 return false;

604

605

606 return true;

607

608procedure_error:

610 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

611 errmsg("invalid attribute in procedure definition"),

613 return false;

614}

615

616static char

618{

620

621 if (strcmp(str, "immutable") == 0)

622 return PROVOLATILE_IMMUTABLE;

623 else if (strcmp(str, "stable") == 0)

624 return PROVOLATILE_STABLE;

625 else if (strcmp(str, "volatile") == 0)

626 return PROVOLATILE_VOLATILE;

627 else

628 {

629 elog(ERROR, "invalid volatility \"%s\"", str);

630 return 0;

631 }

632}

633

634static char

636{

638

639 if (strcmp(str, "safe") == 0)

640 return PROPARALLEL_SAFE;

641 else if (strcmp(str, "unsafe") == 0)

642 return PROPARALLEL_UNSAFE;

643 else if (strcmp(str, "restricted") == 0)

644 return PROPARALLEL_RESTRICTED;

645 else

646 {

648 (errcode(ERRCODE_SYNTAX_ERROR),

649 errmsg("parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));

650 return PROPARALLEL_UNSAFE;

651 }

652}

653

654

655

656

657

658

661{

663

664 foreach(l, set_items)

665 {

667

669 a = NULL;

670 else

671 {

673

674 if (valuestr)

676 else

678 }

679 }

680

681 return a;

682}

683

684static Oid

686{

688 Oid procOid;

689 Oid argList[1];

690

691

692

693

694

695 argList[0] = INTERNALOID;

696

697 procOid = LookupFuncName(procName, 1, argList, true);

700 (errcode(ERRCODE_UNDEFINED_FUNCTION),

701 errmsg("function %s does not exist",

703

706 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

707 errmsg("support function %s must return type %s",

709

710

711

712

713

714

717 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

718 errmsg("must be superuser to specify a support function")));

719

720 return procOid;

721}

722

723

724

725

726

727

728static void

730 bool is_procedure,

733 char **language,

734 Node **transform,

735 bool *windowfunc_p,

736 char *volatility_p,

737 bool *strict_p,

738 bool *security_definer,

739 bool *leakproof_p,

743 Oid *prosupport,

744 char *parallel_p)

745{

748 DefElem *language_item = NULL;

749 DefElem *transform_item = NULL;

750 DefElem *windowfunc_item = NULL;

751 DefElem *volatility_item = NULL;

752 DefElem *strict_item = NULL;

753 DefElem *security_item = NULL;

754 DefElem *leakproof_item = NULL;

756 DefElem *cost_item = NULL;

757 DefElem *rows_item = NULL;

758 DefElem *support_item = NULL;

759 DefElem *parallel_item = NULL;

760

762 {

764

765 if (strcmp(defel->defname, "as") == 0)

766 {

767 if (as_item)

769 as_item = defel;

770 }

771 else if (strcmp(defel->defname, "language") == 0)

772 {

773 if (language_item)

775 language_item = defel;

776 }

777 else if (strcmp(defel->defname, "transform") == 0)

778 {

779 if (transform_item)

781 transform_item = defel;

782 }

783 else if (strcmp(defel->defname, "window") == 0)

784 {

785 if (windowfunc_item)

787 if (is_procedure)

789 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

790 errmsg("invalid attribute in procedure definition"),

792 windowfunc_item = defel;

793 }

795 is_procedure,

796 defel,

797 &volatility_item,

798 &strict_item,

799 &security_item,

800 &leakproof_item,

801 &set_items,

802 &cost_item,

803 &rows_item,

804 &support_item,

805 &parallel_item))

806 {

807

808 continue;

809 }

810 else

811 elog(ERROR, "option \"%s\" not recognized",

813 }

814

815 if (as_item)

816 *as = (List *) as_item->arg;

817 if (language_item)

818 *language = strVal(language_item->arg);

819 if (transform_item)

820 *transform = transform_item->arg;

821 if (windowfunc_item)

822 *windowfunc_p = boolVal(windowfunc_item->arg);

823 if (volatility_item)

825 if (strict_item)

826 *strict_p = boolVal(strict_item->arg);

827 if (security_item)

828 *security_definer = boolVal(security_item->arg);

829 if (leakproof_item)

830 *leakproof_p = boolVal(leakproof_item->arg);

831 if (set_items)

833 if (cost_item)

834 {

836 if (*procost <= 0)

838 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

839 errmsg("COST must be positive")));

840 }

841 if (rows_item)

842 {

844 if (*prorows <= 0)

846 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

847 errmsg("ROWS must be positive")));

848 }

849 if (support_item)

851 if (parallel_item)

853}

854

855

856

857

858

859

860

861

862

863

864

865static void

868 List *parameterTypes, List *inParameterNames,

869 char **prosrc_str_p, char **probin_str_p,

870 Node **sql_body_out,

871 const char *queryString)

872{

873 if (!sql_body_in && !as)

875 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

876 errmsg("no function body specified")));

877

878 if (sql_body_in && as)

880 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

881 errmsg("duplicate function body specified")));

882

883 if (sql_body_in && languageOid != SQLlanguageId)

885 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

886 errmsg("inline SQL function body only valid for language SQL")));

887

888 *sql_body_out = NULL;

889

890 if (languageOid == ClanguageId)

891 {

892

893

894

895

896

897

898

899

903 else

904 {

906 if (strcmp(*prosrc_str_p, "-") == 0)

908 }

909 }

910 else if (sql_body_in)

911 {

913

915

920 for (int i = 0; i < list_length(parameterTypes); i++)

921 {

923

925 if (IsPolymorphicType(pinfo->argtypes[i]))

927 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

928 errmsg("SQL function with unquoted function body cannot have polymorphic arguments")));

929

930 if (s[0] != '\0')

932 else

934 }

935

936 if (IsA(sql_body_in, List))

937 {

940 List *transformed_stmts = NIL;

941

942 foreach(lc, stmts)

943 {

947

953 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

954 errmsg("%s is not yet supported in unquoted SQL function body",

956 transformed_stmts = lappend(transformed_stmts, q);

958 }

959

960 *sql_body_out = (Node *) list_make1(transformed_stmts);

961 }

962 else

963 {

966

972 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

973 errmsg("%s is not yet supported in unquoted SQL function body",

976

977 *sql_body_out = (Node *) q;

978 }

979

980

981

982

983

984

985

986

987 *prosrc_str_p = pstrdup("");

988

989

990 *probin_str_p = NULL;

991 }

992 else

993 {

994

996 *probin_str_p = NULL;

997

1000 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

1001 errmsg("only one AS item needed for language \"%s\"",

1002 languageName)));

1003

1004 if (languageOid == INTERNALlanguageId)

1005 {

1006

1007

1008

1009

1010

1011

1012

1013

1014 if (strlen(*prosrc_str_p) == 0)

1016 }

1017 }

1018}

1019

1020

1021

1022

1023

1024

1027{

1028 char *probin_str;

1029 char *prosrc_str;

1030 Node *prosqlbody;

1031 Oid prorettype;

1032 bool returnsSet;

1033 char *language;

1034 Oid languageOid;

1035 Oid languageValidator;

1036 Node *transformDefElem = NULL;

1038 Oid namespaceId;

1041 List *parameterTypes_list = NIL;

1045 List *inParameterNames_list = NIL;

1046 List *parameterDefaults;

1047 Oid variadicArgType;

1048 List *trftypes_list = NIL;

1049 List *trfoids_list = NIL;

1051 Oid requiredResultType;

1052 bool isWindowFunc,

1053 isStrict,

1054 security,

1055 isLeakProof;

1056 char volatility;

1060 Oid prosupport;

1063 List *as_clause;

1064 char parallel;

1065

1066

1069

1070

1075

1076

1077 as_clause = NIL;

1078 language = NULL;

1079 isWindowFunc = false;

1080 isStrict = false;

1081 security = false;

1082 isLeakProof = false;

1083 volatility = PROVOLATILE_VOLATILE;

1084 proconfig = NULL;

1085 procost = -1;

1086 prorows = -1;

1088 parallel = PROPARALLEL_UNSAFE;

1089

1090

1092 stmt->is_procedure,

1093 stmt->options,

1094 &as_clause, &language, &transformDefElem,

1095 &isWindowFunc, &volatility,

1096 &isStrict, &security, &isLeakProof,

1097 &proconfig, &procost, &prorows,

1098 &prosupport, &parallel);

1099

1100 if (!language)

1101 {

1102 if (stmt->sql_body)

1103 language = "sql";

1104 else

1106 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

1107 errmsg("no language specified")));

1108 }

1109

1110

1114 (errcode(ERRCODE_UNDEFINED_OBJECT),

1115 errmsg("language \"%s\" does not exist", language),

1117 errhint("Use CREATE EXTENSION to load the language into the database.") : 0)));

1118

1120 languageOid = languageStruct->oid;

1121

1122 if (languageStruct->lanpltrusted)

1123 {

1124

1128 NameStr(languageStruct->lanname));

1129 }

1130 else

1131 {

1132

1135 NameStr(languageStruct->lanname));

1136 }

1137

1138 languageValidator = languageStruct->lanvalidator;

1139

1141

1142

1143

1144

1145

1146

1147 if (isLeakProof && superuser())

1149 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

1150 errmsg("only superuser can define a leakproof function")));

1151

1152 if (transformDefElem)

1153 {

1155

1156 foreach(lc, castNode(List, transformDefElem))

1157 {

1161 Oid transformid;

1162

1163 typeid = elt ? elt : typeid;

1165 trftypes_list = lappend_oid(trftypes_list, typeid);

1166 trfoids_list = lappend_oid(trfoids_list, transformid);

1167 }

1168 }

1169

1170

1171

1172

1173

1175 stmt->parameters,

1176 languageOid,

1178 &parameterTypes,

1179 &parameterTypes_list,

1180 &allParameterTypes,

1181 &parameterModes,

1182 &parameterNames,

1183 &inParameterNames_list,

1184 &parameterDefaults,

1185 &variadicArgType,

1186 &requiredResultType);

1187

1188 if (stmt->is_procedure)

1189 {

1191 prorettype = requiredResultType ? requiredResultType : VOIDOID;

1192 returnsSet = false;

1193 }

1194 else if (stmt->returnType)

1195 {

1196

1198 &prorettype, &returnsSet);

1199 if (OidIsValid(requiredResultType) && prorettype != requiredResultType)

1201 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

1202 errmsg("function result type must be %s because of OUT parameters",

1204 }

1205 else if (OidIsValid(requiredResultType))

1206 {

1207

1208 prorettype = requiredResultType;

1209 returnsSet = false;

1210 }

1211 else

1212 {

1214 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

1215 errmsg("function result type must be specified")));

1216

1217 prorettype = VOIDOID;

1218 returnsSet = false;

1219 }

1220

1221 if (trftypes_list != NIL)

1222 {

1225 int i;

1226

1228 i = 0;

1229 foreach(lc, trftypes_list)

1232 }

1233 else

1234 {

1235

1236 trftypes = NULL;

1237 }

1238

1240 parameterTypes_list, inParameterNames_list,

1241 &prosrc_str, &probin_str, &prosqlbody,

1243

1244

1245

1246

1247

1248

1249 if (procost < 0)

1250 {

1251

1252 if (languageOid == INTERNALlanguageId ||

1253 languageOid == ClanguageId)

1254 procost = 1;

1255 else

1256 procost = 100;

1257 }

1258 if (prorows < 0)

1259 {

1260 if (returnsSet)

1261 prorows = 1000;

1262 else

1263 prorows = 0;

1264 }

1265 else if (!returnsSet)

1267 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1268 errmsg("ROWS is not applicable when function does not return a set")));

1269

1270

1271

1272

1273

1275 namespaceId,

1276 stmt->replace,

1277 returnsSet,

1278 prorettype,

1280 languageOid,

1281 languageValidator,

1282 prosrc_str,

1283 probin_str,

1284 prosqlbody,

1285 stmt->is_procedure ? PROKIND_PROCEDURE : (isWindowFunc ? PROKIND_WINDOW : PROKIND_FUNCTION),

1286 security,

1287 isLeakProof,

1288 isStrict,

1289 volatility,

1290 parallel,

1291 parameterTypes,

1295 parameterDefaults,

1297 trfoids_list,

1299 prosupport,

1300 procost,

1301 prorows);

1302}

1303

1304

1305

1306

1307

1308

1309

1310void

1312{

1315 char prokind;

1316

1317

1318

1319

1321

1324 elog(ERROR, "cache lookup failed for function %u", funcOid);

1325

1327

1329

1331

1333

1335

1336

1337

1338

1339 if (prokind == PROKIND_AGGREGATE)

1340 {

1342

1345 elog(ERROR, "cache lookup failed for pg_aggregate tuple for function %u", funcOid);

1346

1348

1350

1352 }

1353}

1354

1355

1356

1357

1358

1359

1362{

1364 Oid funcOid;

1366 bool is_procedure;

1369 DefElem *volatility_item = NULL;

1370 DefElem *strict_item = NULL;

1371 DefElem *security_def_item = NULL;

1372 DefElem *leakproof_item = NULL;

1374 DefElem *cost_item = NULL;

1375 DefElem *rows_item = NULL;

1376 DefElem *support_item = NULL;

1377 DefElem *parallel_item = NULL;

1379

1381

1383

1385

1388 elog(ERROR, "cache lookup failed for function %u", funcOid);

1389

1391

1392

1396

1397 if (procForm->prokind == PROKIND_AGGREGATE)

1399 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1400 errmsg("\"%s\" is an aggregate function",

1402

1403 is_procedure = (procForm->prokind == PROKIND_PROCEDURE);

1404

1405

1406 foreach(l, stmt->actions)

1407 {

1409

1411 is_procedure,

1412 defel,

1413 &volatility_item,

1414 &strict_item,

1415 &security_def_item,

1416 &leakproof_item,

1417 &set_items,

1418 &cost_item,

1419 &rows_item,

1420 &support_item,

1421 &parallel_item) == false)

1422 elog(ERROR, "option \"%s\" not recognized", defel->defname);

1423 }

1424

1425 if (volatility_item)

1427 if (strict_item)

1428 procForm->proisstrict = boolVal(strict_item->arg);

1429 if (security_def_item)

1430 procForm->prosecdef = boolVal(security_def_item->arg);

1431 if (leakproof_item)

1432 {

1433 procForm->proleakproof = boolVal(leakproof_item->arg);

1434 if (procForm->proleakproof && superuser())

1436 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

1437 errmsg("only superuser can define a leakproof function")));

1438 }

1439 if (cost_item)

1440 {

1442 if (procForm->procost <= 0)

1444 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1445 errmsg("COST must be positive")));

1446 }

1447 if (rows_item)

1448 {

1450 if (procForm->prorows <= 0)

1452 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1453 errmsg("ROWS must be positive")));

1454 if (!procForm->proretset)

1456 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1457 errmsg("ROWS is not applicable when function does not return a set")));

1458 }

1459 if (support_item)

1460 {

1461

1463

1464

1465 if (OidIsValid(procForm->prosupport))

1466 {

1468 ProcedureRelationId, procForm->prosupport,

1469 newsupport) != 1)

1470 elog(ERROR, "could not change support dependency for function %s",

1472 }

1473 else

1474 {

1476

1477 referenced.classId = ProcedureRelationId;

1478 referenced.objectId = newsupport;

1481 }

1482

1483 procForm->prosupport = newsupport;

1484 }

1485 if (parallel_item)

1487 if (set_items)

1488 {

1490 bool isnull;

1492 Datum repl_val[Natts_pg_proc];

1493 bool repl_null[Natts_pg_proc];

1494 bool repl_repl[Natts_pg_proc];

1495

1496

1497 datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_proconfig, &isnull);

1499

1500

1502

1503

1504 memset(repl_repl, false, sizeof(repl_repl));

1505 repl_repl[Anum_pg_proc_proconfig - 1] = true;

1506

1507 if (a == NULL)

1508 {

1509 repl_val[Anum_pg_proc_proconfig - 1] = (Datum) 0;

1510 repl_null[Anum_pg_proc_proconfig - 1] = true;

1511 }

1512 else

1513 {

1515 repl_null[Anum_pg_proc_proconfig - 1] = false;

1516 }

1517

1519 repl_val, repl_null, repl_repl);

1520 }

1521

1522

1523

1525

1527

1530

1531 return address;

1532}

1533

1534

1535

1536

1537

1540{

1541 Oid sourcetypeid;

1542 Oid targettypeid;

1543 char sourcetyptype;

1544 char targettyptype;

1545 Oid funcid;

1548 int nargs;

1549 char castcontext;

1550 char castmethod;

1554

1557 sourcetyptype = get_typtype(sourcetypeid);

1558 targettyptype = get_typtype(targettypeid);

1559

1560

1561 if (sourcetyptype == TYPTYPE_PSEUDO)

1563 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1564 errmsg("source data type %s is a pseudo-type",

1566

1567 if (targettyptype == TYPTYPE_PSEUDO)

1569 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1570 errmsg("target data type %s is a pseudo-type",

1572

1573

1577 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

1578 errmsg("must be owner of type %s or type %s",

1581

1585

1589

1590

1591 if (sourcetyptype == TYPTYPE_DOMAIN)

1593 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1594 errmsg("cast will be ignored because the source data type is a domain")));

1595

1596 else if (targettyptype == TYPTYPE_DOMAIN)

1598 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1599 errmsg("cast will be ignored because the target data type is a domain")));

1600

1601

1602 if (stmt->func != NULL)

1603 castmethod = COERCION_METHOD_FUNCTION;

1604 else if (stmt->inout)

1605 castmethod = COERCION_METHOD_INOUT;

1606 else

1607 castmethod = COERCION_METHOD_BINARY;

1608

1609 if (castmethod == COERCION_METHOD_FUNCTION)

1610 {

1612

1614

1617 elog(ERROR, "cache lookup failed for function %u", funcid);

1618

1620 nargs = procstruct->pronargs;

1621 if (nargs < 1 || nargs > 3)

1623 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1624 errmsg("cast function must take one to three arguments")));

1626 procstruct->proargtypes.values[0],

1627 &incastid))

1629 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1630 errmsg("argument of cast function must match or be binary-coercible from source data type")));

1631 if (nargs > 1 && procstruct->proargtypes.values[1] != INT4OID)

1633 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1634 errmsg("second argument of cast function must be type %s",

1635 "integer")));

1636 if (nargs > 2 && procstruct->proargtypes.values[2] != BOOLOID)

1638 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1639 errmsg("third argument of cast function must be type %s",

1640 "boolean")));

1642 targettypeid,

1643 &outcastid))

1645 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1646 errmsg("return data type of cast function must match or be binary-coercible to target data type")));

1647

1648

1649

1650

1651

1652

1653#ifdef NOT_USED

1654 if (procstruct->provolatile == PROVOLATILE_VOLATILE)

1656 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1657 errmsg("cast function must not be volatile")));

1658#endif

1659 if (procstruct->prokind != PROKIND_FUNCTION)

1661 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1662 errmsg("cast function must be a normal function")));

1663 if (procstruct->proretset)

1665 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1666 errmsg("cast function must not return a set")));

1667

1669 }

1670 else

1671 {

1673 nargs = 0;

1674 }

1675

1676 if (castmethod == COERCION_METHOD_BINARY)

1677 {

1680 bool typ1byval;

1681 bool typ2byval;

1682 char typ1align;

1683 char typ2align;

1684

1685

1686

1687

1688

1691 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

1692 errmsg("must be superuser to create a cast WITHOUT FUNCTION")));

1693

1694

1695

1696

1697

1698

1699

1702 if (typ1len != typ2len ||

1703 typ1byval != typ2byval ||

1704 typ1align != typ2align)

1706 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1707 errmsg("source and target data types are not physically compatible")));

1708

1709

1710

1711

1712

1713

1714

1715

1716

1717

1718

1719

1720

1721

1722

1723 if (sourcetyptype == TYPTYPE_COMPOSITE ||

1724 targettyptype == TYPTYPE_COMPOSITE)

1726 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1727 errmsg("composite data types are not binary-compatible")));

1728

1732 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1733 errmsg("array data types are not binary-compatible")));

1734

1735 if (sourcetyptype == TYPTYPE_RANGE ||

1736 targettyptype == TYPTYPE_RANGE ||

1737 sourcetyptype == TYPTYPE_MULTIRANGE ||

1738 targettyptype == TYPTYPE_MULTIRANGE)

1740 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1741 errmsg("range data types are not binary-compatible")));

1742

1743 if (sourcetyptype == TYPTYPE_ENUM ||

1744 targettyptype == TYPTYPE_ENUM)

1746 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1747 errmsg("enum data types are not binary-compatible")));

1748

1749

1750

1751

1752

1753

1754

1755

1756

1757

1758

1759

1760 if (sourcetyptype == TYPTYPE_DOMAIN ||

1761 targettyptype == TYPTYPE_DOMAIN)

1763 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1764 errmsg("domain data types must not be marked binary-compatible")));

1765 }

1766

1767

1768

1769

1770

1771 if (sourcetypeid == targettypeid && nargs < 2)

1773 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1774 errmsg("source data type and target data type are the same")));

1775

1776

1777 switch (stmt->context)

1778 {

1780 castcontext = COERCION_CODE_IMPLICIT;

1781 break;

1783 castcontext = COERCION_CODE_ASSIGNMENT;

1784 break;

1785

1787 castcontext = COERCION_CODE_EXPLICIT;

1788 break;

1789 default:

1790 elog(ERROR, "unrecognized CoercionContext: %d", stmt->context);

1791 castcontext = 0;

1792 break;

1793 }

1794

1795 myself = CastCreate(sourcetypeid, targettypeid, funcid, incastid, outcastid,

1797 return myself;

1798}

1799

1800

1801static void

1803{

1804 if (procstruct->provolatile == PROVOLATILE_VOLATILE)

1806 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1807 errmsg("transform function must not be volatile")));

1808 if (procstruct->prokind != PROKIND_FUNCTION)

1810 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1811 errmsg("transform function must be a normal function")));

1812 if (procstruct->proretset)

1814 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1815 errmsg("transform function must not return a set")));

1816 if (procstruct->pronargs != 1)

1818 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1819 errmsg("transform function must take one argument")));

1820 if (procstruct->proargtypes.values[0] != INTERNALOID)

1822 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1823 errmsg("first argument of transform function must be type %s",

1824 "internal")));

1825}

1826

1827

1828

1829

1830

1833{

1834 Oid typeid;

1835 char typtype;

1836 Oid langid;

1837 Oid fromsqlfuncid;

1838 Oid tosqlfuncid;

1842 bool nulls[Natts_pg_transform] = {0};

1843 bool replaces[Natts_pg_transform] = {0};

1844 Oid transformid;

1849 referenced;

1851 bool is_replace;

1852

1853

1854

1855

1858

1859 if (typtype == TYPTYPE_PSEUDO)

1861 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1862 errmsg("data type %s is a pseudo-type",

1864

1865 if (typtype == TYPTYPE_DOMAIN)

1867 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1868 errmsg("data type %s is a domain",

1870

1873

1877

1878

1879

1880

1882

1886

1887

1888

1889

1890 if (stmt->fromsql)

1891 {

1893

1896

1900

1903 elog(ERROR, "cache lookup failed for function %u", fromsqlfuncid);

1905 if (procstruct->prorettype != INTERNALOID)

1907 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1908 errmsg("return data type of FROM SQL function must be %s",

1909 "internal")));

1912 }

1913 else

1915

1916 if (stmt->tosql)

1917 {

1919

1922

1926

1929 elog(ERROR, "cache lookup failed for function %u", tosqlfuncid);

1931 if (procstruct->prorettype != typeid)

1933 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1934 errmsg("return data type of TO SQL function must be the transform data type")));

1937 }

1938 else

1940

1941

1942

1943

1948

1950

1955 {

1957

1958 if (stmt->replace)

1961 errmsg("transform for type %s language \"%s\" already exists",

1963 stmt->lang)));

1964

1965 replaces[Anum_pg_transform_trffromsql - 1] = true;

1966 replaces[Anum_pg_transform_trftosql - 1] = true;

1967

1970

1971 transformid = form->oid;

1973 is_replace = true;

1974 }

1975 else

1976 {

1978 Anum_pg_transform_oid);

1982 is_replace = false;

1983 }

1984

1985 if (is_replace)

1987

1989

1990

1992

1993

1996

1997

2000

2001

2003 {

2004 ObjectAddressSet(referenced, ProcedureRelationId, fromsqlfuncid);

2006 }

2008 {

2009 ObjectAddressSet(referenced, ProcedureRelationId, tosqlfuncid);

2011 }

2012

2015

2016

2018

2019

2021

2023

2025

2026 return myself;

2027}

2028

2029

2030

2031

2032

2033

2034

2035

2038{

2039 Oid oid;

2040

2041 oid = GetSysCacheOid2(TRFTYPELANG, Anum_pg_transform_oid,

2044 if (OidIsValid(oid) && !missing_ok)

2046 (errcode(ERRCODE_UNDEFINED_OBJECT),

2047 errmsg("transform for type %s language \"%s\" does not exist",

2050 return oid;

2051}

2052

2053

2054

2055

2056

2057

2058

2059

2060void

2063{

2064

2070 (errcode(ERRCODE_DUPLICATE_FUNCTION),

2071 errmsg("function %s already exists in schema \"%s\"",

2075}

2076

2077

2078

2079

2080

2081

2082

2083void

2085{

2088 DefElem *as_item = NULL;

2089 DefElem *language_item = NULL;

2090 char *language;

2091 Oid laninline;

2094

2095

2096 foreach(arg, stmt->args)

2097 {

2099

2100 if (strcmp(defel->defname, "as") == 0)

2101 {

2102 if (as_item)

2104 as_item = defel;

2105 }

2106 else if (strcmp(defel->defname, "language") == 0)

2107 {

2108 if (language_item)

2110 language_item = defel;

2111 }

2112 else

2113 elog(ERROR, "option \"%s\" not recognized",

2115 }

2116

2117 if (as_item)

2119 else

2121 (errcode(ERRCODE_SYNTAX_ERROR),

2122 errmsg("no inline code specified")));

2123

2124

2125 if (language_item)

2126 language = strVal(language_item->arg);

2127 else

2128 language = "plpgsql";

2129

2130

2134 (errcode(ERRCODE_UNDEFINED_OBJECT),

2135 errmsg("language \"%s\" does not exist", language),

2137 errhint("Use CREATE EXTENSION to load the language into the database.") : 0)));

2138

2140 codeblock->langOid = languageStruct->oid;

2141 codeblock->langIsTrusted = languageStruct->lanpltrusted;

2142 codeblock->atomic = atomic;

2143

2144 if (languageStruct->lanpltrusted)

2145 {

2146

2148

2153 NameStr(languageStruct->lanname));

2154 }

2155 else

2156 {

2157

2160 NameStr(languageStruct->lanname));

2161 }

2162

2163

2164 laninline = languageStruct->laninline;

2167 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

2168 errmsg("language \"%s\" does not support inline code execution",

2169 NameStr(languageStruct->lanname))));

2170

2172

2173

2175}

2176

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

2205void

2207{

2211 int nargs;

2212 int i;

2221

2222 fexpr = stmt->funcexpr;

2225

2229

2230

2232 callcontext->atomic = atomic;

2233

2236 elog(ERROR, "cache lookup failed for function %u", fexpr->funcid);

2237

2238

2239

2240

2241

2242

2243

2244 if (heap\_attisnull(tp, Anum_pg_proc_proconfig, NULL))

2245 callcontext->atomic = true;

2246

2247

2248

2249

2250

2251

2252

2254 callcontext->atomic = true;

2255

2257

2258

2262 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),

2263 errmsg_plural("cannot pass more than %d argument to a procedure",

2264 "cannot pass more than %d arguments to a procedure",

2267

2268

2273 (Node *) callcontext, NULL);

2274

2275

2276

2277

2278

2282

2283

2284

2285

2286

2287

2288

2289

2290 if (!atomic)

2292

2293 i = 0;

2294 foreach(lc, fexpr->args)

2295 {

2298 bool isnull;

2299

2301

2303

2304 fcinfo->args[i].value = val;

2305 fcinfo->args[i].isnull = isnull;

2306

2307 i++;

2308 }

2309

2310

2311 if (!atomic)

2313

2314

2318

2319

2320 if (fexpr->funcresulttype == VOIDOID)

2321 {

2322

2323 }

2324 else if (fexpr->funcresulttype == RECORDOID)

2325 {

2326

2328 Oid tupType;

2329 int32 tupTypmod;

2334

2335 if (fcinfo->isnull)

2336 elog(ERROR, "procedure returned null record");

2337

2338

2339

2340

2341

2342

2343

2344

2345

2346

2347

2348

2349

2351

2356

2359

2363 rettupdata.t_data = td;

2364

2367

2369

2371 }

2372 else

2373 elog(ERROR, "unexpected result type for procedure: %u",

2374 fexpr->funcresulttype);

2375

2377}

2378

2379

2380

2381

2384{

2388

2389 fexpr = stmt->funcexpr;

2390

2393 elog(ERROR, "cache lookup failed for procedure %u", fexpr->funcid);

2394

2396

2398

2399

2400

2401

2402

2403

2404

2405

2406

2407

2408

2409 if (tupdesc)

2410 {

2412 for (int i = 0; i < tupdesc->natts; i++)

2413 {

2416

2418 i + 1,

2421 -1,

2422 0);

2423 }

2424 }

2425

2426 return tupdesc;

2427}

void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)

AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)

bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)

void aclcheck_error_type(AclResult aclerr, Oid typeOid)

#define DatumGetArrayTypeP(X)

ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)

static Datum values[MAXATTR]

#define CStringGetTextDatum(s)

#define OidIsValid(objectId)

Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)

const char * GetCommandTagName(CommandTag commandTag)

List * defGetQualifiedName(DefElem *def)

void errorConflictingDefElem(DefElem *defel, ParseState *pstate)

double defGetNumeric(DefElem *def)

void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)

void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)

ObjectAddresses * new_object_addresses(void)

void free_object_addresses(ObjectAddresses *addrs)

int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)

int errdetail(const char *fmt,...)

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

ExprState * ExecPrepareExpr(Expr *node, EState *estate)

void end_tup_output(TupOutputState *tstate)

const TupleTableSlotOps TTSOpsHeapTuple

TupOutputState * begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)

TupleTableSlot * ExecStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)

ExprContext * CreateExprContext(EState *estate)

void FreeExecutorState(EState *estate)

EState * CreateExecutorState(void)

static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)

bool extension_file_exists(const char *extensionName)

void fmgr_info(Oid functionId, FmgrInfo *finfo)

#define OidFunctionCall1(functionId, arg1)

#define DatumGetHeapTupleHeader(X)

#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)

#define LOCAL_FCINFO(name, nargs)

#define FunctionCallInvoke(fcinfo)

#define fmgr_info_set_expr(expr, finfo)

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)

SQLFunctionParseInfo * SQLFunctionParseInfoPtr

void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)

ArrayType * GUCArrayAdd(ArrayType *array, const char *name, const char *value)

ArrayType * GUCArrayDelete(ArrayType *array, const char *name)

char * ExtractSetVariableArgs(VariableSetStmt *stmt)

Assert(PointerIsAligned(start, uint64))

HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)

HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)

bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)

void heap_freetuple(HeapTuple htup)

#define HeapTupleIsValid(tuple)

static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)

static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)

static void * GETSTRUCT(const HeapTupleData *tuple)

static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)

void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)

void CatalogTupleInsert(Relation heapRel, HeapTuple tup)

void CatalogTupleDelete(Relation heapRel, ItemPointer tid)

if(TABLE==NULL||TABLE_index==NULL)

static void ItemPointerSetInvalid(ItemPointerData *pointer)

List * lappend(List *list, void *datum)

List * lappend_oid(List *list, Oid datum)

Oid get_element_type(Oid typid)

void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)

char * get_language_name(Oid langoid, bool missing_ok)

char * get_func_name(Oid funcid)

char get_typtype(Oid typid)

Oid get_base_element_type(Oid typid)

char * get_namespace_name(Oid nspid)

Oid get_func_rettype(Oid funcid)

char * pstrdup(const char *in)

void * palloc0(Size size)

char * NameListToString(const List *names)

Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)

Oid exprType(const Node *expr)

#define IsA(nodeptr, _type_)

#define castNode(_type_, nodeptr)

#define InvokeObjectPostCreateHook(classId, objectId, subId)

#define InvokeObjectPostAlterHook(classId, objectId, subId)

#define InvokeFunctionExecuteHook(objectId)

#define ObjectAddressSet(addr, class_id, object_id)

oidvector * buildoidvector(const Oid *oids, int n)

Node * coerce_to_specific_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *constructName)

bool IsBinaryCoercibleWithCast(Oid srctype, Oid targettype, Oid *castoid)

void assign_expr_collations(ParseState *pstate, Node *expr)

Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)

const char * funcname_signature_string(const char *funcname, int nargs, List *argnames, const Oid *argtypes)

const char * func_signature_string(List *funcname, int nargs, List *argnames, const Oid *argtypes)

Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok)

Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)

void free_parsestate(ParseState *pstate)

int parser_errposition(ParseState *pstate, int location)

ParseState * make_parsestate(ParseState *parentParseState)

@ EXPR_KIND_FUNCTION_DEFAULT

char * TypeNameToString(const TypeName *typeName)

Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)

Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)

Query * transformStmt(ParseState *pstate, Node *parseTree)

FormData_pg_attribute * Form_pg_attribute

ObjectAddress CastCreate(Oid sourcetypeid, Oid targettypeid, Oid funcid, Oid incastid, Oid outcastid, char castcontext, char castmethod, DependencyType behavior)

void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)

long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)

long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)

void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)

FormData_pg_language * Form_pg_language

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define linitial_node(type, l)

static Oid list_nth_oid(const List *list, int n)

static void * list_nth(const List *list, int n)

ObjectAddress ProcedureCreate(const char *procedureName, Oid procNamespace, bool replace, bool returnsSet, Oid returnType, Oid proowner, Oid languageObjectId, Oid languageValidator, const char *prosrc, const char *probin, Node *prosqlbody, char prokind, bool security_definer, bool isLeakProof, bool isStrict, char volatility, char parallel, oidvector *parameterTypes, Datum allParameterTypes, Datum parameterModes, Datum parameterNames, List *parameterDefaults, Datum trftypes, List *trfoids, Datum proconfig, Oid prosupport, float4 procost, float4 prorows)

FormData_pg_proc * Form_pg_proc

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)