PostgreSQL Source Code: src/backend/commands/functioncmds.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

34

74

75

76

77

78

79

80

81

82

83

84

85

86

87static void

89 Oid *prorettype_p, bool *returnsSet_p)

90{

91 Oid rettype;

94

95 typtup = LookupTypeName(NULL, returnType, NULL, false);

96

97 if (typtup)

98 {

100 {

101 if (languageOid == SQLlanguageId)

103 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

104 errmsg("SQL function cannot return shell type %s",

106 else

108 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

109 errmsg("return type %s is only a shell",

111 }

114 }

115 else

116 {

118 Oid namespaceId;

121

122

123

124

125

126

127

128 if (languageOid != INTERNALlanguageId &&

129 languageOid != ClanguageId)

131 (errcode(ERRCODE_UNDEFINED_OBJECT),

132 errmsg("type \"%s\" does not exist", typnam)));

133

134

137 (errcode(ERRCODE_SYNTAX_ERROR),

138 errmsg("type modifier cannot be specified for shell type \"%s\"",

139 typnam)));

140

141

143 (errcode(ERRCODE_UNDEFINED_OBJECT),

144 errmsg("type \"%s\" is not yet defined", typnam),

145 errdetail("Creating a shell type definition.")));

156

158 }

159

163

164 *prorettype_p = rettype;

165 *returnsSet_p = returnType->setof;

166}

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184void

186 List *parameters,

187 Oid languageOid,

190 List **parameterTypes_list,

194 List **inParameterNames_list,

195 List **parameterDefaults,

196 Oid *variadicArgType,

197 Oid *requiredResultType)

198{

199 int parameterCount = list_length(parameters);

200 Oid *inTypes;

201 int inCount = 0;

203 Datum *paramModes;

204 Datum *paramNames;

205 int outCount = 0;

206 int varCount = 0;

207 bool have_names = false;

208 bool have_defaults = false;

210 int i;

211

212 *variadicArgType = InvalidOid;

213 *requiredResultType = InvalidOid;

214

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

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

219 *parameterDefaults = NIL;

220

221

222 i = 0;

223 foreach(x, parameters)

224 {

228 bool isinput = false;

229 Oid toid;

232

233

236

238 if (typtup)

239 {

241 {

242

243 if (languageOid == SQLlanguageId)

245 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

249

252 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

256 else

258 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

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

262 }

265 }

266 else

267 {

269 (errcode(ERRCODE_UNDEFINED_OBJECT),

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

273 toid = InvalidOid;

274 }

275

279

281 {

284 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

289 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

292 else

294 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

297 }

298

299

301 {

302

303 if (varCount > 0)

305 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

308 inTypes[inCount++] = toid;

309 isinput = true;

310 if (parameterTypes_list)

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

312 }

313

314

316 {

318 {

319

320

321

322

323

324 if (varCount > 0)

326 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

329

330 *requiredResultType = RECORDOID;

331 }

332 else if (outCount == 0)

333 *requiredResultType = toid;

334 outCount++;

335 }

336

338 {

339 *variadicArgType = toid;

340 varCount++;

341

342 switch (toid)

343 {

344 case ANYARRAYOID:

345 case ANYCOMPATIBLEARRAYOID:

346 case ANYOID:

347

348 break;

349 default:

352 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

355 break;

356 }

357 }

358

360

362

364 {

366

367

368

369

370

371

372

373 foreach(px, parameters)

374 {

377

378 if (prevfp == fp)

379 break;

380

381 prevfpmode = prevfp->mode;

384

389 continue;

394 continue;

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

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

398 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

402 }

403

405 have_names = true;

406 }

407

408 if (inParameterNames_list)

410

412 {

414

415 if (!isinput)

417 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

420

425

426

427

428

429

433 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),

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

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

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

452 have_defaults = true;

453 }

454 else

455 {

456 if (isinput && have_defaults)

458 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

461

462

463

464

465

466

469 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

472 }

473

474 i++;

475 }

476

477

479

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

481 {

484 if (outCount > 1)

485 *requiredResultType = RECORDOID;

486

487 }

488 else

489 {

490 *allParameterTypes = NULL;

491 *parameterModes = NULL;

492 }

493

494 if (have_names)

495 {

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

497 {

500 }

502 }

503 else

504 *parameterNames = NULL;

505}

506

507

508

509

510

511

512

513

514

515

516static bool

518 bool is_procedure,

520 DefElem **volatility_item,

523 DefElem **leakproof_item,

524 List **set_items,

529{

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

531 {

532 if (is_procedure)

533 goto procedure_error;

534 if (*volatility_item)

536

537 *volatility_item = defel;

538 }

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

540 {

541 if (is_procedure)

542 goto procedure_error;

543 if (*strict_item)

545

546 *strict_item = defel;

547 }

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

549 {

550 if (*security_item)

552

553 *security_item = defel;

554 }

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

556 {

557 if (is_procedure)

558 goto procedure_error;

559 if (*leakproof_item)

561

562 *leakproof_item = defel;

563 }

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

565 {

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

567 }

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

569 {

570 if (is_procedure)

571 goto procedure_error;

572 if (*cost_item)

574

575 *cost_item = defel;

576 }

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

578 {

579 if (is_procedure)

580 goto procedure_error;

581 if (*rows_item)

583

584 *rows_item = defel;

585 }

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

587 {

588 if (is_procedure)

589 goto procedure_error;

590 if (*support_item)

592

593 *support_item = defel;

594 }

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

596 {

597 if (is_procedure)

598 goto procedure_error;

599 if (*parallel_item)

601

602 *parallel_item = defel;

603 }

604 else

605 return false;

606

607

608 return true;

609

610procedure_error:

612 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

615 return false;

616}

617

618static char

620{

622

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

624 return PROVOLATILE_IMMUTABLE;

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

626 return PROVOLATILE_STABLE;

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

628 return PROVOLATILE_VOLATILE;

629 else

630 {

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

632 return 0;

633 }

634}

635

636static char

638{

640

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

642 return PROPARALLEL_SAFE;

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

644 return PROPARALLEL_UNSAFE;

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

646 return PROPARALLEL_RESTRICTED;

647 else

648 {

650 (errcode(ERRCODE_SYNTAX_ERROR),

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

652 return PROPARALLEL_UNSAFE;

653 }

654}

655

656

657

658

659

660

663{

665

666 foreach(l, set_items)

667 {

669

671 a = NULL;

672 else

673 {

675

676 if (valuestr)

678 else

680 }

681 }

682

683 return a;

684}

685

686static Oid

688{

690 Oid procOid;

691 Oid argList[1];

692

693

694

695

696

697 argList[0] = INTERNALOID;

698

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

702 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

705

708 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

711

712

713

714

715

716

719 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

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

721

722 return procOid;

723}

724

725

726

727

728

729

730static void

732 bool is_procedure,

735 char **language,

736 Node **transform,

737 bool *windowfunc_p,

738 char *volatility_p,

739 bool *strict_p,

740 bool *security_definer,

741 bool *leakproof_p,

745 Oid *prosupport,

746 char *parallel_p)

747{

750 DefElem *language_item = NULL;

751 DefElem *transform_item = NULL;

752 DefElem *windowfunc_item = NULL;

753 DefElem *volatility_item = NULL;

754 DefElem *strict_item = NULL;

755 DefElem *security_item = NULL;

756 DefElem *leakproof_item = NULL;

758 DefElem *cost_item = NULL;

759 DefElem *rows_item = NULL;

760 DefElem *support_item = NULL;

761 DefElem *parallel_item = NULL;

762

764 {

766

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

768 {

769 if (as_item)

771 as_item = defel;

772 }

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

774 {

775 if (language_item)

777 language_item = defel;

778 }

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

780 {

781 if (transform_item)

783 transform_item = defel;

784 }

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

786 {

787 if (windowfunc_item)

789 if (is_procedure)

791 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

794 windowfunc_item = defel;

795 }

797 is_procedure,

798 defel,

799 &volatility_item,

800 &strict_item,

801 &security_item,

802 &leakproof_item,

803 &set_items,

804 &cost_item,

805 &rows_item,

806 &support_item,

807 &parallel_item))

808 {

809

810 continue;

811 }

812 else

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

815 }

816

817 if (as_item)

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

819 if (language_item)

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

821 if (transform_item)

822 *transform = transform_item->arg;

823 if (windowfunc_item)

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

825 if (volatility_item)

827 if (strict_item)

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

829 if (security_item)

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

831 if (leakproof_item)

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

833 if (set_items)

835 if (cost_item)

836 {

838 if (*procost <= 0)

840 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

842 }

843 if (rows_item)

844 {

846 if (*prorows <= 0)

848 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

850 }

851 if (support_item)

853 if (parallel_item)

855}

856

857

858

859

860

861

862

863

864

865

866

867static void

870 List *parameterTypes, List *inParameterNames,

871 char **prosrc_str_p, char **probin_str_p,

872 Node **sql_body_out,

873 const char *queryString)

874{

875 if (!sql_body_in && !as)

877 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

879

880 if (sql_body_in && as)

882 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

884

885 if (sql_body_in && languageOid != SQLlanguageId)

887 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

889

890 *sql_body_out = NULL;

891

892 if (languageOid == ClanguageId)

893 {

894

895

896

897

898

899

900

901

905 else

906 {

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

910 }

911 }

912 else if (sql_body_in)

913 {

915

917

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

923 {

925

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

929 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

931

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

934 else

936 }

937

938 if (IsA(sql_body_in, List))

939 {

942 List *transformed_stmts = NIL;

943

944 foreach(lc, stmts)

945 {

949

955 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

958 transformed_stmts = lappend(transformed_stmts, q);

960 }

961

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

963 }

964 else

965 {

968

974 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

978

979 *sql_body_out = (Node *) q;

980 }

981

982

983

984

985

986

987

988

989 *prosrc_str_p = pstrdup("");

990

991

992 *probin_str_p = NULL;

993 }

994 else

995 {

996

998 *probin_str_p = NULL;

999

1002 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

1004 languageName)));

1005

1006 if (languageOid == INTERNALlanguageId)

1007 {

1008

1009

1010

1011

1012

1013

1014

1015

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

1018 }

1019 }

1020}

1021

1022

1023

1024

1025

1026

1029{

1030 char *probin_str;

1031 char *prosrc_str;

1032 Node *prosqlbody;

1033 Oid prorettype;

1034 bool returnsSet;

1035 char *language;

1036 Oid languageOid;

1037 Oid languageValidator;

1038 Node *transformDefElem = NULL;

1040 Oid namespaceId;

1043 List *parameterTypes_list = NIL;

1047 List *inParameterNames_list = NIL;

1048 List *parameterDefaults;

1049 Oid variadicArgType;

1050 List *trftypes_list = NIL;

1051 List *trfoids_list = NIL;

1053 Oid requiredResultType;

1054 bool isWindowFunc,

1055 isStrict,

1056 security,

1057 isLeakProof;

1058 char volatility;

1062 Oid prosupport;

1065 List *as_clause;

1066 char parallel;

1067

1068

1071

1072

1077

1078

1079 as_clause = NIL;

1080 language = NULL;

1081 isWindowFunc = false;

1082 isStrict = false;

1083 security = false;

1084 isLeakProof = false;

1085 volatility = PROVOLATILE_VOLATILE;

1086 proconfig = NULL;

1087 procost = -1;

1088 prorows = -1;

1090 parallel = PROPARALLEL_UNSAFE;

1091

1092

1094 stmt->is_procedure,

1095 stmt->options,

1096 &as_clause, &language, &transformDefElem,

1097 &isWindowFunc, &volatility,

1098 &isStrict, &security, &isLeakProof,

1099 &proconfig, &procost, &prorows,

1100 &prosupport, &parallel);

1101

1102 if (!language)

1103 {

1104 if (stmt->sql_body)

1105 language = "sql";

1106 else

1108 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

1110 }

1111

1112

1116 (errcode(ERRCODE_UNDEFINED_OBJECT),

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

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

1120

1122 languageOid = languageStruct->oid;

1123

1124 if (languageStruct->lanpltrusted)

1125 {

1126

1130 NameStr(languageStruct->lanname));

1131 }

1132 else

1133 {

1134

1137 NameStr(languageStruct->lanname));

1138 }

1139

1140 languageValidator = languageStruct->lanvalidator;

1141

1143

1144

1145

1146

1147

1148

1149 if (isLeakProof && superuser())

1151 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

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

1153

1154 if (transformDefElem)

1155 {

1157

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

1159 {

1163 Oid transformid;

1164

1165 typeid = elt ? elt : typeid;

1167 trftypes_list = lappend_oid(trftypes_list, typeid);

1168 trfoids_list = lappend_oid(trfoids_list, transformid);

1169 }

1170 }

1171

1172

1173

1174

1175

1177 stmt->parameters,

1178 languageOid,

1180 &parameterTypes,

1181 &parameterTypes_list,

1182 &allParameterTypes,

1183 &parameterModes,

1184 &parameterNames,

1185 &inParameterNames_list,

1186 &parameterDefaults,

1187 &variadicArgType,

1188 &requiredResultType);

1189

1190 if (stmt->is_procedure)

1191 {

1193 prorettype = requiredResultType ? requiredResultType : VOIDOID;

1194 returnsSet = false;

1195 }

1196 else if (stmt->returnType)

1197 {

1198

1200 &prorettype, &returnsSet);

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

1203 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

1206 }

1207 else if (OidIsValid(requiredResultType))

1208 {

1209

1210 prorettype = requiredResultType;

1211 returnsSet = false;

1212 }

1213 else

1214 {

1216 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

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

1218

1219 prorettype = VOIDOID;

1220 returnsSet = false;

1221 }

1222

1223 if (trftypes_list != NIL)

1224 {

1227 int i;

1228

1230 i = 0;

1231 foreach(lc, trftypes_list)

1234 }

1235 else

1236 {

1237

1238 trftypes = NULL;

1239 }

1240

1242 parameterTypes_list, inParameterNames_list,

1243 &prosrc_str, &probin_str, &prosqlbody,

1245

1246

1247

1248

1249

1250

1251 if (procost < 0)

1252 {

1253

1254 if (languageOid == INTERNALlanguageId ||

1255 languageOid == ClanguageId)

1256 procost = 1;

1257 else

1258 procost = 100;

1259 }

1260 if (prorows < 0)

1261 {

1262 if (returnsSet)

1263 prorows = 1000;

1264 else

1265 prorows = 0;

1266 }

1267 else if (!returnsSet)

1269 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1271

1272

1273

1274

1275

1277 namespaceId,

1278 stmt->replace,

1279 returnsSet,

1280 prorettype,

1282 languageOid,

1283 languageValidator,

1284 prosrc_str,

1285 probin_str,

1286 prosqlbody,

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

1288 security,

1289 isLeakProof,

1290 isStrict,

1291 volatility,

1292 parallel,

1293 parameterTypes,

1297 parameterDefaults,

1299 trfoids_list,

1301 prosupport,

1302 procost,

1303 prorows);

1304}

1305

1306

1307

1308

1309

1310

1311

1312void

1314{

1317 char prokind;

1318

1319

1320

1321

1323

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

1327

1329

1331

1333

1335

1337

1338

1339

1340

1341 if (prokind == PROKIND_AGGREGATE)

1342 {

1344

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

1348

1350

1352

1354 }

1355}

1356

1357

1358

1359

1360

1361

1364{

1366 Oid funcOid;

1368 bool is_procedure;

1371 DefElem *volatility_item = NULL;

1372 DefElem *strict_item = NULL;

1373 DefElem *security_def_item = NULL;

1374 DefElem *leakproof_item = NULL;

1376 DefElem *cost_item = NULL;

1377 DefElem *rows_item = NULL;

1378 DefElem *support_item = NULL;

1379 DefElem *parallel_item = NULL;

1381

1383

1385

1387

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

1391

1393

1394

1398

1399 if (procForm->prokind == PROKIND_AGGREGATE)

1401 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

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

1404

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

1406

1407

1408 foreach(l, stmt->actions)

1409 {

1411

1413 is_procedure,

1414 defel,

1415 &volatility_item,

1416 &strict_item,

1417 &security_def_item,

1418 &leakproof_item,

1419 &set_items,

1420 &cost_item,

1421 &rows_item,

1422 &support_item,

1423 &parallel_item) == false)

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

1425 }

1426

1427 if (volatility_item)

1429 if (strict_item)

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

1431 if (security_def_item)

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

1433 if (leakproof_item)

1434 {

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

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

1438 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

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

1440 }

1441 if (cost_item)

1442 {

1444 if (procForm->procost <= 0)

1446 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1448 }

1449 if (rows_item)

1450 {

1452 if (procForm->prorows <= 0)

1454 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1456 if (!procForm->proretset)

1458 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1460 }

1461 if (support_item)

1462 {

1463

1465

1466

1467 if (OidIsValid(procForm->prosupport))

1468 {

1470 ProcedureRelationId, procForm->prosupport,

1471 newsupport) != 1)

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

1474 }

1475 else

1476 {

1478

1479 referenced.classId = ProcedureRelationId;

1480 referenced.objectId = newsupport;

1483 }

1484

1485 procForm->prosupport = newsupport;

1486 }

1487 if (parallel_item)

1489 if (set_items)

1490 {

1492 bool isnull;

1494 Datum repl_val[Natts_pg_proc];

1495 bool repl_null[Natts_pg_proc];

1496 bool repl_repl[Natts_pg_proc];

1497

1498

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

1501

1502

1504

1505

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

1507 repl_repl[Anum_pg_proc_proconfig - 1] = true;

1508

1509 if (a == NULL)

1510 {

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

1512 repl_null[Anum_pg_proc_proconfig - 1] = true;

1513 }

1514 else

1515 {

1517 repl_null[Anum_pg_proc_proconfig - 1] = false;

1518 }

1519

1521 repl_val, repl_null, repl_repl);

1522 }

1523

1524

1525

1527

1529

1532

1533 return address;

1534}

1535

1536

1537

1538

1539

1542{

1543 Oid sourcetypeid;

1544 Oid targettypeid;

1545 char sourcetyptype;

1546 char targettyptype;

1547 Oid funcid;

1550 int nargs;

1551 char castcontext;

1552 char castmethod;

1556

1559 sourcetyptype = get_typtype(sourcetypeid);

1560 targettyptype = get_typtype(targettypeid);

1561

1562

1563 if (sourcetyptype == TYPTYPE_PSEUDO)

1565 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

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

1568

1569 if (targettyptype == TYPTYPE_PSEUDO)

1571 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

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

1574

1575

1579 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

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

1583

1587

1591

1592

1593 if (sourcetyptype == TYPTYPE_DOMAIN)

1595 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

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

1597

1598 else if (targettyptype == TYPTYPE_DOMAIN)

1600 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

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

1602

1603

1604 if (stmt->func != NULL)

1605 castmethod = COERCION_METHOD_FUNCTION;

1606 else if (stmt->inout)

1607 castmethod = COERCION_METHOD_INOUT;

1608 else

1609 castmethod = COERCION_METHOD_BINARY;

1610

1611 if (castmethod == COERCION_METHOD_FUNCTION)

1612 {

1614

1616

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

1620

1622 nargs = procstruct->pronargs;

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

1625 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1628 procstruct->proargtypes.values[0],

1629 &incastid))

1631 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

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

1635 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1637 "integer")));

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

1640 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1642 "boolean")));

1644 targettypeid,

1645 &outcastid))

1647 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1649

1650

1651

1652

1653

1654

1655#ifdef NOT_USED

1656 if (procstruct->provolatile == PROVOLATILE_VOLATILE)

1658 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1660#endif

1661 if (procstruct->prokind != PROKIND_FUNCTION)

1663 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1665 if (procstruct->proretset)

1667 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1669

1671 }

1672 else

1673 {

1675 nargs = 0;

1676 }

1677

1678 if (castmethod == COERCION_METHOD_BINARY)

1679 {

1682 bool typ1byval;

1683 bool typ2byval;

1684 char typ1align;

1685 char typ2align;

1686

1687

1688

1689

1690

1693 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

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

1695

1696

1697

1698

1699

1700

1701

1704 if (typ1len != typ2len ||

1705 typ1byval != typ2byval ||

1706 typ1align != typ2align)

1708 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1710

1711

1712

1713

1714

1715

1716

1717

1718

1719

1720

1721

1722

1723

1724

1725 if (sourcetyptype == TYPTYPE_COMPOSITE ||

1726 targettyptype == TYPTYPE_COMPOSITE)

1728 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1730

1734 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1736

1737 if (sourcetyptype == TYPTYPE_RANGE ||

1738 targettyptype == TYPTYPE_RANGE ||

1739 sourcetyptype == TYPTYPE_MULTIRANGE ||

1740 targettyptype == TYPTYPE_MULTIRANGE)

1742 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1744

1745 if (sourcetyptype == TYPTYPE_ENUM ||

1746 targettyptype == TYPTYPE_ENUM)

1748 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1750

1751

1752

1753

1754

1755

1756

1757

1758

1759

1760

1761

1762 if (sourcetyptype == TYPTYPE_DOMAIN ||

1763 targettyptype == TYPTYPE_DOMAIN)

1765 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1767 }

1768

1769

1770

1771

1772

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

1775 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1777

1778

1779 switch (stmt->context)

1780 {

1782 castcontext = COERCION_CODE_IMPLICIT;

1783 break;

1785 castcontext = COERCION_CODE_ASSIGNMENT;

1786 break;

1787

1789 castcontext = COERCION_CODE_EXPLICIT;

1790 break;

1791 default:

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

1793 castcontext = 0;

1794 break;

1795 }

1796

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

1799 return myself;

1800}

1801

1802

1803static void

1805{

1806 if (procstruct->provolatile == PROVOLATILE_VOLATILE)

1808 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1810 if (procstruct->prokind != PROKIND_FUNCTION)

1812 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1814 if (procstruct->proretset)

1816 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1818 if (procstruct->pronargs != 1)

1820 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

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

1824 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1826 "internal")));

1827}

1828

1829

1830

1831

1832

1835{

1836 Oid typeid;

1837 char typtype;

1838 Oid langid;

1839 Oid fromsqlfuncid;

1840 Oid tosqlfuncid;

1844 bool nulls[Natts_pg_transform] = {0};

1845 bool replaces[Natts_pg_transform] = {0};

1846 Oid transformid;

1851 referenced;

1853 bool is_replace;

1854

1855

1856

1857

1860

1861 if (typtype == TYPTYPE_PSEUDO)

1863 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

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

1866

1867 if (typtype == TYPTYPE_DOMAIN)

1869 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

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

1872

1875

1879

1880

1881

1882

1884

1888

1889

1890

1891

1892 if (stmt->fromsql)

1893 {

1895

1898

1902

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

1907 if (procstruct->prorettype != INTERNALOID)

1909 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1911 "internal")));

1914 }

1915 else

1917

1918 if (stmt->tosql)

1919 {

1921

1924

1928

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

1933 if (procstruct->prorettype != typeid)

1935 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

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

1939 }

1940 else

1942

1943

1944

1945

1950

1952

1957 {

1959

1960 if (stmt->replace)

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

1965 stmt->lang)));

1966

1967 replaces[Anum_pg_transform_trffromsql - 1] = true;

1968 replaces[Anum_pg_transform_trftosql - 1] = true;

1969

1972

1973 transformid = form->oid;

1975 is_replace = true;

1976 }

1977 else

1978 {

1980 Anum_pg_transform_oid);

1984 is_replace = false;

1985 }

1986

1987 if (is_replace)

1989

1991

1992

1994

1995

1998

1999

2002

2003

2005 {

2006 ObjectAddressSet(referenced, ProcedureRelationId, fromsqlfuncid);

2008 }

2010 {

2011 ObjectAddressSet(referenced, ProcedureRelationId, tosqlfuncid);

2013 }

2014

2017

2018

2020

2021

2023

2025

2027

2028 return myself;

2029}

2030

2031

2032

2033

2034

2035

2036

2037

2040{

2041 Oid oid;

2042

2043 oid = GetSysCacheOid2(TRFTYPELANG, Anum_pg_transform_oid,

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

2048 (errcode(ERRCODE_UNDEFINED_OBJECT),

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

2052 return oid;

2053}

2054

2055

2056

2057

2058

2059

2060

2061

2062void

2065{

2066

2072 (errcode(ERRCODE_DUPLICATE_FUNCTION),

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

2077}

2078

2079

2080

2081

2082

2083

2084

2085void

2087{

2090 DefElem *as_item = NULL;

2091 DefElem *language_item = NULL;

2092 char *language;

2093 Oid laninline;

2096

2097

2098 foreach(arg, stmt->args)

2099 {

2101

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

2103 {

2104 if (as_item)

2106 as_item = defel;

2107 }

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

2109 {

2110 if (language_item)

2112 language_item = defel;

2113 }

2114 else

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

2117 }

2118

2119 if (as_item)

2121 else

2123 (errcode(ERRCODE_SYNTAX_ERROR),

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

2125

2126

2127 if (language_item)

2128 language = strVal(language_item->arg);

2129 else

2130 language = "plpgsql";

2131

2132

2136 (errcode(ERRCODE_UNDEFINED_OBJECT),

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

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

2140

2142 codeblock->langOid = languageStruct->oid;

2143 codeblock->langIsTrusted = languageStruct->lanpltrusted;

2144 codeblock->atomic = atomic;

2145

2146 if (languageStruct->lanpltrusted)

2147 {

2148

2150

2155 NameStr(languageStruct->lanname));

2156 }

2157 else

2158 {

2159

2162 NameStr(languageStruct->lanname));

2163 }

2164

2165

2166 laninline = languageStruct->laninline;

2169 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

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

2172

2174

2175

2177}

2178

2179

2180

2181

2182

2183

2184

2185

2186

2187

2188

2189

2190

2191

2192

2193

2194

2195

2196

2197

2198

2199

2200

2201

2202

2203

2204

2205

2206

2207void

2209{

2213 int nargs;

2214 int i;

2223

2224 fexpr = stmt->funcexpr;

2227

2231

2232

2234 callcontext->atomic = atomic;

2235

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

2239

2240

2241

2242

2243

2244

2245

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

2247 callcontext->atomic = true;

2248

2249

2250

2251

2252

2253

2254

2256 callcontext->atomic = true;

2257

2259

2260

2264 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),

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

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

2269

2270

2275 (Node *) callcontext, NULL);

2276

2277

2278

2279

2280

2284

2285

2286

2287

2288

2289

2290

2291

2292 if (!atomic)

2294

2295 i = 0;

2296 foreach(lc, fexpr->args)

2297 {

2300 bool isnull;

2301

2303

2305

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

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

2308

2309 i++;

2310 }

2311

2312

2313 if (!atomic)

2315

2316

2320

2321

2322 if (fexpr->funcresulttype == VOIDOID)

2323 {

2324

2325 }

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

2327 {

2328

2330 Oid tupType;

2331 int32 tupTypmod;

2336

2337 if (fcinfo->isnull)

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

2339

2340

2341

2342

2343

2344

2345

2346

2347

2348

2349

2350

2351

2353

2358

2361

2365 rettupdata.t_data = td;

2366

2369

2371

2373 }

2374 else

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

2376 fexpr->funcresulttype);

2377

2379}

2380

2381

2382

2383

2386{

2390

2391 fexpr = stmt->funcexpr;

2392

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

2396

2398

2400

2401

2402

2403

2404

2405

2406

2407

2408

2409

2410

2411 if (tupdesc)

2412 {

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

2415 {

2418

2420 i + 1,

2423 -1,

2424 0);

2425 }

2426 }

2427

2428 return tupdesc;

2429}

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

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

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

void aclcheck_error_type(AclResult aclerr, Oid typeOid)

#define DatumGetArrayTypeP(X)

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

static Datum values[MAXATTR]

#define CStringGetTextDatum(s)

#define OidIsValid(objectId)

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

const char * GetCommandTagName(CommandTag commandTag)

List * defGetQualifiedName(DefElem *def)

void errorConflictingDefElem(DefElem *defel, ParseState *pstate)

double defGetNumeric(DefElem *def)

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

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

ObjectAddresses * new_object_addresses(void)

void free_object_addresses(ObjectAddresses *addrs)

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

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

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

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

void end_tup_output(TupOutputState *tstate)

const TupleTableSlotOps TTSOpsHeapTuple

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

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

ExprContext * CreateExprContext(EState *estate)

void FreeExecutorState(EState *estate)

EState * CreateExecutorState(void)

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

bool extension_file_exists(const char *extensionName)

#define palloc0_object(type)

void fmgr_info(Oid functionId, FmgrInfo *finfo)

#define OidFunctionCall1(functionId, arg1)

#define DatumGetHeapTupleHeader(X)

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

#define LOCAL_FCINFO(name, nargs)

#define FunctionCallInvoke(fcinfo)

#define fmgr_info_set_expr(expr, finfo)

char * format_type_be(Oid type_oid)

TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple)

void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest)

ObjectAddress CreateCast(CreateCastStmt *stmt)

static void compute_return_type(TypeName *returnType, Oid languageOid, Oid *prorettype_p, bool *returnsSet_p)

static Oid interpret_func_support(DefElem *defel)

static void compute_function_attributes(ParseState *pstate, bool is_procedure, List *options, List **as, char **language, Node **transform, bool *windowfunc_p, char *volatility_p, bool *strict_p, bool *security_definer, bool *leakproof_p, ArrayType **proconfig, float4 *procost, float4 *prorows, Oid *prosupport, char *parallel_p)

void interpret_function_parameter_list(ParseState *pstate, List *parameters, Oid languageOid, ObjectType objtype, oidvector **parameterTypes, List **parameterTypes_list, ArrayType **allParameterTypes, ArrayType **parameterModes, ArrayType **parameterNames, List **inParameterNames_list, List **parameterDefaults, Oid *variadicArgType, Oid *requiredResultType)

static bool compute_common_attribute(ParseState *pstate, bool is_procedure, DefElem *defel, DefElem **volatility_item, DefElem **strict_item, DefElem **security_item, DefElem **leakproof_item, List **set_items, DefElem **cost_item, DefElem **rows_item, DefElem **support_item, DefElem **parallel_item)

static char interpret_func_volatility(DefElem *defel)

ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)

void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)

ObjectAddress AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)

TupleDesc CallStmtResultDesc(CallStmt *stmt)

static void interpret_AS_clause(Oid languageOid, const char *languageName, char *funcname, List *as, Node *sql_body_in, List *parameterTypes, List *inParameterNames, char **prosrc_str_p, char **probin_str_p, Node **sql_body_out, const char *queryString)

Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)

void ExecuteDoStmt(ParseState *pstate, DoStmt *stmt, bool atomic)

static void check_transform_function(Form_pg_proc procstruct)

ObjectAddress CreateTransform(CreateTransformStmt *stmt)

static ArrayType * update_proconfig_value(ArrayType *a, List *set_items)

void RemoveFunctionById(Oid funcOid)

static char interpret_func_parallel(DefElem *defel)

void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)

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

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

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

char * ExtractSetVariableArgs(VariableSetStmt *stmt)

Assert(PointerIsAligned(start, uint64))

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

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

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

void heap_freetuple(HeapTuple htup)

#define HeapTupleIsValid(tuple)

static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)

static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)

static void * GETSTRUCT(const HeapTupleData *tuple)

static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)

void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)

void CatalogTupleInsert(Relation heapRel, HeapTuple tup)

void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)

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

static void ItemPointerSetInvalid(ItemPointerData *pointer)

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

List * lappend_oid(List *list, Oid datum)

Oid get_element_type(Oid typid)

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

char * get_language_name(Oid langoid, bool missing_ok)

char * get_func_name(Oid funcid)

char get_typtype(Oid typid)

Oid get_base_element_type(Oid typid)

char * get_namespace_name(Oid nspid)

Oid get_func_rettype(Oid funcid)

char * pstrdup(const char *in)

void * palloc0(Size size)

char * NameListToString(const List *names)

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

Oid exprType(const Node *expr)

#define IsA(nodeptr, _type_)

#define castNode(_type_, nodeptr)

#define InvokeObjectPostCreateHook(classId, objectId, subId)

#define InvokeObjectPostAlterHook(classId, objectId, subId)

#define InvokeFunctionExecuteHook(objectId)

#define ObjectAddressSet(addr, class_id, object_id)

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

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

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

void assign_expr_collations(ParseState *pstate, Node *expr)

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

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

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

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

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

void free_parsestate(ParseState *pstate)

int parser_errposition(ParseState *pstate, int location)

ParseState * make_parsestate(ParseState *parentParseState)

@ EXPR_KIND_FUNCTION_DEFAULT

char * TypeNameToString(const TypeName *typeName)

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

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

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

FormData_pg_attribute * Form_pg_attribute

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

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

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

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

void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)

FormData_pg_language * Form_pg_language

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define linitial_node(type, l)

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

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

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

FormData_pg_proc * Form_pg_proc

FormData_pg_transform * Form_pg_transform

ObjectAddress TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)

FormData_pg_type * Form_pg_type

void pgstat_drop_function(Oid proid)

void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)

void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)

static Datum PointerGetDatum(const void *X)

static Datum ObjectIdGetDatum(Oid X)

static Datum CStringGetDatum(const char *X)

static Datum CharGetDatum(char X)

void EnsurePortalSnapshotExists(void)

Oid get_language_oid(const char *langname, bool missing_ok)

#define RelationGetDescr(relation)

Snapshot GetTransactionSnapshot(void)

void PushActiveSnapshot(Snapshot snapshot)

void PopActiveSnapshot(void)

#define ERRCODE_DUPLICATE_OBJECT

ParamListInfo es_param_list_info

FunctionParameterMode mode

const char * p_sourcetext

bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)

Oid values[FLEXIBLE_ARRAY_MEMBER]

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)

HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)

#define SearchSysCacheCopy1(cacheId, key1)

#define SearchSysCacheExists3(cacheId, key1, key2, key3)

#define GetSysCacheOid2(cacheId, oidcol, key1, key2)

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)

#define ReleaseTupleDesc(tupdesc)

static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)

TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)

CommandTag CreateCommandTag(Node *parsetree)

String * makeString(char *str)

bool contain_var_clause(Node *node)

void CommandCounterIncrement(void)