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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

19

49#include "utils/fmgroids.h"

58

59

60

61

62

63

64typedef struct

65{

69

70

74 bool verbose, bool *pSwapToastByContent,

78 Oid indexOid);

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106void

108{

116

117

118 foreach(lc, stmt->params)

119 {

121

122 if (strcmp(opt->defname, "verbose") == 0)

124 else

126 (errcode(ERRCODE_SYNTAX_ERROR),

127 errmsg("unrecognized CLUSTER option \"%s\"",

130 }

131

133

134 if (stmt->relation != NULL)

135 {

136

137 Oid tableOid;

138

139

140

141

142

143

146 0,

148 NULL);

150

151

152

153

154

157 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

158 errmsg("cannot cluster temporary tables of other sessions")));

159

160 if (stmt->indexname == NULL)

161 {

163

164

166 {

169 break;

171 }

172

175 (errcode(ERRCODE_UNDEFINED_OBJECT),

176 errmsg("there is no previously clustered index for table \"%s\"",

177 stmt->relation->relname)));

178 }

179 else

180 {

181

182

183

184

186 rel->rd_rel->relnamespace);

189 (errcode(ERRCODE_UNDEFINED_OBJECT),

190 errmsg("index \"%s\" for table \"%s\" does not exist",

191 stmt->indexname, stmt->relation->relname)));

192 }

193

194

195 if (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)

196 {

198

199

200 return;

201 }

202 }

203

204

205

206

207

208

209

211

212

214 "Cluster",

216

217

218

219

220

221

222

223

224

225

226

227

228

230 if (rel != NULL)

231 {

232 Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);

235

236

238 }

239 else

240 {

243 }

244

245

247

248

250

251

253}

254

255

256

257

258

259

260

261

262static void

264{

266

267

270

271

272 foreach(lc, rtcs)

273 {

276

277

279

280

282

284

285

287

288

291 }

292}

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310void

312{

314 Oid save_userid;

315 int save_sec_context;

316 int save_nestlevel;

320

322

323

325

330 else

333

334

335

336

337

338

344

345

346

347

348

349

350

351

352

353 if (recheck)

354 {

355

357 {

359 goto out;

360 }

361

362

363

364

365

366

367

368

369

370

372 {

374 goto out;

375 }

376

378 {

379

380

381

383 {

385 goto out;

386 }

387

388

389

390

391

394 {

396 goto out;

397 }

398 }

399 }

400

401

402

403

404

405

406

409 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

410 errmsg("cannot cluster a shared catalog")));

411

412

413

414

415

417 {

420 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

421 errmsg("cannot cluster temporary tables of other sessions")));

422 else

424 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

425 errmsg("cannot vacuum temporary tables of other sessions")));

426 }

427

428

429

430

431

433

434

436 {

437

439

441 }

442 else

444

445

446

447

448

449

450

451

452 if (OldHeap->rd_rel->relkind == RELKIND_MATVIEW &&

454 {

456 goto out;

457 }

458

459 Assert(OldHeap->rd_rel->relkind == RELKIND_RELATION ||

460 OldHeap->rd_rel->relkind == RELKIND_MATVIEW ||

461 OldHeap->rd_rel->relkind == RELKIND_TOASTVALUE);

462

463

464

465

466

467

468

470

471

473

474

475out:

476

478

479

481

483}

484

485

486

487

488

489

490

491

492

493void

495{

497

498 OldIndex = index_open(indexOid, lockmode);

499

500

501

502

503 if (OldIndex->rd_index == NULL ||

506 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

507 errmsg("\"%s\" is not an index for table \"%s\"",

510

511

514 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

515 errmsg("cannot cluster on index \"%s\" because access method does not support clustering",

517

518

519

520

521

522

523

526 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

527 errmsg("cannot cluster on partial index \"%s\"",

529

530

531

532

533

534

535

536

537

538 if (!OldIndex->rd_index->indisvalid)

540 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

541 errmsg("cannot cluster on invalid index \"%s\"",

543

544

546}

547

548

549

550

551

552

553void

555{

560

561

562 if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)

564 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

565 errmsg("cannot mark index clustered in partitioned table")));

566

567

568

569

571 {

573 return;

574 }

575

576

577

578

580

582 {

584

588 elog(ERROR, "cache lookup failed for index %u", thisIndexOid);

590

591

592

593

594

595 if (indexForm->indisclustered)

596 {

597 indexForm->indisclustered = false;

599 }

600 else if (thisIndexOid == indexOid)

601 {

602

603 if (!indexForm->indisvalid)

604 elog(ERROR, "cannot cluster on invalid index %u", indexOid);

605 indexForm->indisclustered = true;

607 }

608

611

613 }

614

616}

617

618

619

620

621

622

623

624

625

626

627

628static void

630{

632 Oid accessMethod = OldHeap->rd_rel->relam;

633 Oid tableSpace = OldHeap->rd_rel->reltablespace;

634 Oid OIDNewHeap;

636 char relpersistence;

637 bool is_system_catalog;

638 bool swap_toast_by_content;

641

644

646

648

649

650 relpersistence = OldHeap->rd_rel->relpersistence;

652

653

654

655

656

657

658

660 accessMethod,

661 relpersistence,

665

666

668 &swap_toast_by_content, &frozenXid, &cutoffMulti);

669

670

671

675

676

677

678

679

680

682

683

684

685

686

688 swap_toast_by_content, false, true,

689 frozenXid, cutoffMulti,

690 relpersistence);

691}

692

693

694

695

696

697

698

699

700

701

702

703

706 char relpersistence, LOCKMODE lockmode)

707{

710 Oid OIDNewHeap;

711 Oid toastid;

714 Datum reloptions;

715 bool isNull;

716 Oid namespaceid;

717

718 OldHeap = table_open(OIDOldHeap, lockmode);

720

721

722

723

724

725

726

727

728

729

730

733 elog(ERROR, "cache lookup failed for relation %u", OIDOldHeap);

734 reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,

735 &isNull);

736 if (isNull)

737 reloptions = (Datum) 0;

738

739 if (relpersistence == RELPERSISTENCE_TEMP)

741 else

743

744

745

746

747

748

749

750

751

752

753

754

755

756 snprintf(NewHeapName, sizeof(NewHeapName), "pg_temp_%u", OIDOldHeap);

757

759 namespaceid,

760 NewTableSpace,

764 OldHeap->rd_rel->relowner,

765 NewAccessMethod,

766 OldHeapDesc,

768 RELKIND_RELATION,

769 relpersistence,

770 false,

773 reloptions,

774 false,

775 true,

776 true,

777 OIDOldHeap,

778 NULL);

780

782

783

784

785

786

788

789

790

791

792

793

794

795

796

797

798

799

800 toastid = OldHeap->rd_rel->reltoastrelid;

802 {

803

806 elog(ERROR, "cache lookup failed for relation %u", toastid);

807 reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,

808 &isNull);

809 if (isNull)

810 reloptions = (Datum) 0;

811

813

815 }

816

818

819 return OIDNewHeap;

820}

821

822

823

824

825

826

827

828

829

830static void

832 bool *pSwapToastByContent, TransactionId *pFreezeXid,

834{

842 bool use_sort;

843 double num_tuples = 0,

844 tups_vacuumed = 0,

845 tups_recently_dead = 0;

849 char *nspname;

850

852

853

855

856

857

858

859

862 Assert(newTupDesc->natts == oldTupDesc->natts);

863

864

865

866

867

868

869

870

871

872

873

874

875

876

877 if (OldHeap->rd_rel->reltoastrelid)

879

880

881

882

883

884

885

886

887 if (OldHeap->rd_rel->reltoastrelid && NewHeap->rd_rel->reltoastrelid)

888 {

889 *pSwapToastByContent = true;

890

891

892

893

894

895

896

897

898

899

900

901

902

903

904

905

906

907

908

910 }

911 else

912 *pSwapToastByContent = false;

913

914

915

916

917

918

921

922

923

924

925

926 {

928

932 }

933

934

935

936

937 {

939

943 }

944

945

946

947

948

949

950

951

952 if (OldIndex != NULL && OldIndex->rd_rel->relam == BTREE_AM_OID)

955 else

956 use_sort = false;

957

958

959 if (OldIndex != NULL && !use_sort)

961 (errmsg("clustering \"%s.%s\" using index scan on \"%s\"",

962 nspname,

965 else if (use_sort)

967 (errmsg("clustering \"%s.%s\" using sequential scan and sort",

968 nspname,

970 else

972 (errmsg("vacuuming \"%s.%s\"",

973 nspname,

975

976

977

978

979

980

981

985 &num_tuples, &tups_vacuumed,

986 &tups_recently_dead);

987

988

991

992

994

996

997

999 (errmsg("\"%s.%s\": found %.0f removable, %.0f nonremovable row versions in %u pages",

1000 nspname,

1002 tups_vacuumed, num_tuples,

1004 errdetail("%.0f dead row versions cannot be removed yet.\n"

1005 "%s.",

1006 tups_recently_dead,

1008

1009

1011

1015 elog(ERROR, "cache lookup failed for relation %u",

1018

1019 relform->relpages = num_pages;

1020 relform->reltuples = num_tuples;

1021

1022

1025 else

1027

1028

1031

1032

1034}

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1061

1062static void

1064 bool swap_toast_by_content,

1065 bool is_internal,

1068 Oid *mapped_tables)

1069{

1072 reltup2;

1074 relform2;

1076 relfilenumber2;

1078 char swptmpchr;

1079 Oid relam1,

1080 relam2;

1081

1082

1084

1087 elog(ERROR, "cache lookup failed for relation %u", r1);

1089

1092 elog(ERROR, "cache lookup failed for relation %u", r2);

1094

1095 relfilenumber1 = relform1->relfilenode;

1096 relfilenumber2 = relform2->relfilenode;

1097 relam1 = relform1->relam;

1098 relam2 = relform2->relam;

1099

1102 {

1103

1104

1105

1106

1107 Assert(!target_is_pg_class);

1108

1109 swaptemp = relform1->relfilenode;

1110 relform1->relfilenode = relform2->relfilenode;

1111 relform2->relfilenode = swaptemp;

1112

1113 swaptemp = relform1->reltablespace;

1114 relform1->reltablespace = relform2->reltablespace;

1115 relform2->reltablespace = swaptemp;

1116

1117 swaptemp = relform1->relam;

1118 relform1->relam = relform2->relam;

1119 relform2->relam = swaptemp;

1120

1121 swptmpchr = relform1->relpersistence;

1122 relform1->relpersistence = relform2->relpersistence;

1123 relform2->relpersistence = swptmpchr;

1124

1125

1126 if (!swap_toast_by_content)

1127 {

1128 swaptemp = relform1->reltoastrelid;

1129 relform1->reltoastrelid = relform2->reltoastrelid;

1130 relform2->reltoastrelid = swaptemp;

1131 }

1132 }

1133 else

1134 {

1135

1136

1137

1138

1141 elog(ERROR, "cannot swap mapped relation \"%s\" with non-mapped relation",

1142 NameStr(relform1->relname));

1143

1144

1145

1146

1147

1148

1149

1150

1151 if (relform1->reltablespace != relform2->reltablespace)

1152 elog(ERROR, "cannot change tablespace of mapped relation \"%s\"",

1153 NameStr(relform1->relname));

1154 if (relform1->relpersistence != relform2->relpersistence)

1155 elog(ERROR, "cannot change persistence of mapped relation \"%s\"",

1156 NameStr(relform1->relname));

1157 if (relform1->relam != relform2->relam)

1158 elog(ERROR, "cannot change access method of mapped relation \"%s\"",

1159 NameStr(relform1->relname));

1160 if (!swap_toast_by_content &&

1161 (relform1->reltoastrelid || relform2->reltoastrelid))

1162 elog(ERROR, "cannot swap toast by links for mapped relation \"%s\"",

1163 NameStr(relform1->relname));

1164

1165

1166

1167

1170 elog(ERROR, "could not find relation mapping for relation \"%s\", OID %u",

1171 NameStr(relform1->relname), r1);

1174 elog(ERROR, "could not find relation mapping for relation \"%s\", OID %u",

1175 NameStr(relform2->relname), r2);

1176

1177

1178

1179

1180

1183

1184

1185 *mapped_tables++ = r2;

1186 }

1187

1188

1189

1190

1191

1192

1193 {

1195 rel2;

1196

1205 }

1206

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216 if (relform1->relkind != RELKIND_INDEX)

1217 {

1220 relform1->relfrozenxid = frozenXid;

1221 relform1->relminmxid = cutoffMulti;

1222 }

1223

1224

1225 {

1226 int32 swap_pages;

1228 int32 swap_allvisible;

1229 int32 swap_allfrozen;

1230

1231 swap_pages = relform1->relpages;

1232 relform1->relpages = relform2->relpages;

1233 relform2->relpages = swap_pages;

1234

1235 swap_tuples = relform1->reltuples;

1236 relform1->reltuples = relform2->reltuples;

1237 relform2->reltuples = swap_tuples;

1238

1239 swap_allvisible = relform1->relallvisible;

1240 relform1->relallvisible = relform2->relallvisible;

1241 relform2->relallvisible = swap_allvisible;

1242

1243 swap_allfrozen = relform1->relallfrozen;

1244 relform1->relallfrozen = relform2->relallfrozen;

1245 relform2->relallfrozen = swap_allfrozen;

1246 }

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257 if (!target_is_pg_class)

1258 {

1260

1263 indstate);

1265 indstate);

1267 }

1268 else

1269 {

1270

1273 }

1274

1275

1276

1277

1278

1279

1280 if (relam1 != relam2)

1281 {

1283 r1,

1284 AccessMethodRelationId,

1285 relam1,

1286 relam2) != 1)

1287 elog(ERROR, "could not change access method dependency for relation \"%s.%s\"",

1291 r2,

1292 AccessMethodRelationId,

1293 relam2,

1294 relam1) != 1)

1295 elog(ERROR, "could not change access method dependency for relation \"%s.%s\"",

1298 }

1299

1300

1301

1302

1303

1308

1309

1310

1311

1312

1313 if (relform1->reltoastrelid || relform2->reltoastrelid)

1314 {

1315 if (swap_toast_by_content)

1316 {

1317 if (relform1->reltoastrelid && relform2->reltoastrelid)

1318 {

1319

1321 relform2->reltoastrelid,

1322 target_is_pg_class,

1323 swap_toast_by_content,

1324 is_internal,

1325 frozenXid,

1326 cutoffMulti,

1327 mapped_tables);

1328 }

1329 else

1330 {

1331

1332 elog(ERROR, "cannot swap toast files by content when there's only one");

1333 }

1334 }

1335 else

1336 {

1337

1338

1339

1340

1341

1342

1343

1344

1345

1346

1347

1349 toastobject;

1350 long count;

1351

1352

1353

1354

1355

1356

1357

1359 elog(ERROR, "cannot swap toast files by links for system catalogs");

1360

1361

1362 if (relform1->reltoastrelid)

1363 {

1365 relform1->reltoastrelid,

1366 false);

1367 if (count != 1)

1368 elog(ERROR, "expected one dependency record for TOAST table, found %ld",

1369 count);

1370 }

1371 if (relform2->reltoastrelid)

1372 {

1374 relform2->reltoastrelid,

1375 false);

1376 if (count != 1)

1377 elog(ERROR, "expected one dependency record for TOAST table, found %ld",

1378 count);

1379 }

1380

1381

1382 baseobject.classId = RelationRelationId;

1384 toastobject.classId = RelationRelationId;

1386

1387 if (relform1->reltoastrelid)

1388 {

1390 toastobject.objectId = relform1->reltoastrelid;

1393 }

1394

1395 if (relform2->reltoastrelid)

1396 {

1398 toastobject.objectId = relform2->reltoastrelid;

1401 }

1402 }

1403 }

1404

1405

1406

1407

1408

1409

1410 if (swap_toast_by_content &&

1411 relform1->relkind == RELKIND_TOASTVALUE &&

1412 relform2->relkind == RELKIND_TOASTVALUE)

1413 {

1414 Oid toastIndex1,

1415 toastIndex2;

1416

1417

1422

1424 toastIndex2,

1425 target_is_pg_class,

1426 swap_toast_by_content,

1427 is_internal,

1430 mapped_tables);

1431 }

1432

1433

1436

1438}

1439

1440

1441

1442

1443

1444void

1446 bool is_system_catalog,

1447 bool swap_toast_by_content,

1448 bool check_constraints,

1449 bool is_internal,

1452 char newrelpersistence)

1453{

1455 Oid mapped_tables[4];

1456 int reindex_flags;

1458 int i;

1459

1460

1463

1464

1465 memset(mapped_tables, 0, sizeof(mapped_tables));

1466

1467

1468

1469

1470

1472 (OIDOldHeap == RelationRelationId),

1473 swap_toast_by_content, is_internal,

1474 frozenXid, cutoffMulti, mapped_tables);

1475

1476

1477

1478

1479

1480 if (is_system_catalog)

1482

1483

1484

1485

1486

1487

1488

1489

1490

1491

1492

1493

1494

1495

1496

1497

1499 if (check_constraints)

1501

1502

1503

1504

1505

1506 if (newrelpersistence == RELPERSISTENCE_UNLOGGED)

1508 else if (newrelpersistence == RELPERSISTENCE_PERMANENT)

1510

1511

1514

1515 reindex_relation(NULL, OIDOldHeap, reindex_flags, &reindex_params);

1516

1517

1520

1521

1522

1523

1524

1525

1526

1527

1528

1529

1530

1531

1532

1533 if (OIDOldHeap == RelationRelationId)

1534 {

1538

1540

1543 elog(ERROR, "cache lookup failed for relation %u", OIDOldHeap);

1545

1546 relform->relfrozenxid = frozenXid;

1547 relform->relminmxid = cutoffMulti;

1548

1550

1552 }

1553

1554

1555 object.classId = RelationRelationId;

1556 object.objectId = OIDNewHeap;

1557 object.objectSubId = 0;

1558

1559

1560

1561

1562

1564

1565

1566

1567

1568

1569

1570

1571

1572

1575

1576

1577

1578

1579

1580

1581

1582

1583

1584

1585

1586 if (!swap_toast_by_content)

1587 {

1589

1592 {

1593 Oid toastidx;

1595

1596

1599

1600

1602 OIDOldHeap);

1604 NewToastName, true, false);

1605

1606

1608 OIDOldHeap);

1609

1611 NewToastName, true, true);

1612

1613

1614

1615

1616

1617

1620 }

1622 }

1623

1624

1625 if (!is_system_catalog)

1626 {

1628

1632 }

1633}

1634

1635

1636

1637

1638

1639

1640

1641

1642static List *

1644{

1652

1653

1654

1655

1656

1659 Anum_pg_index_indisclustered,

1664 {

1666

1668

1670 continue;

1671

1672

1674

1678 rtcs = lappend(rtcs, rtc);

1679

1681 }

1683

1685

1686 return rtcs;

1687}

1688

1689

1690

1691

1692

1693

1694

1695

1696static List *

1698{

1699 List *inhoids;

1703

1704

1706

1707 foreach(lc, inhoids)

1708 {

1712

1713

1715 continue;

1716

1717

1718

1719

1720

1721

1722

1724 continue;

1725

1726

1728

1732 rtcs = lappend(rtcs, rtc);

1733

1735 }

1736

1737 return rtcs;

1738}

1739

1740

1741

1742

1743

1744static bool

1746{

1748 return true;

1749

1751 (errmsg("permission denied to cluster \"%s\", skipping it",

1753 return false;

1754}

AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)

void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)

void pgstat_progress_update_param(int index, int64 val)

void pgstat_progress_end_command(void)

@ PROGRESS_COMMAND_CLUSTER

#define RelationGetNumberOfBlocks(reln)

#define PG_USED_FOR_ASSERTS_ONLY

TransactionId MultiXactId

#define OidIsValid(objectId)

bool IsSystemRelation(Relation relation)

bool IsSystemClass(Oid relid, Form_pg_class reltuple)

static void copy_table_data(Relation NewHeap, Relation OldHeap, Relation OldIndex, bool verbose, bool *pSwapToastByContent, TransactionId *pFreezeXid, MultiXactId *pCutoffMulti)

void check_index_is_clusterable(Relation OldHeap, Oid indexOid, LOCKMODE lockmode)

void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, bool is_system_catalog, bool swap_toast_by_content, bool check_constraints, bool is_internal, TransactionId frozenXid, MultiXactId cutoffMulti, char newrelpersistence)

static List * get_tables_to_cluster(MemoryContext cluster_context)

void cluster_rel(Relation OldHeap, Oid indexOid, ClusterParams *params)

static List * get_tables_to_cluster_partitioned(MemoryContext cluster_context, Oid indexOid)

static bool cluster_is_permitted_for_relation(Oid relid, Oid userid)

static void cluster_multiple_rels(List *rtcs, ClusterParams *params)

Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, char relpersistence, LOCKMODE lockmode)

static void rebuild_relation(Relation OldHeap, Relation index, bool verbose)

void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)

void mark_index_clustered(Relation rel, Oid indexOid, bool is_internal)

static void swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, bool swap_toast_by_content, bool is_internal, TransactionId frozenXid, MultiXactId cutoffMulti, Oid *mapped_tables)

#define CLUOPT_RECHECK_ISCLUSTERED

bool defGetBoolean(DefElem *def)

void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)

#define PERFORM_DELETION_INTERNAL

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

int NewGUCNestLevel(void)

void RestrictSearchPath(void)

void AtEOXact_GUC(bool isCommit, int nestLevel)

Assert(PointerIsAligned(start, uint64))

void RelationClearMissing(Relation rel)

Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid reltypeid, Oid reloftypeid, Oid ownerid, Oid accessmtd, TupleDesc tupdesc, List *cooked_constraints, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, bool allow_system_table_mods, bool is_internal, Oid relrewrite, ObjectAddress *typaddress)

HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)

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

void heap_freetuple(HeapTuple htup)

#define HeapTupleIsValid(tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

Oid IndexGetRelation(Oid indexId, bool missing_ok)

bool reindex_relation(const ReindexStmt *stmt, Oid relid, int flags, const ReindexParams *params)

#define REINDEX_REL_FORCE_INDEXES_UNLOGGED

#define REINDEX_REL_SUPPRESS_INDEX_USE

#define REINDEX_REL_FORCE_INDEXES_PERMANENT

#define REINDEX_REL_CHECK_CONSTRAINTS

void index_close(Relation relation, LOCKMODE lockmode)

Relation index_open(Oid relationId, LOCKMODE lockmode)

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

void CatalogCloseIndexes(CatalogIndexState indstate)

CatalogIndexState CatalogOpenIndexes(Relation heapRel)

void CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup, CatalogIndexState indstate)

void CacheInvalidateCatalog(Oid catalogId)

void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)

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

void LockRelationOid(Oid relid, LOCKMODE lockmode)

bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)

bool CheckRelationOidLockedByMe(Oid relid, LOCKMODE lockmode, bool orstronger)

#define AccessExclusiveLock

char * get_rel_name(Oid relid)

char get_rel_relkind(Oid relid)

Oid get_rel_namespace(Oid relid)

bool get_index_isclustered(Oid index_oid)

char * get_namespace_name(Oid nspid)

Oid get_relname_relid(const char *relname, Oid relnamespace)

void MemoryContextDelete(MemoryContext context)

MemoryContext PortalContext

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define SECURITY_RESTRICTED_OPERATION

#define CHECK_FOR_INTERRUPTS()

void GetUserIdAndSecContext(Oid *userid, int *sec_context)

void SetUserIdAndSecContext(Oid userid, int sec_context)

bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)

#define MultiXactIdIsValid(multi)

#define InvalidMultiXactId

Oid LookupCreationNamespace(const char *nspname)

Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)

#define InvokeObjectPostAlterHookArg(classId, objectId, subId, auxiliaryId, is_internal)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

int parser_errposition(ParseState *pstate, int location)

FormData_pg_class * Form_pg_class

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)

FormData_pg_index * Form_pg_index

List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)

const char * pg_rusage_show(const PGRUsage *ru0)

void pg_rusage_init(PGRUsage *ru0)

bool plan_cluster_use_sort(Oid tableOid, Oid indexOid)

static Datum BoolGetDatum(bool X)

static Datum ObjectIdGetDatum(Oid X)

void TransferPredicateLocksToHeapRelation(Relation relation)

#define PROGRESS_CLUSTER_PHASE

#define PROGRESS_CLUSTER_COMMAND_VACUUM_FULL

#define PROGRESS_CLUSTER_PHASE_REBUILD_INDEX

#define PROGRESS_CLUSTER_COMMAND_CLUSTER

#define PROGRESS_CLUSTER_PHASE_FINAL_CLEANUP

#define PROGRESS_CLUSTER_COMMAND

#define PROGRESS_CLUSTER_PHASE_SWAP_REL_FILES

#define RelationGetRelid(relation)

#define RelationGetDescr(relation)

#define RelationIsMapped(relation)

#define RelationGetRelationName(relation)

#define RelationIsPopulated(relation)

#define RELATION_IS_OTHER_TEMP(relation)

#define RelationGetNamespace(relation)

List * RelationGetIndexList(Relation relation)

void RelationAssumeNewRelfilelocator(Relation relation)

void RelationMapRemoveMapping(Oid relationId)

RelFileNumber RelationMapOidToFilenumber(Oid relationId, bool shared)

void RelationMapUpdateMap(Oid relationId, RelFileNumber fileNumber, bool shared, bool immediate)

#define RelFileNumberIsValid(relnumber)

void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)

Snapshot GetTransactionSnapshot(void)

void PushActiveSnapshot(Snapshot snapshot)

void PopActiveSnapshot(void)

void relation_close(Relation relation, LOCKMODE lockmode)

Relation relation_open(Oid relationId, LOCKMODE lockmode)

#define BTEqualStrategyNumber

struct IndexAmRoutine * rd_indam

SubTransactionId rd_firstRelfilelocatorSubid

struct HeapTupleData * rd_indextuple

SubTransactionId rd_newRelfilelocatorSubid

SubTransactionId rd_createSubid

TransactionId FreezeLimit

TransactionId relfrozenxid

MultiXactId MultiXactCutoff

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

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

#define SearchSysCacheCopy1(cacheId, key1)

#define SearchSysCacheExists1(cacheId, key1)

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, struct ScanKeyData *key)

static void table_endscan(TableScanDesc scan)

static void table_relation_copy_for_cluster(Relation OldTable, Relation NewTable, Relation OldIndex, bool use_sort, TransactionId OldestXmin, TransactionId *xid_cutoff, MultiXactId *multi_cutoff, double *num_tuples, double *tups_vacuumed, double *tups_recently_dead)

void ResetRelRewrite(Oid myrelid)

void CheckTableNotInUse(Relation rel, const char *stmt)

void RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal, bool is_index)

void RangeVarCallbackMaintainsTable(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)

Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock)

void NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, Oid OIDOldToast)

bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)

#define InvalidTransactionId

#define TransactionIdIsValid(xid)

#define TransactionIdIsNormal(xid)

bool vacuum_get_cutoffs(Relation rel, const VacuumParams *params, struct VacuumCutoffs *cutoffs)

void CommandCounterIncrement(void)

void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)

void StartTransactionCommand(void)

void CommitTransactionCommand(void)