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)