PostgreSQL Source Code: src/backend/tcop/pquery.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

17

18#include <limits.h>

19

30

31

32

33

34

35

37

38

40 const char *sourceText,

51 bool isTopLevel, bool setHoldSnapshot,

54 bool isTopLevel, bool setHoldSnapshot,

59 long count,

62

63

64

65

66

69 const char *sourceText,

75 int instrument_options)

76{

78

81 qd->sourceText = sourceText;

83

85 qd->dest = dest;

86 qd->params = params;

88 qd->instrument_options = instrument_options;

89

90

95

96

98

99 return qd;

100}

101

102

103

104

105void

107{

108

110

111

114

115

117}

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136static void

138 const char *sourceText,

143{

145

146

147

148

151 dest, params, queryEnv, 0);

152

153

154

155

157

158

159

160

162

163

164

165

166 if (qc)

167 {

169

171 tag = CMDTAG_SELECT;

173 tag = CMDTAG_INSERT;

175 tag = CMDTAG_UPDATE;

177 tag = CMDTAG_DELETE;

179 tag = CMDTAG_MERGE;

180 else

181 tag = CMDTAG_UNKNOWN;

182

184 }

185

186

187

188

191

193}

194

195

196

197

198

199

200

201

202

203

206{

207 int nSetTag;

209

210

211

212

213

214

215

217 {

219

221 {

223

224 if (query->canSetTag)

225 {

227 {

228 if (query->hasModifyingCTE)

230 else

232 }

234 {

237

239 }

240 }

241 }

243 {

245

247 {

249 {

252 else

254 }

256 {

259

261 }

262 }

263 }

264 else

266 }

267

268

269

270

271

272

273 nSetTag = 0;

274 foreach(lc, stmts)

275 {

277

279 {

281

282 if (query->canSetTag)

283 {

284 if (++nSetTag > 1)

289 }

290 }

292 {

294

296 {

297 if (++nSetTag > 1)

302 }

303 }

304 else

306 }

307 if (nSetTag == 1)

309

310

312}

313

314

315

316

317

318

319

320

323{

324

326 return NIL;

327

329}

330

331

332

333

334

335

336

337

338

339

340

341

342

345{

346 if (stmt == NULL)

347 return NIL;

349 {

351

353 {

354

356 }

357 else

358 {

363 return NIL;

364 }

365 }

367 {

369

371 {

372

374 }

375 else

376 {

381 return NIL;

382 }

383 }

385 {

388

393 }

395 {

398

401 }

402 return NIL;

403}

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428void

430 int eflags, Snapshot snapshot)

431{

432 Portal saveActivePortal;

437 int myeflags;

438

441

442

443

444

449 {

454

456

457

459

460

461

462

464

465

466

467

469 {

471

472

473 if (snapshot)

475 else

477

478

479

480

481

482

483

484

485

486

487

488

489

490

496 params,

498 0);

499

500

501

502

503

504

507 else

508 myeflags = eflags;

509

510

511

512

514

515

516

517

519

520

521

522

524

525

526

527

529 portal->atEnd = false;

531

533 break;

534

537

538

539

540

541

542 {

544

548 }

549

550

551

552

554 portal->atEnd = false;

556 break;

557

559

560

561

562

563

564 {

566

569 }

570

571

572

573

575 portal->atEnd = false;

577 break;

578

580

582 break;

583 }

584 }

586 {

587

589

590

594

596 }

598

600

604

606}

607

608

609

610

611

612

613

614

615

616

617

618void

620{

621 int natts;

622 int i;

623

624

625 if (portal->tupDesc == NULL)

626 return;

630 natts * sizeof(int16));

631 if (nFormats > 1)

632 {

633

634 if (nFormats != natts)

636 (errcode(ERRCODE_PROTOCOL_VIOLATION),

637 errmsg("bind message has %d result formats but query has %d columns",

638 nFormats, natts)));

639 memcpy(portal->formats, formats, natts * sizeof(int16));

640 }

641 else if (nFormats > 0)

642 {

643

644 int16 format1 = formats[0];

645

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

647 portal->formats[i] = format1;

648 }

649 else

650 {

651

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

654 }

655}

656

657

658

659

660

661

662

663

664

665

666

667

668

669

670

671

672

673

674

675

676

677

678

679bool

683{

684 bool result;

688 Portal saveActivePortal;

692

694

695 TRACE_POSTGRESQL_QUERY_EXECUTE_START();

696

697

698 if (qc)

700

702 {

704

706 }

707

708

709

710

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

734 {

739

741

743 {

748

749

750

751

752

753

756

757

758

759

761

762

763

764

765

766

767 if (qc && portal->qc.commandTag != CMDTAG_UNKNOWN)

768 {

771 }

772

773

775

776

777

778

779 result = portal->atEnd;

780 break;

781

784 dest, altdest, qc);

785

786

788

789

790 result = true;

791 break;

792

793 default:

794 elog(ERROR, "unrecognized portal strategy: %d",

796 result = false;

797 break;

798 }

799 }

801 {

802

804

805

806 if (saveMemoryContext == saveTopTransactionContext)

808 else

811 if (saveResourceOwner == saveTopTransactionResourceOwner)

813 else

816

818 }

820

821 if (saveMemoryContext == saveTopTransactionContext)

823 else

826 if (saveResourceOwner == saveTopTransactionResourceOwner)

828 else

831

833 ShowUsage("EXECUTOR STATISTICS");

834

835 TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();

836

837 return result;

838}

839

840

841

842

843

844

845

846

847

848

849

850

851

852

853

854

855

856

857

860 bool forward,

861 long count,

863{

867

868

869

870

871

873

874

876

877

878

879

880

881

882

883 if (queryDesc)

885

886

887

888

889

890

891

892

893

894

895

896

897 if (forward)

898 {

899 if (portal->atEnd || count <= 0)

900 {

902 count = 0;

903 }

904 else

906

907

909 count = 0;

910

913 else

914 {

919 }

920

922 {

923 if (nprocessed > 0)

924 portal->atStart = false;

925 if (count == 0 || nprocessed < (uint64) count)

926 portal->atEnd = true;

928 }

929 }

930 else

931 {

934 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

935 errmsg("cursor can only scan forward"),

936 errhint("Declare it with SCROLL option to enable backward scan.")));

937

938 if (portal->atStart || count <= 0)

939 {

941 count = 0;

942 }

943 else

945

946

948 count = 0;

949

952 else

953 {

958 }

959

961 {

962 if (nprocessed > 0 && portal->atEnd)

963 {

964 portal->atEnd = false;

965 portal->portalPos++;

966 }

967 if (count == 0 || nprocessed < (uint64) count)

968 {

969 portal->atStart = true;

971 }

972 else

973 {

975 }

976 }

977 }

978

979 return nprocessed;

980}

981

982

983

984

985

986

987

988

989static void

991{

994

1001 false,

1002 NULL,

1003 NULL);

1004

1006 {

1009

1010

1011

1012

1013

1014

1015

1018 break;

1019

1022 isTopLevel, true, treceiver, &qc);

1023 break;

1024

1025 default:

1026 elog(ERROR, "unsupported portal strategy: %d",

1028 break;

1029 }

1030

1031

1032 if (qc.commandTag != CMDTAG_UNKNOWN)

1034

1035 treceiver->rDestroy(treceiver);

1036}

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1053{

1054 uint64 current_tuple_count = 0;

1056

1058

1060

1062 {

1063

1064 }

1065 else

1066 {

1068

1069 for (;;)

1070 {

1072 bool ok;

1073

1075

1077 slot);

1078

1080

1081 if (!ok)

1082 break;

1083

1084

1085

1086

1087

1088

1089 if (dest->receiveSlot(slot, dest))

1090 break;

1091

1093

1094

1095

1096

1097

1098

1099 current_tuple_count++;

1100 if (count && count == current_tuple_count)

1101 break;

1102 }

1103 }

1104

1106

1108

1109 return current_tuple_count;

1110}

1111

1112

1113

1114

1115

1116static void

1118 bool isTopLevel, bool setHoldSnapshot,

1120{

1121

1122

1123

1125 {

1127

1128

1129 if (setHoldSnapshot)

1130 {

1133 }

1134

1135

1136

1137

1138

1139

1140

1142

1144 }

1145 else

1147

1150 (portal->cplan != NULL),

1155 qc);

1156

1157

1159

1160

1161

1162

1163

1164

1165

1166

1168 {

1171 }

1173}

1174

1175

1176

1177

1178

1179

1180static void

1182 bool isTopLevel, bool setHoldSnapshot,

1185{

1186 bool active_snapshot_set = false;

1188

1189

1190

1191

1192

1193

1194

1195

1196

1197

1198

1203

1204

1205

1206

1207

1208 foreach(stmtlist_item, portal->stmts)

1209 {

1211

1212

1213

1214

1216

1218 {

1219

1220

1221

1222 TRACE_POSTGRESQL_QUERY_EXECUTE_START();

1223

1226

1227

1228

1229

1230

1231

1232

1233 if (!active_snapshot_set)

1234 {

1236

1237

1238 if (setHoldSnapshot)

1239 {

1242 }

1243

1244

1245

1246

1247

1248

1249

1250

1251

1252

1254

1255

1256

1257

1258

1259

1260 active_snapshot_set = true;

1261 }

1262 else

1264

1266 {

1267

1273 }

1274 else

1275 {

1276

1281 altdest, NULL);

1282 }

1283

1285 ShowUsage("EXECUTOR STATISTICS");

1286

1287 TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();

1288 }

1289 else

1290 {

1291

1292

1293

1294

1295

1296

1297

1298

1299

1300

1301

1303 {

1304 Assert(!active_snapshot_set);

1305

1308 }

1309 else

1310 {

1312

1314 altdest, NULL);

1315 }

1316 }

1317

1318

1319

1320

1322

1324

1325

1326

1327

1328

1329

1330

1331

1332

1334 break;

1335

1336

1337

1338

1339

1340 if (lnext(portal->stmts, stmtlist_item) != NULL)

1342 }

1343

1344

1345 if (active_snapshot_set)

1347

1348

1349

1350

1351

1352

1353

1354 if (qc &&

1358}

1359

1360

1361

1362

1363

1364

1365

1366

1367

1368

1369

1370

1371

1375 long count,

1377{

1379 Portal saveActivePortal;

1383

1385

1386

1387

1388

1390

1391

1392

1393

1398 {

1403

1405

1407 {

1410 break;

1411

1415

1416

1417

1418

1419

1422

1423

1424

1425

1427 break;

1428

1429 default:

1430 elog(ERROR, "unsupported portal strategy");

1431 result = 0;

1432 break;

1433 }

1434 }

1436 {

1437

1439

1440

1444

1446 }

1448

1450

1451

1453

1457

1458 return result;

1459}

1460

1461

1462

1463

1464

1465

1466

1467

1468

1469

1473 long count,

1475{

1476 bool forward;

1477

1482

1483

1484

1485

1486

1487

1488

1489

1490

1491

1492 switch (fdirection)

1493 {

1495 if (count < 0)

1496 {

1498 count = -count;

1499 }

1500

1501 break;

1503 if (count < 0)

1504 {

1506 count = -count;

1507 }

1508

1509 break;

1511 if (count > 0)

1512 {

1513

1514

1515

1516

1517

1518

1519

1520

1521

1522

1523

1524

1525

1526

1527

1530 {

1532 if (count > 1)

1535 }

1536 else

1537 {

1538 long pos = (long) portal->portalPos;

1539

1541 pos++;

1542 if (count <= pos)

1545 else if (count > pos + 1)

1548 }

1550 }

1551 else if (count < 0)

1552 {

1553

1554

1555

1556

1557

1558

1559

1561 if (count < -1)

1564 }

1565 else

1566 {

1567

1568

1571 }

1572 break;

1574 if (count > 0)

1575 {

1576

1577

1578

1579 if (count > 1)

1582 }

1583 else if (count < 0)

1584 {

1585

1586

1587

1588

1589 if (count < -1)

1592 }

1593 else

1594 {

1595

1596

1598 }

1599 break;

1600 default:

1602 break;

1603 }

1604

1605

1606

1607

1608

1610

1611

1612

1613

1614 if (count == 0)

1615 {

1616 bool on_row;

1617

1618

1619 on_row = (!portal->atStart && !portal->atEnd);

1620

1622 {

1623

1624 return on_row ? 1 : 0;

1625 }

1626 else

1627 {

1628

1629

1630

1631

1632

1633

1634

1635 if (on_row)

1636 {

1638

1639 count = 1;

1640 forward = true;

1641 }

1642 }

1643 }

1644

1645

1646

1647

1649 {

1651

1652 if (result > 0 && !portal->atEnd)

1653 result--;

1655 return result;

1656 }

1657

1659}

1660

1661

1662

1663

1664static void

1666{

1668

1669

1670

1671

1672

1674 return;

1675

1676

1679 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

1680 errmsg("cursor can only scan forward"),

1681 errhint("Declare it with SCROLL option to enable backward scan.")));

1682

1683

1685 {

1687

1691 }

1692

1693

1695 if (queryDesc)

1696 {

1700 }

1701

1703 portal->atEnd = false;

1705}

1706

1707

1708

1709

1710bool

1712{

1714

1715

1716 if (utilityStmt == NULL)

1717 return true;

1718

1719

1720

1721

1722

1723

1724

1725

1726

1727

1728

1729

1730

1731

1737

1744 return false;

1745

1746 return true;

1747}

1748

1749

1750

1751

1752

1753

1754

1755

1756

1757

1758

1759void

1761{

1763

1764

1765

1766

1767

1768

1770 return;

1771

1772

1774 if (unlikely(portal == NULL))

1775 elog(ERROR, "cannot execute SQL without an outer snapshot or portal");

1777

1778

1779

1780

1781

1782

1783

1785

1787}

PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)

List * FetchPreparedStatementTargetList(PreparedStatement *stmt)

void InitializeQueryCompletion(QueryCompletion *qc)

static void SetQueryCompletion(QueryCompletion *qc, CommandTag commandTag, uint64 nprocessed)

static void CopyQueryCompletion(QueryCompletion *dst, const QueryCompletion *src)

DestReceiver * CreateDestReceiver(CommandDest dest)

DestReceiver * None_Receiver

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

void ExecutorEnd(QueryDesc *queryDesc)

void ExecutorFinish(QueryDesc *queryDesc)

void ExecutorRewind(QueryDesc *queryDesc)

void ExecutorStart(QueryDesc *queryDesc, int eflags)

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

TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)

void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)

TupleDesc ExecCleanTypeFromTL(List *targetList)

const TupleTableSlotOps TTSOpsMinimalTuple

#define EXEC_FLAG_BACKWARD

#define palloc_object(type)

Assert(PointerIsAligned(start, uint64))

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

void * MemoryContextAlloc(MemoryContext context, Size size)

MemoryContext TopTransactionContext

void pfree(void *pointer)

void MemoryContextDeleteChildren(MemoryContext context)

MemoryContext CurrentMemoryContext

MemoryContext PortalContext

#define CHECK_FOR_INTERRUPTS()

#define IsA(nodeptr, _type_)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

#define CURSOR_OPT_SCROLL

#define CURSOR_OPT_NO_SCROLL

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define linitial_node(type, l)

static ListCell * lnext(const List *l, const ListCell *c)

void MarkPortalDone(Portal portal)

void MarkPortalFailed(Portal portal)

PlannedStmt * PortalGetPrimaryStmt(Portal portal)

void MarkPortalActive(Portal portal)

Portal GetPortalByName(const char *name)

void PortalCreateHoldStore(Portal portal)

void ShowUsage(const char *title)

void FreeQueryDesc(QueryDesc *qdesc)

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

PortalStrategy ChoosePortalStrategy(List *stmts)

static void PortalRunMulti(Portal portal, bool isTopLevel, bool setHoldSnapshot, DestReceiver *dest, DestReceiver *altdest, QueryCompletion *qc)

static void FillPortalStore(Portal portal, bool isTopLevel)

bool PlannedStmtRequiresSnapshot(PlannedStmt *pstmt)

void EnsurePortalSnapshotExists(void)

void PortalSetResultFormat(Portal portal, int nFormats, int16 *formats)

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

static uint64 PortalRunSelect(Portal portal, bool forward, long count, DestReceiver *dest)

static uint64 RunFromStore(Portal portal, ScanDirection direction, uint64 count, DestReceiver *dest)

List * FetchStatementTargetList(Node *stmt)

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

static void ProcessQuery(PlannedStmt *plan, const char *sourceText, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)

List * FetchPortalTargetList(Portal portal)

bool PortalRun(Portal portal, long count, bool isTopLevel, DestReceiver *dest, DestReceiver *altdest, QueryCompletion *qc)

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

static void DoPortalRewind(Portal portal)

static void PortalRunUtility(Portal portal, PlannedStmt *pstmt, bool isTopLevel, bool setHoldSnapshot, DestReceiver *dest, QueryCompletion *qc)

ResourceOwner TopTransactionResourceOwner

ResourceOwner CurrentResourceOwner

#define ScanDirectionIsForward(direction)

#define ScanDirectionIsNoMovement(direction)

@ NoMovementScanDirection

Snapshot GetTransactionSnapshot(void)

void UnregisterSnapshot(Snapshot snapshot)

void PushActiveSnapshot(Snapshot snapshot)

void UpdateActiveSnapshotCommandId(void)

bool ActiveSnapshotSet(void)

Snapshot RegisterSnapshot(Snapshot snapshot)

void PopActiveSnapshot(void)

void PushCopiedSnapshot(Snapshot snapshot)

void PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level)

Snapshot GetActiveSnapshot(void)

MemoryContext holdContext

QueryEnvironment * queryEnv

MemoryContext portalContext

ParamListInfo portalParams

Tuplestorestate * holdStore

PlannedStmt * plannedstmt

struct Instrumentation * totaltime

QueryEnvironment * queryEnv

Snapshot crosscheck_snapshot

void(* rDestroy)(DestReceiver *self)

void SetTuplestoreDestReceiverParams(DestReceiver *self, Tuplestorestate *tStore, MemoryContext tContext, bool detoast, TupleDesc target_tupdesc, const char *map_failure_msg)

bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)

void tuplestore_rescan(Tuplestorestate *state)

static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)

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

bool UtilityReturnsTuples(Node *parsetree)

TupleDesc UtilityTupleDescriptor(Node *parsetree)

@ PROCESS_UTILITY_TOPLEVEL

void CommandCounterIncrement(void)