PostgreSQL Source Code: src/backend/executor/spi.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

36

37

38

39

40

41

42

43

47

52

54{

58

61

63

65

68 bool fire_triggers);

69

72

75

77

81

84

90

91

92

93

94int

96{

98}

99

100int

102{

103 int newdepth;

104

105

107 {

109 elog(ERROR, "SPI stack corrupted");

110 newdepth = 16;

115 }

116 else

117 {

119 elog(ERROR, "SPI stack corrupted");

121 {

127 }

128 }

129

130

133

148

149

150

151

152

153

154

155

156

157

158

159

160

161

163 "SPI Proc",

166 "SPI Exec",

168

170

171

172

173

174

178

180}

181

182int

184{

185 int res;

186

187 res = _SPI_begin_call(false);

188 if (res < 0)

189 return res;

190

191

193

194

199

200

201

202

203

207

208

212 else

214

216}

217

218

219

220

221

222void

224{

225}

226

227static void

229{

232

233

234

235

236

237

238

241 (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION),

242 errmsg("invalid transaction termination")));

243

244

245

246

247

248

249

250

251

252

253

256 (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION),

257 errmsg("cannot commit while a subtransaction is active")));

258

259 if (chain)

261

262

264 {

265

267

268

269

270

271

272

274

275

277

278

280

281

283 if (chain)

285

287

289 }

291 {

293

294

298

299

300

301

302

304

305

307 if (chain)

309

311

313

314

316 }

318}

319

320void

322{

324}

325

326void

328{

330}

331

332static void

334{

337

338

341 (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION),

342 errmsg("invalid transaction termination")));

343

344

347 (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION),

348 errmsg("cannot roll back while a subtransaction is active")));

349

350 if (chain)

352

353

355 {

356

358

359

360

361

362

363

364

366

367

369

370

372

373

375 if (chain)

377

379

381 }

383 {

385

386

390

391

392

393

394

395

397

398

400 if (chain)

402

404

406

407

409 }

411}

412

413void

415{

417}

418

419void

421{

423}

424

425

426

427

428void

430{

431 bool found = false;

432

433

434

435

436

438 {

440

442 break;

443

444 found = true;

445

446

447

448

449

450

451

452

453

454

455

456

460

464 else

466 }

467

468

469 if (found && isCommit)

471 (errcode(ERRCODE_WARNING),

472 errmsg("transaction left non-empty SPI stack"),

473 errhint("Check for missing \"SPI_finish\" calls.")));

474}

475

476

477

478

479

480

481

482void

484{

485 bool found = false;

486

488 {

490

491 if (connection->connectSubid != mySubid)

492 break;

493

495 break;

496

497 found = true;

498

499

500

501

503 {

506 }

508 {

511 }

512

513

514

515

516

517

521

525 else

527 }

528

529 if (found && isCommit)

531 (errcode(ERRCODE_WARNING),

532 errmsg("subtransaction left non-empty SPI stack"),

533 errhint("Check for missing \"SPI_finish\" calls.")));

534

535

536

537

538

540 {

542

543

544

545

546

548 {

551 }

552

553

555 {

557

559 if (tuptable->subid >= mySubid)

560 {

561

562

563

564

565

566

573 }

574 }

575 }

576}

577

578

579

580

581bool

583{

585 return false;

586

588 return false;

590 return false;

591 return true;

592}

593

594

595

596int

597SPI_execute(const char *src, bool read_only, long tcount)

598{

601 int res;

602

603 if (src == NULL || tcount < 0)

605

607 if (res < 0)

608 return res;

609

614

616

618 options.read_only = read_only;

620

623 true);

624

626 return res;

627}

628

629

630int

632{

634}

635

636

637int

640{

641 int res;

643

644 if (src == NULL || options == NULL)

646

648 if (res < 0)

649 return res;

650

656 {

657 plan.parserSetup = options->params->parserSetup;

658 plan.parserSetupArg = options->params->parserSetupArg;

659 }

660

662

665 true);

666

668 return res;

669}

670

671

672int

674 bool read_only, long tcount)

675{

677 int res;

678

681

682 if (plan->nargs > 0 && Values == NULL)

684

686 if (res < 0)

687 return res;

688

692 options.read_only = read_only;

694

697 true);

698

700 return res;

701}

702

703

704int

706{

708}

709

710

711int

714{

715 int res;

716

719

721 if (res < 0)

722 return res;

723

726 true);

727

729 return res;

730}

731

732

733int

735 bool read_only, long tcount)

736{

738 int res;

739

742

744 if (res < 0)

745 return res;

746

749 options.read_only = read_only;

751

754 true);

755

757 return res;

758}

759

760

761

762

763

764

765

766

767

768

769

770

771

772

773int

777 bool read_only, bool fire_triggers, long tcount)

778{

780 int res;

781

784

785 if (plan->nargs > 0 && Values == NULL)

787

789 if (res < 0)

790 return res;

791

795 options.read_only = read_only;

797

799 snapshot, crosscheck_snapshot,

800 fire_triggers);

801

803 return res;

804}

805

806

807

808

809

810

811

812int

814 int nargs, Oid *argtypes,

816 bool read_only, long tcount)

817{

818 int res;

822

823 if (src == NULL || nargs < 0 || tcount < 0)

825

826 if (nargs > 0 && (argtypes == NULL || Values == NULL))

828

830 if (res < 0)

831 return res;

832

837 plan.nargs = nargs;

838 plan.argtypes = argtypes;

839 plan.parserSetup = NULL;

840 plan.parserSetupArg = NULL;

841

844

846

848 options.params = paramLI;

849 options.read_only = read_only;

851

854 true);

855

857 return res;

858}

859

862{

864}

865

868 int cursorOptions)

869{

872

873 if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))

874 {

876 return NULL;

877 }

878

881 return NULL;

882

886 plan.cursor_options = cursorOptions;

887 plan.nargs = nargs;

888 plan.argtypes = argtypes;

889 plan.parserSetup = NULL;

890 plan.parserSetupArg = NULL;

891

893

894

896

898

899 return result;

900}

901

905{

908

909 if (src == NULL || options == NULL)

910 {

912 return NULL;

913 }

914

917 return NULL;

918

922 plan.cursor_options = options->cursorOptions;

923 plan.nargs = 0;

924 plan.argtypes = NULL;

926 plan.parserSetupArg = options->parserSetupArg;

927

929

930

932

934

935 return result;

936}

937

941 void *parserSetupArg,

942 int cursorOptions)

943{

946

947 if (src == NULL)

948 {

950 return NULL;

951 }

952

955 return NULL;

956

960 plan.cursor_options = cursorOptions;

961 plan.nargs = 0;

962 plan.argtypes = NULL;

963 plan.parserSetup = parserSetup;

964 plan.parserSetupArg = parserSetupArg;

965

967

968

970

972

973 return result;

974}

975

976int

978{

980

982 plan->saved || plan->oneshot)

984

985

986

987

988

989

990 plan->saved = true;

992

993 foreach(lc, plan->plancache_list)

994 {

996

998 }

999

1000 return 0;

1001}

1002

1005{

1007

1009 {

1011 return NULL;

1012 }

1013

1016 return NULL;

1017

1019

1021

1022 return newplan;

1023}

1024

1025int

1027{

1029

1032

1033

1034 foreach(lc, plan->plancache_list)

1035 {

1037

1039 }

1040

1041

1043

1044 return 0;

1045}

1046

1049{

1052

1053 if (tuple == NULL)

1054 {

1056 return NULL;

1057 }

1058

1060 {

1062 return NULL;

1063 }

1064

1066

1068

1070

1071 return ctuple;

1072}

1073

1076{

1079

1080 if (tuple == NULL || tupdesc == NULL)

1081 {

1083 return NULL;

1084 }

1085

1087 {

1089 return NULL;

1090 }

1091

1092

1093 if (tupdesc->tdtypeid == RECORDOID &&

1096

1098

1100

1102

1103 return dtup;

1104}

1105

1109{

1112 int numberOfAttributes;

1114 bool *n;

1115 int i;

1116

1117 if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)

1118 {

1120 return NULL;

1121 }

1122

1124 {

1126 return NULL;

1127 }

1128

1130

1132

1133 numberOfAttributes = rel->rd_att->natts;

1135 n = (bool *) palloc(numberOfAttributes * sizeof(bool));

1136

1137

1139

1140

1141 for (i = 0; i < natts; i++)

1142 {

1143 if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)

1144 break;

1145 v[attnum[i] - 1] = Values[i];

1147 }

1148

1149 if (i == natts)

1150 {

1152

1153

1154

1155

1156

1160 }

1161 else

1162 {

1163 mtuple = NULL;

1165 }

1166

1169

1171

1172 return mtuple;

1173}

1174

1175int

1177{

1178 int res;

1180

1181 for (res = 0; res < tupdesc->natts; res++)

1182 {

1184

1185 if (namestrcmp(&attr->attname, fname) == 0 &&

1186 !attr->attisdropped)

1187 return res + 1;

1188 }

1189

1191 if (sysatt != NULL)

1192 return sysatt->attnum;

1193

1194

1196}

1197

1198char *

1200{

1202

1204

1205 if (fnumber > tupdesc->natts || fnumber == 0 ||

1207 {

1209 return NULL;

1210 }

1211

1212 if (fnumber > 0)

1214 else

1216

1218}

1219

1220char *

1222{

1224 bool isnull;

1225 Oid typoid,

1226 foutoid;

1227 bool typisvarlena;

1228

1230

1231 if (fnumber > tupdesc->natts || fnumber == 0 ||

1233 {

1235 return NULL;

1236 }

1237

1239 if (isnull)

1240 return NULL;

1241

1242 if (fnumber > 0)

1243 typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;

1244 else

1246

1248

1250}

1251

1254{

1256

1257 if (fnumber > tupdesc->natts || fnumber == 0 ||

1259 {

1261 *isnull = true;

1262 return (Datum) NULL;

1263 }

1264

1265 return heap_getattr(tuple, fnumber, tupdesc, isnull);

1266}

1267

1268char *

1270{

1271 Oid typoid;

1273 char *result;

1274

1276

1277 if (fnumber > tupdesc->natts || fnumber == 0 ||

1279 {

1281 return NULL;

1282 }

1283

1284 if (fnumber > 0)

1285 typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;

1286 else

1288

1290

1292 {

1294 return NULL;

1295 }

1296

1299 return result;

1300}

1301

1302

1303

1304

1305

1306

1307

1310{

1312

1313 if (fnumber > tupdesc->natts || fnumber == 0 ||

1315 {

1318 }

1319

1320 if (fnumber > 0)

1321 return TupleDescAttr(tupdesc, fnumber - 1)->atttypid;

1322 else

1324}

1325

1326char *

1328{

1330}

1331

1332char *

1334{

1336}

1337

1338void *

1340{

1342 elog(ERROR, "SPI_palloc called while not connected to SPI");

1343

1345}

1346

1347void *

1349{

1350

1351 return repalloc(pointer, size);

1352}

1353

1354void

1356{

1357

1359}

1360

1363{

1366

1368 elog(ERROR, "SPI_datumTransfer called while not connected to SPI");

1369

1371

1373

1375

1376 return result;

1377}

1378

1379void

1381{

1382

1384}

1385

1386void

1388{

1389 bool found = false;

1390

1391

1392 if (tuptable == NULL)

1393 return;

1394

1395

1396

1397

1399 {

1401

1402

1404 {

1406

1408 if (tt == tuptable)

1409 {

1411 found = true;

1412 break;

1413 }

1414 }

1415 }

1416

1417

1418

1419

1420

1421

1422

1423 if (!found)

1424 {

1425 elog(WARNING, "attempt to delete invalid SPITupleTable %p", tuptable);

1426 return;

1427 }

1428

1429

1434

1435

1437}

1438

1439

1440

1441

1442

1443

1444

1448 bool read_only)

1449{

1452

1453

1456

1458

1459

1460 if (paramLI)

1462

1463 return portal;

1464}

1465

1466

1467

1468

1469

1470

1471

1474 const char *src,

1475 int nargs, Oid *argtypes,

1477 bool read_only, int cursorOptions)

1478{

1482

1483 if (src == NULL || nargs < 0)

1484 elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");

1485

1486 if (nargs > 0 && (argtypes == NULL || Values == NULL))

1487 elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");

1488

1491 elog(ERROR, "SPI_cursor_open_with_args called while not connected");

1492

1496 plan.cursor_options = cursorOptions;

1497 plan.nargs = nargs;

1498 plan.argtypes = argtypes;

1499 plan.parserSetup = NULL;

1500 plan.parserSetupArg = NULL;

1501

1502

1505

1507

1508

1509

1511

1512

1514

1515 return result;

1516}

1517

1518

1519

1520

1521

1522

1523

1524

1528{

1530}

1531

1532

1535 const char *src,

1537{

1540

1541 if (src == NULL || options == NULL)

1542 elog(ERROR, "SPI_cursor_parse_open called with invalid arguments");

1543

1546 elog(ERROR, "SPI_cursor_parse_open called while not connected");

1547

1551 plan.cursor_options = options->cursorOptions;

1553 {

1554 plan.parserSetup = options->params->parserSetup;

1555 plan.parserSetupArg = options->params->parserSetupArg;

1556 }

1557

1559

1560

1561

1564

1565

1567

1568 return result;

1569}

1570

1571

1572

1573

1574

1575

1576

1580{

1583 List *stmt_list;

1584 char *query_string;

1590

1591

1592

1593

1594

1596 {

1597

1598 const char *cmdtag;

1599

1602 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),

1603 errmsg("cannot open multi-query plan as cursor")));

1605

1606 if (plansource->commandTag == CMDTAG_SELECT)

1607 cmdtag = "SELECT INTO";

1608 else

1611 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),

1612

1613 errmsg("cannot open %s query as cursor", cmdtag)));

1614 }

1615

1618

1619

1621 elog(ERROR, "SPI_cursor_open called while not connected");

1622

1623

1628

1629

1630 if (name == NULL || name[0] == '\0')

1631 {

1632

1634 }

1635 else

1636 {

1637

1639 }

1640

1641

1644

1645

1646

1647

1648

1650 spicallbackarg.mode = plan->parse_mode;

1652 spierrcontext.arg = &spicallbackarg;

1655

1656

1657

1658

1659

1660

1661

1662

1665

1666 if (plan->saved)

1667 {

1668

1669

1670

1671

1672

1673

1678 cplan = NULL;

1679 }

1680

1681

1682

1683

1685 NULL,

1686 query_string,

1688 stmt_list,

1689 cplan,

1690 plansource);

1691

1692

1693

1694

1695

1698 {

1704 else

1706 }

1707

1708

1709

1710

1711

1712

1714 {

1719 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

1720 errmsg("DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported"),

1721 errdetail("Scrollable cursors must be READ ONLY.")));

1722 }

1723

1724

1726

1727

1728

1729

1730

1731

1732

1733

1734 if (read_only)

1735 {

1737

1738 foreach(lc, stmt_list)

1739 {

1741

1744 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

1745

1746 errmsg("%s is not allowed in a non-volatile function",

1748 }

1749 }

1750

1751

1752 if (read_only)

1754 else

1755 {

1758 }

1759

1760

1761

1762

1763

1764

1765 if (paramLI)

1766 {

1770 }

1771

1772

1773

1774

1775 PortalStart(portal, paramLI, 0, snapshot);

1776

1778

1779

1781

1782

1784

1785

1786 return portal;

1787}

1788

1789

1790

1791

1792

1793

1794

1797{

1799}

1800

1801

1802

1803

1804

1805

1806

1807void

1809{

1813

1814}

1815

1816

1817

1818

1819

1820

1821

1822void

1824{

1828}

1829

1830

1831

1832

1833

1834

1835

1836void

1838{

1840 direction, count,

1842

1843}

1844

1845

1846

1847

1848

1849

1850

1851void

1853{

1855}

1856

1857

1858

1859

1860

1861

1862

1863void

1865{

1867 elog(ERROR, "invalid portal in SPI cursor operation");

1868

1870}

1871

1872

1873

1874

1875

1878{

1880 argIndex < 0 || argIndex >= plan->nargs)

1881 {

1884 }

1885 return plan->argtypes[argIndex];

1886}

1887

1888

1889

1890

1891int

1893{

1895 {

1897 return -1;

1898 }

1899 return plan->nargs;

1900}

1901

1902

1903

1904

1905

1906

1907

1908

1909

1910

1911bool

1913{

1915

1917 {

1919 return false;

1920 }

1921

1923 {

1925 return false;

1926 }

1928

1929

1930

1931

1932

1933

1935

1936

1938 return true;

1939

1940 return false;

1941}

1942

1943

1944

1945

1946

1947

1948

1949bool

1951{

1953

1955

1956 foreach(lc, plan->plancache_list)

1957 {

1959

1961 return false;

1962 }

1963 return true;

1964}

1965

1966

1967

1968

1969

1970

1971

1972

1973const char *

1975{

1976 static char buf[64];

1977

1978 switch (code)

1979 {

1981 return "SPI_ERROR_CONNECT";

1983 return "SPI_ERROR_COPY";

1985 return "SPI_ERROR_OPUNKNOWN";

1987 return "SPI_ERROR_UNCONNECTED";

1989 return "SPI_ERROR_ARGUMENT";

1991 return "SPI_ERROR_PARAM";

1993 return "SPI_ERROR_TRANSACTION";

1995 return "SPI_ERROR_NOATTRIBUTE";

1997 return "SPI_ERROR_NOOUTFUNC";

1999 return "SPI_ERROR_TYPUNKNOWN";

2001 return "SPI_ERROR_REL_DUPLICATE";

2003 return "SPI_ERROR_REL_NOT_FOUND";

2005 return "SPI_OK_CONNECT";

2007 return "SPI_OK_FINISH";

2009 return "SPI_OK_FETCH";

2011 return "SPI_OK_UTILITY";

2013 return "SPI_OK_SELECT";

2015 return "SPI_OK_SELINTO";

2017 return "SPI_OK_INSERT";

2019 return "SPI_OK_DELETE";

2021 return "SPI_OK_UPDATE";

2023 return "SPI_OK_CURSOR";

2025 return "SPI_OK_INSERT_RETURNING";

2027 return "SPI_OK_DELETE_RETURNING";

2029 return "SPI_OK_UPDATE_RETURNING";

2031 return "SPI_OK_REWRITTEN";

2033 return "SPI_OK_REL_REGISTER";

2035 return "SPI_OK_REL_UNREGISTER";

2037 return "SPI_OK_TD_REGISTER";

2039 return "SPI_OK_MERGE";

2041 return "SPI_OK_MERGE_RETURNING";

2042 }

2043

2044 sprintf(buf, "Unrecognized SPI code %d", code);

2045 return buf;

2046}

2047

2048

2049

2050

2051

2052

2053

2054

2055

2056

2057

2060{

2062 return plan->plancache_list;

2063}

2064

2065

2066

2067

2068

2069

2070

2071

2072

2073

2074

2075

2076

2079{

2084

2086

2087

2088 if (plan->oneshot)

2089 return NULL;

2090

2091

2093 return NULL;

2095

2096

2098 spicallbackarg.mode = plan->parse_mode;

2100 spierrcontext.arg = &spicallbackarg;

2103

2104

2109

2110

2112

2113 return cplan;

2114}

2115

2116

2117

2118

2119

2120

2121

2122

2123

2124void

2126{

2130

2132 elog(ERROR, "spi_dest_startup called while not connected to SPI");

2133

2135 elog(ERROR, "improper call to spi_dest_startup");

2136

2137

2138

2139 oldcxt = _SPI_procmem();

2140

2142 "SPI TupTable",

2145

2148 tuptable->tuptabcxt = tuptabcxt;

2150

2151

2152

2153

2154

2155

2157

2158

2159 tuptable->alloced = 128;

2163

2165}

2166

2167

2168

2169

2170

2171

2172bool

2174{

2177

2179 elog(ERROR, "spi_printtup called while not connected to SPI");

2180

2182 if (tuptable == NULL)

2183 elog(ERROR, "improper call to spi_printtup");

2184

2186

2188 {

2189

2191

2193 newalloced * sizeof(HeapTuple));

2194 tuptable->alloced = newalloced;

2195 }

2196

2199

2201

2202 return true;

2203}

2204

2205

2206

2207

2208

2209

2210

2211

2212

2213

2214

2215

2216

2217

2218

2219

2220

2221

2222static void

2224{

2225 List *raw_parsetree_list;

2226 List *plancache_list;

2230

2231

2232

2233

2234 spicallbackarg.query = src;

2235 spicallbackarg.mode = plan->parse_mode;

2237 spierrcontext.arg = &spicallbackarg;

2240

2241

2242

2243

2244 raw_parsetree_list = raw_parser(src, plan->parse_mode);

2245

2246

2247

2248

2249

2250 plancache_list = NIL;

2251

2252 foreach(list_item, raw_parsetree_list)

2253 {

2255 List *stmt_list;

2257

2258

2259

2260

2261

2263 src,

2265

2266

2267

2268

2269

2270 if (plan->parserSetup != NULL)

2271 {

2274 src,

2275 plan->parserSetup,

2276 plan->parserSetupArg,

2278 }

2279 else

2280 {

2282 src,

2283 plan->argtypes,

2284 plan->nargs,

2286 }

2287

2288

2290 stmt_list,

2291 NULL,

2292 plan->argtypes,

2293 plan->nargs,

2294 plan->parserSetup,

2295 plan->parserSetupArg,

2296 plan->cursor_options,

2297 false);

2298

2299 plancache_list = lappend(plancache_list, plansource);

2300 }

2301

2302 plan->plancache_list = plancache_list;

2303 plan->oneshot = false;

2304

2305

2306

2307

2309}

2310

2311

2312

2313

2314

2315

2316

2317

2318

2319

2320

2321

2322

2323

2324

2325

2326

2327

2328

2329

2330static void

2332{

2333 List *raw_parsetree_list;

2334 List *plancache_list;

2338

2339

2340

2341

2342 spicallbackarg.query = src;

2343 spicallbackarg.mode = plan->parse_mode;

2345 spierrcontext.arg = &spicallbackarg;

2348

2349

2350

2351

2352 raw_parsetree_list = raw_parser(src, plan->parse_mode);

2353

2354

2355

2356

2357 plancache_list = NIL;

2358

2359 foreach(list_item, raw_parsetree_list)

2360 {

2363

2365 src,

2367

2368 plancache_list = lappend(plancache_list, plansource);

2369 }

2370

2371 plan->plancache_list = plancache_list;

2372 plan->oneshot = true;

2373

2374

2375

2376

2378}

2379

2380

2381

2382

2383

2384

2385

2386

2387

2388

2389

2390

2391

2392

2393

2394

2395

2396

2397

2398

2399

2400static int

2403 bool fire_triggers)

2404{

2405 int my_res = 0;

2406 uint64 my_processed = 0;

2408 int res = 0;

2409 bool allow_nonatomic;

2410 bool pushed_active_snap = false;

2416

2417

2418

2419

2420

2421

2422

2423 allow_nonatomic = options->allow_nonatomic &&

2425

2426

2427

2428

2429 spicallbackarg.query = NULL;

2430 spicallbackarg.mode = plan->parse_mode;

2432 spierrcontext.arg = &spicallbackarg;

2435

2436

2437

2438

2439

2440

2441

2442

2443

2444

2445

2446

2447

2448

2449

2450

2451

2452

2453

2454

2455

2456

2457

2458

2459

2460

2461

2462

2464 {

2465

2468 {

2470 pushed_active_snap = true;

2471 }

2472 else

2473 {

2474

2476 pushed_active_snap = true;

2477 }

2478 }

2479

2480

2481

2482

2483

2484 if (plan->saved)

2485 plan_owner = NULL;

2486 else if (plan_owner == NULL)

2488

2489

2490

2491

2492

2493

2494

2495 if (options->must_return_tuples && plan->plancache_list == NIL)

2497 (errcode(ERRCODE_SYNTAX_ERROR),

2498 errmsg("empty query does not return tuples")));

2499

2500 foreach(lc1, plan->plancache_list)

2501 {

2503 List *stmt_list;

2505 int query_index = 0;

2506

2508

2509

2510

2511

2512 if (plan->oneshot)

2513 {

2516 List *querytree_list;

2517

2518

2519

2520

2521

2522 if (parsetree == NULL)

2523 querytree_list = NIL;

2524 else if (plan->parserSetup != NULL)

2525 {

2528 src,

2529 plan->parserSetup,

2530 plan->parserSetupArg,

2532 }

2533 else

2534 {

2536 src,

2537 plan->argtypes,

2538 plan->nargs,

2540 }

2541

2542

2544 querytree_list,

2545 NULL,

2546 plan->argtypes,

2547 plan->nargs,

2548 plan->parserSetup,

2549 plan->parserSetupArg,

2550 plan->cursor_options,

2551 false);

2552 }

2553

2554

2555

2556

2557

2558

2559

2561 {

2562

2563 const char *cmdtag;

2564

2565

2566 if (plansource->commandTag == CMDTAG_SELECT)

2567 cmdtag = "SELECT INTO";

2568 else

2571 (errcode(ERRCODE_SYNTAX_ERROR),

2572

2573 errmsg("%s query does not return tuples", cmdtag)));

2574 }

2575

2576

2577

2578

2579

2582

2584

2585

2586

2587

2588

2593 stmt_list)))))

2594 {

2595

2596

2597

2598

2599

2600

2601

2602

2603

2605

2606

2607

2608

2609

2610

2611

2612 if (options->read_only && !allow_nonatomic)

2613 {

2614 if (pushed_active_snap)

2617 pushed_active_snap = true;

2618 }

2619 }

2620

2621 foreach(lc2, stmt_list)

2622 {

2624 bool canSetTag = stmt->canSetTag;

2626

2627

2628

2629

2630

2631

2632

2635

2636

2637 if (stmt->utilityStmt)

2638 {

2640 {

2642

2644 {

2646 goto fail;

2647 }

2648 }

2650 {

2652 goto fail;

2653 }

2654 }

2655

2658 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

2659

2660 errmsg("%s is not allowed in a non-volatile function",

2662

2663

2664

2665

2666

2667

2668 if (options->read_only && pushed_active_snap)

2669 {

2672 }

2673

2674

2675

2676

2677

2678 if (!canSetTag)

2682 else

2684

2685 if (stmt->utilityStmt == NULL)

2686 {

2689

2692 else

2694

2696 cplan,

2698 snap, crosscheck_snapshot,

2702 0);

2703

2704 res = _SPI_pquery(qdesc, fire_triggers, canSetTag ? options->tcount : 0,

2705 plansource, query_index);

2707 }

2708 else

2709 {

2712

2713

2714

2715

2716

2717 if (allow_nonatomic)

2719 else

2721

2725 true,

2726 context,

2730 &qc);

2731

2732

2735

2737

2738

2739

2740

2741

2743 {

2745

2748 else

2749 {

2750

2751

2752

2753

2757 }

2758

2759

2760

2761

2762

2765 }

2767 {

2770 }

2771 }

2772

2773

2774

2775

2776

2777

2778 if (canSetTag)

2779 {

2783 my_res = res;

2784 }

2785 else

2786 {

2789 }

2790

2791

2792

2793

2794

2795

2796

2797 if (res < 0)

2798 {

2799 my_res = res;

2800 goto fail;

2801 }

2802

2803 query_index++;

2804 }

2805

2806

2808 cplan = NULL;

2809

2810

2811

2812

2813

2814

2815 if (options->read_only)

2817 }

2818

2819fail:

2820

2821

2822 if (pushed_active_snap)

2824

2825

2826 if (cplan)

2828

2829

2830

2831

2833

2834

2837

2838

2840

2841

2842

2843

2844

2845

2846 if (my_res == 0)

2848

2849 return my_res;

2850}

2851

2852

2853

2854

2858{

2860

2861 if (nargs > 0)

2862 {

2864

2865 for (int i = 0; i < nargs; i++)

2866 {

2868

2869 prm->value = Values[i];

2872 prm->ptype = argtypes[i];

2873 }

2874 }

2875 else

2876 paramLI = NULL;

2877 return paramLI;

2878}

2879

2880static int

2883{

2884 int operation = queryDesc->operation;

2885 int eflags;

2886 int res;

2887

2888 switch (operation)

2889 {

2892 {

2893

2895 }

2896 else

2898 break;

2902 else

2904 break;

2908 else

2910 break;

2914 else

2916 break;

2920 else

2922 break;

2923 default:

2925 }

2926

2927#ifdef SPI_EXECUTOR_STATS

2928 if (ShowExecutorStats)

2930#endif

2931

2932

2933 if (fire_triggers)

2934 eflags = 0;

2935 else

2937

2938 if (queryDesc->cplan)

2939 {

2942 }

2943 else

2944 {

2946 elog(ERROR, "ExecutorStart() failed unexpectedly");

2947 }

2948

2950

2952

2955 {

2957 elog(ERROR, "consistency check on SPI tuple count failed");

2958 }

2959

2962

2963

2964#ifdef SPI_EXECUTOR_STATS

2965 if (ShowExecutorStats)

2966 ShowUsage("SPI EXECUTOR STATS");

2967#endif

2968

2969 return res;

2970}

2971

2972

2973

2974

2975

2976

2977static void

2979{

2981 const char *query = carg->query;

2982 int syntaxerrposition;

2983

2984 if (query == NULL)

2985 return;

2986

2987

2988

2989

2990

2992 if (syntaxerrposition > 0)

2993 {

2997 }

2998 else

2999 {

3000

3001 switch (carg->mode)

3002 {

3004 errcontext("PL/pgSQL expression \"%s\"", query);

3005 break;

3009 errcontext("PL/pgSQL assignment \"%s\"", query);

3010 break;

3011 default:

3012 errcontext("SQL statement \"%s\"", query);

3013 break;

3014 }

3015 }

3016}

3017

3018

3019

3020

3021

3022

3023static void

3026{

3028

3029

3031 elog(ERROR, "invalid portal in SPI cursor operation");

3032

3033

3035 elog(ERROR, "SPI cursor operation called while not connected");

3036

3037

3042

3043

3045 direction,

3046 count,

3048

3049

3050

3051

3052

3053

3054

3055

3056

3058

3060 elog(ERROR, "consistency check on SPI tuple count failed");

3061

3062

3065

3066

3068

3069

3071}

3072

3073

3076{

3078}

3079

3082{

3084}

3085

3086

3087

3088

3089

3090

3091

3092

3093static int

3095{

3098

3099 if (use_exec)

3100 {

3101

3103

3105 }

3106

3107 return 0;

3108}

3109

3110

3111

3112

3113

3114

3115

3116

3117static int

3119{

3120 if (use_exec)

3121 {

3122

3124

3126

3128 }

3129

3130 return 0;

3131}

3132

3133static bool

3135{

3138 bool failed = false;

3139

3140 if (tuptable == NULL)

3141 failed = true;

3142 else if (processed != tuptable->numvals)

3143 failed = true;

3144

3145 return failed;

3146}

3147

3148

3149

3150

3151

3152

3153

3154

3155

3156

3159{

3165

3166

3169

3171

3172

3173

3174

3175

3177 "SPI Plan",

3180

3181

3184 newplan->plancxt = plancxt;

3188 if (plan->nargs > 0)

3189 {

3192 }

3193 else

3197

3198

3199

3200

3201

3202

3203

3204 foreach(lc, plan->plancache_list)

3205 {

3207

3209

3210

3212 }

3213

3215

3216

3217 plan->plancache_list = NIL;

3218

3219 return newplan;

3220}

3221

3222

3223

3224

3227{

3232

3233

3235

3236

3237

3238

3239

3240

3242 "SPI Plan",

3245

3246

3249 newplan->plancxt = plancxt;

3253 if (plan->nargs > 0)

3254 {

3257 }

3258 else

3262

3263

3264 foreach(lc, plan->plancache_list)

3265 {

3268

3271 }

3272

3274

3275

3276

3277

3278

3279

3280 newplan->saved = true;

3282

3284 {

3286

3288 }

3289

3290 return newplan;

3291}

3292

3293

3294

3295

3298{

3299

3301

3302

3304 return NULL;

3305

3307}

3308

3309

3310

3311

3312

3313int

3315{

3317 int res;

3318

3319 if (enr == NULL || enr->md.name == NULL)

3321

3322 res = _SPI_begin_call(false);

3323 if (res < 0)

3324 return res;

3325

3327 if (match)

3329 else

3330 {

3333

3336 }

3337

3339

3340 return res;

3341}

3342

3343

3344

3345

3346

3347int

3349{

3351 int res;

3352

3353 if (name == NULL)

3355

3356 res = _SPI_begin_call(false);

3357 if (res < 0)

3358 return res;

3359

3361 if (match)

3362 {

3365 }

3366 else

3368

3370

3371 return res;

3372}

3373

3374

3375

3376

3377

3378

3379

3380int

3382{

3383 if (tdata == NULL)

3385

3387 {

3390 int rc;

3391

3400 return rc;

3401 }

3402

3404 {

3407 int rc;

3408

3417 return rc;

3418 }

3419

3421}

List * raw_parser(const char *str, RawParseMode mode)

static bool Nulls[MAXATTR]

#define InvalidSubTransactionId

void InitializeQueryCompletion(QueryCompletion *qc)

const char * GetCommandTagName(CommandTag commandTag)

Datum datumTransfer(Datum value, bool typByVal, int typLen)

DestReceiver * CreateDestReceiver(CommandDest dest)

DestReceiver * None_Receiver

int internalerrquery(const char *query)

int internalerrposition(int cursorpos)

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

ErrorContextCallback * error_context_stack

void ReThrowError(ErrorData *edata)

ErrorData * CopyErrorData(void)

void FlushErrorState(void)

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

int errcode(int sqlerrcode)

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

int errposition(int cursorpos)

#define ereport(elevel,...)

bool ExecSupportsBackwardScan(Plan *node)

bool ExecutorStart(QueryDesc *queryDesc, int eflags)

void ExecutorStartCachedPlan(QueryDesc *queryDesc, int eflags, CachedPlanSource *plansource, int query_index)

void ExecutorEnd(QueryDesc *queryDesc)

void ExecutorFinish(QueryDesc *queryDesc)

void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)

#define EXEC_FLAG_SKIP_TRIGGERS

char * OidOutputFunctionCall(Oid functionId, Datum val)

#define DatumGetHeapTupleHeader(X)

Assert(PointerIsAligned(start, uint64))

const FormData_pg_attribute * SystemAttributeByName(const char *attname)

const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)

HeapTuple heap_copytuple(HeapTuple tuple)

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

void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)

Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)

void heap_freetuple(HeapTuple htup)

#define HeapTupleIsValid(tuple)

static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)

static void * GETSTRUCT(const HeapTupleData *tuple)

static void slist_delete_current(slist_mutable_iter *iter)

#define slist_foreach_modify(iter, lhead)

static void slist_init(slist_head *head)

static void slist_push_head(slist_head *head, slist_node *node)

#define slist_container(type, membername, ptr)

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

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

void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)

char * get_namespace_name(Oid nspid)

char * MemoryContextStrdup(MemoryContext context, const char *string)

void * MemoryContextAlloc(MemoryContext context, Size size)

void MemoryContextReset(MemoryContext context)

MemoryContext TopTransactionContext

char * pstrdup(const char *in)

void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)

void * repalloc(void *pointer, Size size)

void pfree(void *pointer)

void * palloc0(Size size)

MemoryContext TopMemoryContext

MemoryContext CurrentMemoryContext

MemoryContext CacheMemoryContext

void MemoryContextDelete(MemoryContext context)

void * repalloc_huge(void *pointer, Size size)

MemoryContext PortalContext

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define ALLOCSET_SMALL_SIZES

int namestrcmp(Name name, const char *str)

#define IsA(nodeptr, _type_)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

ParamListInfo makeParamList(int numParams)

ParamListInfo copyParamList(ParamListInfo from)

void(* ParserSetupHook)(struct ParseState *pstate, void *arg)

#define CURSOR_OPT_SCROLL

#define CURSOR_OPT_PARALLEL_OK

#define CURSOR_OPT_NO_SCROLL

@ RAW_PARSE_PLPGSQL_ASSIGN2

@ RAW_PARSE_PLPGSQL_ASSIGN1

@ RAW_PARSE_PLPGSQL_ASSIGN3

FormData_pg_attribute * Form_pg_attribute

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define linitial_node(type, l)

FormData_pg_type * Form_pg_type

void CachedPlanSetParentContext(CachedPlanSource *plansource, MemoryContext newcontext)

bool CachedPlanIsValid(CachedPlanSource *plansource)

void DropCachedPlan(CachedPlanSource *plansource)

void SaveCachedPlan(CachedPlanSource *plansource)

void CompleteCachedPlan(CachedPlanSource *plansource, List *querytree_list, MemoryContext querytree_context, Oid *param_types, int num_params, ParserSetupHook parserSetup, void *parserSetupArg, int cursor_options, bool fixed_result)

CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)

CachedPlanSource * CreateOneShotCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)

CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)

CachedPlanSource * CopyCachedPlan(CachedPlanSource *plansource)

void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)

void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, CommandTag commandTag, List *stmts, CachedPlan *cplan, CachedPlanSource *plansource)

Portal CreateNewPortal(void)

void HoldPinnedPortals(void)

void PortalDrop(Portal portal, bool isTopCommit)

Portal GetPortalByName(const char *name)

Portal CreatePortal(const char *name, bool allowDup, bool dupSilent)

void ForgetPortalSnapshots(void)

List * pg_analyze_and_rewrite_withcb(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)

List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)

void ShowUsage(const char *title)

static Datum ObjectIdGetDatum(Oid X)

void FreeQueryDesc(QueryDesc *qdesc)

bool PlannedStmtRequiresSnapshot(PlannedStmt *pstmt)

void EnsurePortalSnapshotExists(void)

void PortalStart(Portal portal, ParamListInfo params, int eflags, Snapshot snapshot)

uint64 PortalRunFetch(Portal portal, FetchDirection fdirection, long count, DestReceiver *dest)

QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, CachedPlan *cplan, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)

EphemeralNamedRelation get_ENR(QueryEnvironment *queryEnv, const char *name)

void unregister_ENR(QueryEnvironment *queryEnv, const char *name)

QueryEnvironment * create_queryEnv(void)

void register_ENR(QueryEnvironment *queryEnv, EphemeralNamedRelation enr)

#define RelationGetRelationName(relation)

#define RelationGetNamespace(relation)

ResourceOwner CurrentResourceOwner

Snapshot GetTransactionSnapshot(void)

void PushActiveSnapshot(Snapshot snapshot)

void UpdateActiveSnapshotCommandId(void)

bool ActiveSnapshotSet(void)

void PopActiveSnapshot(void)

void PushCopiedSnapshot(Snapshot snapshot)

Snapshot GetActiveSnapshot(void)

void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)

List * SPI_plan_get_plan_sources(SPIPlanPtr plan)

SPIPlanPtr SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes, int cursorOptions)

static int _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options, Snapshot snapshot, Snapshot crosscheck_snapshot, bool fire_triggers)

int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, bool read_only, long tcount)

bool spi_printtup(TupleTableSlot *slot, DestReceiver *self)

static void _SPI_error_callback(void *arg)

static int _SPI_connected

void SPI_scroll_cursor_move(Portal portal, FetchDirection direction, long count)

static SPIPlanPtr _SPI_save_plan(SPIPlanPtr plan)

void SPI_cursor_move(Portal portal, bool forward, long count)

void SPI_freetuple(HeapTuple tuple)

int SPI_fnumber(TupleDesc tupdesc, const char *fname)

void spi_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)

static int _SPI_end_call(bool use_exec)

bool SPI_plan_is_valid(SPIPlanPtr plan)

void SPI_commit_and_chain(void)

bool SPI_is_cursor_plan(SPIPlanPtr plan)

char * SPI_gettype(TupleDesc tupdesc, int fnumber)

void * SPI_repalloc(void *pointer, Size size)

SPIPlanPtr SPI_prepare_extended(const char *src, const SPIPrepareOptions *options)

Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)

static _SPI_connection * _SPI_stack

HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc)

int SPI_freeplan(SPIPlanPtr plan)

const char * SPI_result_code_string(int code)

void SPI_rollback_and_chain(void)

SPITupleTable * SPI_tuptable

Portal SPI_cursor_find(const char *name)

int SPI_unregister_relation(const char *name)

bool SPI_inside_nonatomic_context(void)

static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)

int SPI_execute_snapshot(SPIPlanPtr plan, Datum *Values, const char *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount)

int SPI_execute_plan_extended(SPIPlanPtr plan, const SPIExecuteOptions *options)

SPIPlanPtr SPI_prepare_params(const char *src, ParserSetupHook parserSetup, void *parserSetupArg, int cursorOptions)

SPIPlanPtr SPI_saveplan(SPIPlanPtr plan)

void SPI_cursor_fetch(Portal portal, bool forward, long count)

Portal SPI_cursor_parse_open(const char *name, const char *src, const SPIParseOpenOptions *options)

int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)

static _SPI_connection * _SPI_current

Datum SPI_datumTransfer(Datum value, bool typByVal, int typLen)

CachedPlan * SPI_plan_get_cached_plan(SPIPlanPtr plan)

int SPI_register_trigger_data(TriggerData *tdata)

static int _SPI_stack_depth

static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)

Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only)

Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, Datum *Values, const char *Nulls, bool read_only, int cursorOptions)

void SPI_freetuptable(SPITupleTable *tuptable)

Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)

int SPI_exec(const char *src, long tcount)

static int _SPI_begin_call(bool use_exec)

static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)

int SPI_register_relation(EphemeralNamedRelation enr)

HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum, Datum *Values, const char *Nulls)

SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)

int SPI_keepplan(SPIPlanPtr plan)

void SPI_cursor_close(Portal portal)

void SPI_pfree(void *pointer)

int SPI_connect_ext(int options)

int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount)

static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)

char * SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)

void SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, long count)

char * SPI_getnspname(Relation rel)

static void _SPI_commit(bool chain)

int SPI_execute_extended(const char *src, const SPIExecuteOptions *options)

static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)

static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount, CachedPlanSource *plansource, int query_index)

void * SPI_palloc(Size size)

static bool _SPI_checktuples(void)

static EphemeralNamedRelation _SPI_find_ENR_by_name(const char *name)

static MemoryContext _SPI_execmem(void)

static MemoryContext _SPI_procmem(void)

int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, Datum *Values, const char *Nulls, bool read_only, long tcount)

void SPI_start_transaction(void)

HeapTuple SPI_copytuple(HeapTuple tuple)

int SPI_getargcount(SPIPlanPtr plan)

struct SPICallbackArg SPICallbackArg

void AtEOXact_SPI(bool isCommit)

int SPI_execute(const char *src, bool read_only, long tcount)

Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)

static void _SPI_rollback(bool chain)

char * SPI_getrelname(Relation rel)

char * SPI_fname(TupleDesc tupdesc, int fnumber)

Oid SPI_getargtypeid(SPIPlanPtr plan, int argIndex)

static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)

#define SPI_ERROR_TRANSACTION

#define SPI_ERROR_REL_NOT_FOUND

#define SPI_ERROR_REL_DUPLICATE

#define SPI_OPT_NONATOMIC

#define SPI_OK_TD_REGISTER

#define SPI_OK_REL_REGISTER

#define SPI_ERROR_OPUNKNOWN

#define SPI_OK_UPDATE_RETURNING

#define SPI_ERROR_UNCONNECTED

#define SPI_OK_REL_UNREGISTER

#define SPI_ERROR_ARGUMENT

#define SPI_ERROR_NOATTRIBUTE

#define SPI_OK_INSERT_RETURNING

#define SPI_ERROR_NOOUTFUNC

#define SPI_OK_DELETE_RETURNING

struct _SPI_plan * SPIPlanPtr

#define SPI_ERROR_TYPUNKNOWN

#define SPI_OK_MERGE_RETURNING

#define SPI_ERROR_CONNECT

struct CachedPlan * gplan

const char * query_string

struct RawStmt * raw_parse_tree

EphemeralNamedRelationMetadataData md

struct ErrorContextCallback * previous

void(* callback)(void *arg)

ParamExternData params[FLEXIBLE_ARRAY_MEMBER]

QueryEnvironment * queryEnv

MemoryContext portalContext

PlannedStmt * plannedstmt

Tuplestorestate * tg_oldtable

Tuplestorestate * tg_newtable

SubTransactionId connectSubid

SPITupleTable * outer_tuptable

QueryEnvironment * queryEnv

SubTransactionId execSubid

ParserSetupHook parserSetup

#define FirstLowInvalidHeapAttributeNumber

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)

static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)

int64 tuplestore_tuple_count(Tuplestorestate *state)

static HeapTuple ExecCopySlotHeapTuple(TupleTableSlot *slot)

void assign_record_type_typmod(TupleDesc tupDesc)

void ProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)

bool CommandIsReadOnly(PlannedStmt *pstmt)

CommandTag CreateCommandTag(Node *parsetree)

static const char * CreateCommandName(Node *parsetree)

@ PROCESS_UTILITY_QUERY_NONATOMIC

void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)

void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)

SubTransactionId GetCurrentSubTransactionId(void)

void CommandCounterIncrement(void)

void StartTransactionCommand(void)

bool IsSubTransaction(void)

void CommitTransactionCommand(void)

void AbortCurrentTransaction(void)