PostgreSQL Source Code: src/backend/commands/indexcmds.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
17
63#include "utils/fmgroids.h"
74
75
76
80 Oid *typeOids,
81 Oid *collationOids,
82 Oid *opclassOids,
83 Datum *opclassOptions,
84 int16 *colOptions,
85 const List *attList,
86 const List *exclusionOpNames,
87 Oid relId,
88 const char *accessMethodName,
89 Oid accessMethodId,
90 bool amcanorder,
91 bool isconstraint,
92 bool iswithoutoverlaps,
93 Oid ddl_userid,
94 int ddl_sec_context,
95 int *ddl_save_nestlevel);
97 const List *colnames, const List *exclusionOpNames,
98 bool primary, bool isconstraint);
102 bool isTopLevel);
104 Oid relId, Oid oldRelId, void *arg);
106 bool isTopLevel);
115 Oid relationOid,
119
120
121
122
124{
127};
128
129
130
131
133{
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177bool
179 const char *accessMethodName,
180 const List *attributeList,
181 const List *exclusionOpNames,
182 bool isWithoutOverlaps)
183{
184 bool isconstraint;
185 Oid *typeIds;
186 Oid *collationIds;
187 Oid *opclassIds;
188 Datum *opclassOptions;
189 Oid accessMethodId;
190 Oid relationId;
195 bool amcanorder;
196 bool amsummarizing;
197 int16 *coloptions;
199 int numberOfAttributes;
200 int old_natts;
201 bool ret = true;
205 int i;
207
208
210
211
212
213
214
215 isconstraint = false;
216
217 numberOfAttributes = list_length(attributeList);
218 Assert(numberOfAttributes > 0);
220
221
225 (errcode(ERRCODE_UNDEFINED_OBJECT),
226 errmsg("access method \"%s\" does not exist",
227 accessMethodName)));
229 accessMethodId = accessMethodForm->oid;
232
235
236
237
238
239
240
241
242
243
244 indexInfo = makeIndexInfo(numberOfAttributes, numberOfAttributes,
245 accessMethodId, NIL, NIL, false, false,
246 false, false, amsummarizing, isWithoutOverlaps);
253 typeIds, collationIds, opclassIds, opclassOptions,
254 coloptions, attributeList,
255 exclusionOpNames, relationId,
256 accessMethodName, accessMethodId,
257 amcanorder, isconstraint, isWithoutOverlaps, InvalidOid,
258 0, NULL);
259
260
263 elog(ERROR, "cache lookup failed for index %u", oldId);
265
266
267
268
269
270 if (!(heap_attisnull(tuple, Anum_pg_index_indpred, NULL) &&
271 heap_attisnull(tuple, Anum_pg_index_indexprs, NULL) &&
272 indexForm->indisvalid))
273 {
275 return false;
276 }
277
278
279 old_natts = indexForm->indnkeyatts;
280 Assert(old_natts == numberOfAttributes);
281
284
287
288 ret = (memcmp(old_indclass->values, opclassIds, old_natts * sizeof(Oid)) == 0 &&
289 memcmp(old_indcollation->values, collationIds, old_natts * sizeof(Oid)) == 0);
290
292
293 if (!ret)
294 return false;
295
296
298 for (i = 0; i < old_natts; i++)
299 {
302 {
303 ret = false;
304 break;
305 }
306 }
307
308
309 if (ret)
310 {
312
313 for (i = 0; i < old_natts; i++)
315
317
318 pfree(oldOpclassOptions);
319 }
320
321
323 {
324 Oid *old_operators,
325 *old_procs;
327
330 old_natts * sizeof(Oid)) == 0;
331
332
333 if (ret)
334 {
335 for (i = 0; i < old_natts && ret; i++)
336 {
337 Oid left,
338 right;
339
341 if ((IsPolymorphicType(left) || IsPolymorphicType(right)) &&
343 {
344 ret = false;
345 break;
346 }
347 }
348 }
349 }
350
352 return ret;
353}
354
355
356
357
358
359
360
361static bool
363{
364 int i;
366
367 if (!opts1 && !opts2)
368 return true;
369
371 for (i = 0; i < natts; i++)
372 {
373 Datum opt1 = opts1 ? opts1[i] : (Datum) 0;
374 Datum opt2 = opts2 ? opts2[i] : (Datum) 0;
375
376 if (opt1 == (Datum) 0)
377 {
378 if (opt2 == (Datum) 0)
379 continue;
380 else
381 return false;
382 }
383 else if (opt2 == (Datum) 0)
384 return false;
385
386
387
388
389
390
392 return false;
393 }
394
395 return true;
396}
397
398
399
400
401
402
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
428
429
430
431
432
433
434void
436{
437 int n_old_snapshots;
438 int i;
440
444 &n_old_snapshots);
447
448 for (i = 0; i < n_old_snapshots; i++)
449 {
451 continue;
452
453 if (i > 0)
454 {
455
457 int n_newer_snapshots;
458 int j;
459 int k;
460
462 true, false,
465 &n_newer_snapshots);
466 for (j = i; j < n_old_snapshots; j++)
467 {
469 continue;
470 for (k = 0; k < n_newer_snapshots; k++)
471 {
473 newer_snapshots[k]))
474 break;
475 }
476 if (k >= n_newer_snapshots)
478 }
479 pfree(newer_snapshots);
480 }
481
483 {
484
486 {
488
489 if (holder)
491 holder->pid);
492 }
494 }
495
498 }
499}
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
544 Oid indexRelationId,
545 Oid parentIndexId,
546 Oid parentConstraintId,
547 int total_parts,
548 bool is_alter_table,
549 bool check_rights,
550 bool check_not_in_use,
551 bool skip_build,
552 bool quiet)
553{
554 bool concurrent;
555 char *indexRelationName;
556 char *accessMethodName;
557 Oid *typeIds;
558 Oid *collationIds;
559 Oid *opclassIds;
560 Datum *opclassOptions;
561 Oid accessMethodId;
562 Oid namespaceId;
563 Oid tablespaceId;
565 List *indexColNames;
566 List *allIndexParams;
571 bool amcanorder;
572 bool amissummarizing;
574 bool exclusion;
575 bool partitioned;
576 bool safe_index;
577 Datum reloptions;
578 int16 *coloptions;
582 int numberOfAttributes;
583 int numberOfKeyAttributes;
590 Oid root_save_userid;
591 int root_save_sec_context;
592 int root_save_nestlevel;
593
595
597
598
599
600
601
602
603 if (stmt->reset_default_tblspc)
607
608
609
610
611
612
613
614
616 concurrent = true;
617 else
618 concurrent = false;
619
620
621
622
623
625 {
628 concurrent ?
631 }
632
633
634
635
638
639
640
641
643
644
645
646
647
648
649
650
651
653 stmt->indexIncludingParams);
654 numberOfAttributes = list_length(allIndexParams);
655
656 if (numberOfKeyAttributes <= 0)
658 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
659 errmsg("must specify at least one column")));
662 (errcode(ERRCODE_TOO_MANY_COLUMNS),
663 errmsg("cannot use more than %d columns in an index",
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
683
684
685
686
687
688
692
694
695
696
697
698
699 exclusion = stmt->excludeOpNames || stmt->iswithoutoverlaps;
700
701
702 switch (rel->rd_rel->relkind)
703 {
704 case RELKIND_RELATION:
705 case RELKIND_MATVIEW:
706 case RELKIND_PARTITIONED_TABLE:
707
708 break;
709 default:
711 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
712 errmsg("cannot create index on relation \"%s\"",
715 break;
716 }
717
718
719
720
721
722
723
724
725
726 partitioned = rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE;
727 if (partitioned)
728 {
729
730
731
732
733
734
735 if (stmt->concurrent)
737 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
738 errmsg("cannot create index on partitioned table \"%s\" concurrently",
740 }
741
742
743
744
747 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
748 errmsg("cannot create indexes on temporary tables of other sessions")));
749
750
751
752
753
754
755
756 if (check_not_in_use)
758
759
760
761
762
763
764
766 {
768
769 aclresult = object_aclcheck(NamespaceRelationId, namespaceId, root_save_userid,
774 }
775
776
777
778
779
780 if (stmt->tableSpace)
781 {
785 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
786 errmsg("cannot specify default tablespace for partitioned relations")));
787 }
788 else
789 {
791 partitioned);
792
793 }
794
795
796 if (check_rights &&
798 {
800
801 aclresult = object_aclcheck(TableSpaceRelationId, tablespaceId, root_save_userid,
806 }
807
808
809
810
811
812
813 if (rel->rd_rel->relisshared)
814 tablespaceId = GLOBALTABLESPACE_OID;
815 else if (tablespaceId == GLOBALTABLESPACE_OID)
817 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
818 errmsg("only shared relations can be placed in pg_global tablespace")));
819
820
821
822
824
825
826
827
828 indexRelationName = stmt->idxname;
829 if (indexRelationName == NULL)
831 namespaceId,
832 indexColNames,
833 stmt->excludeOpNames,
834 stmt->primary,
835 stmt->isconstraint);
836
837
838
839
840 accessMethodName = stmt->accessMethod;
843 {
844
845
846
847
848 if (strcmp(accessMethodName, "rtree") == 0)
849 {
851 (errmsg("substituting access method \"gist\" for obsolete method \"rtree\"")));
852 accessMethodName = "gist";
854 }
855
858 (errcode(ERRCODE_UNDEFINED_OBJECT),
859 errmsg("access method \"%s\" does not exist",
860 accessMethodName)));
861 }
863 accessMethodId = accessMethodForm->oid;
865
867 accessMethodId);
868
871 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
872 errmsg("access method \"%s\" does not support unique indexes",
873 accessMethodName)));
876 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
877 errmsg("access method \"%s\" does not support included columns",
878 accessMethodName)));
879 if (numberOfKeyAttributes > 1 && !amRoutine->amcanmulticol)
881 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
882 errmsg("access method \"%s\" does not support multicolumn indexes",
883 accessMethodName)));
884 if (exclusion && amRoutine->amgettuple == NULL)
886 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
887 errmsg("access method \"%s\" does not support exclusion constraints",
888 accessMethodName)));
889 if (stmt->iswithoutoverlaps && strcmp(accessMethodName, "gist") != 0)
891 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
892 errmsg("access method \"%s\" does not support WITHOUT OVERLAPS constraints",
893 accessMethodName)));
894
896 amoptions = amRoutine->amoptions;
898
899 pfree(amRoutine);
901
902
903
904
905 if (stmt->whereClause)
907
908
909
910
912 NULL, NULL, false, false);
913
915
916
917
918
919
920
922 numberOfKeyAttributes,
923 accessMethodId,
924 NIL,
926 stmt->unique,
927 stmt->nulls_not_distinct,
928 !concurrent,
929 concurrent,
930 amissummarizing,
931 stmt->iswithoutoverlaps);
932
939 typeIds, collationIds, opclassIds, opclassOptions,
940 coloptions, allIndexParams,
941 stmt->excludeOpNames, tableId,
942 accessMethodName, accessMethodId,
943 amcanorder, stmt->isconstraint, stmt->iswithoutoverlaps,
944 root_save_userid, root_save_sec_context,
945 &root_save_nestlevel);
946
947
948
949
950 if (stmt->primary)
952
953
954
955
956
957
958
959
960
961
962
963 if (partitioned && (stmt->unique || exclusion))
964 {
966 const char *constraint_type;
967 int i;
968
969 if (stmt->primary)
970 constraint_type = "PRIMARY KEY";
971 else if (stmt->unique)
972 constraint_type = "UNIQUE";
973 else if (stmt->excludeOpNames)
974 constraint_type = "EXCLUDE";
975 else
976 {
977 elog(ERROR, "unknown constraint type");
978 constraint_type = NULL;
979 }
980
981
982
983
984
985 for (i = 0; i < key->partnatts; i++)
986 {
987 bool found = false;
988 int eq_strategy;
989 Oid ptkey_eqop;
990 int j;
991
992
993
994
995
996
997
1000 else
1002
1006 eq_strategy);
1008 elog(ERROR, "missing operator %d(%u,%u) in partition opfamily %u",
1009 eq_strategy, key->partopcintype[i], key->partopcintype[i],
1011
1012
1013
1014
1015
1016 if (key->partattrs[i] == 0)
1018 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1019 errmsg("unsupported %s constraint with partition key definition",
1020 constraint_type),
1021 errdetail("%s constraints cannot be used when partition keys include expressions.",
1022 constraint_type)));
1023
1024
1026 {
1028 {
1029
1030
1031
1032
1033 Oid idx_opfamily;
1034 Oid idx_opcintype;
1035
1036 if (key->partcollation[i] != collationIds[j])
1037 continue;
1038
1040 &idx_opfamily,
1041 &idx_opcintype))
1042 {
1044
1045 if (stmt->unique && ->iswithoutoverlaps)
1047 idx_opcintype,
1048 idx_opcintype,
1050 else if (exclusion)
1052
1053 if (!idx_eqop)
1055 errcode(ERRCODE_UNDEFINED_OBJECT),
1056 errmsg("could not identify an equality operator for type %s", format_type_be(idx_opcintype)),
1057 errdetail("There is no suitable operator in operator family \"%s\" for access method \"%s\".",
1059
1060 if (ptkey_eqop == idx_eqop)
1061 {
1062 found = true;
1063 break;
1064 }
1065 else if (exclusion)
1066 {
1067
1068
1069
1070
1071
1072
1074
1076 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1077 errmsg("cannot match partition key to index on column \"%s\" using non-equal operator \"%s\"",
1080 }
1081 }
1082 }
1083 }
1084
1085 if (!found)
1086 {
1088
1092 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1093 errmsg("unique constraint on partitioned table must include all partitioning columns"),
1094 errdetail("%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key.",
1096 NameStr(att->attname))));
1097 }
1098 }
1099 }
1100
1101
1102
1103
1104
1105
1106
1107
1108
1110 {
1112
1113 if (attno < 0)
1115 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1116 errmsg("index creation on system columns is not supported")));
1117
1118
1121 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1122 stmt->primary ?
1123 errmsg("primary keys on virtual generated columns are not supported") :
1124 stmt->isconstraint ?
1125 errmsg("unique constraints on virtual generated columns are not supported") :
1126 errmsg("indexes on virtual generated columns are not supported"));
1127 }
1128
1129
1130
1131
1132
1134 {
1136 int j;
1137
1140
1142 {
1144 indexattrs))
1146 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1147 errmsg("index creation on system columns is not supported")));
1148 }
1149
1150
1151
1152
1153
1154
1155 j = -1;
1157 {
1159
1162 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1163 stmt->isconstraint ?
1164 errmsg("unique constraints on virtual generated columns are not supported") :
1165 errmsg("indexes on virtual generated columns are not supported")));
1166 }
1167 }
1168
1169
1172
1173
1174
1175
1176
1177 if (stmt->isconstraint && !quiet)
1178 {
1179 const char *constraint_type;
1180
1181 if (stmt->primary)
1182 constraint_type = "PRIMARY KEY";
1183 else if (stmt->unique)
1184 constraint_type = "UNIQUE";
1185 else if (stmt->excludeOpNames)
1186 constraint_type = "EXCLUDE";
1187 else
1188 {
1189 elog(ERROR, "unknown constraint type");
1190 constraint_type = NULL;
1191 }
1192
1194 (errmsg_internal("%s %s will create implicit index \"%s\" for table \"%s\"",
1195 is_alter_table ? "ALTER TABLE / ADD" : "CREATE TABLE /",
1196 constraint_type,
1198 }
1199
1200
1201
1202
1203
1205
1206
1207
1208
1209
1210
1211
1212 flags = constr_flags = 0;
1213 if (stmt->isconstraint)
1215 if (skip_build || concurrent || partitioned)
1217 if (stmt->if_not_exists)
1219 if (concurrent)
1221 if (partitioned)
1223 if (stmt->primary)
1225
1226
1227
1228
1229
1230 if (partitioned && stmt->relation && ->relation->inh)
1231 {
1233
1234 if (pd->nparts != 0)
1236 }
1237
1238 if (stmt->deferrable)
1240 if (stmt->initdeferred)
1242 if (stmt->iswithoutoverlaps)
1244
1245 indexRelationId =
1246 index_create(rel, indexRelationName, indexRelationId, parentIndexId,
1247 parentConstraintId,
1248 stmt->oldNumber, indexInfo, indexColNames,
1249 accessMethodId, tablespaceId,
1250 collationIds, opclassIds, opclassOptions,
1251 coloptions, NULL, reloptions,
1252 flags, constr_flags,
1254 &createdConstraintId);
1255
1256 ObjectAddressSet(address, RelationRelationId, indexRelationId);
1257
1259 {
1260
1261
1262
1263
1265
1266
1268
1270
1271
1274
1275 return address;
1276 }
1277
1278
1279
1280
1281
1282
1286
1287
1288 if (stmt->idxcomment != NULL)
1289 CreateComments(indexRelationId, RelationRelationId, 0,
1290 stmt->idxcomment);
1291
1292 if (partitioned)
1293 {
1295
1296
1297
1298
1299
1300
1301
1303 if ((->relation || stmt->relation->inh) && partdesc->nparts > 0)
1304 {
1305 int nparts = partdesc->nparts;
1307 bool invalidate_parent = false;
1310
1311
1312
1313
1314
1316 {
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330 if (total_parts < 0)
1331 {
1333
1334 total_parts = list_length(children) - 1;
1336 }
1337
1339 total_parts);
1340 }
1341
1342
1343 memcpy(part_oids, partdesc->oids, sizeof(Oid) * nparts);
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353 parentIndex = index_open(indexRelationId, lockmode);
1355
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366 for (int i = 0; i < nparts; i++)
1367 {
1368 Oid childRelid = part_oids[i];
1370 Oid child_save_userid;
1371 int child_save_sec_context;
1372 int child_save_nestlevel;
1373 List *childidxs;
1376 bool found = false;
1377
1378 childrel = table_open(childRelid, lockmode);
1379
1381 &child_save_sec_context);
1386
1387
1388
1389
1390
1391
1392 if (childrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1393 {
1394 if (stmt->unique || stmt->primary)
1396 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1397 errmsg("cannot create unique index on partitioned table \"%s\"",
1399 errdetail("Table \"%s\" contains partitions that are foreign tables.",
1401
1404 child_save_sec_context);
1406 continue;
1407 }
1408
1410 attmap =
1412 parentDesc,
1413 false);
1414
1415 foreach(cell, childidxs)
1416 {
1420
1421
1423 continue;
1424
1425 cldidx = index_open(cldidxid, lockmode);
1432 attmap))
1433 {
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445 if (createdConstraintId != InvalidOid)
1446 {
1447 cldConstrOid =
1449 cldidxid);
1451 {
1453 continue;
1454 }
1455 }
1456
1457
1459 if (createdConstraintId != InvalidOid)
1461 createdConstraintId,
1462 childRelid);
1463
1464 if (!cldidx->rd_index->indisvalid)
1465 invalidate_parent = true;
1466
1467 found = true;
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1479
1480
1482 break;
1483 }
1484
1486 }
1487
1491 child_save_sec_context);
1493
1494
1495
1496
1497 if (!found)
1498 {
1501
1502
1503
1504
1505
1506
1507
1508
1510 parentIndex,
1511 attmap,
1512 NULL);
1513
1514
1515
1516
1517
1520 root_save_sec_context);
1521 childAddr =
1524 indexRelationId,
1525 createdConstraintId,
1526 -1,
1527 is_alter_table, check_rights,
1528 check_not_in_use,
1529 skip_build, quiet);
1531 child_save_sec_context);
1532
1533
1534
1535
1536
1537
1539 invalidate_parent = true;
1540 }
1541
1543 }
1544
1546
1547
1548
1549
1550
1551
1552 if (invalidate_parent)
1553 {
1556 newtup;
1557
1561 elog(ERROR, "cache lookup failed for index %u",
1562 indexRelationId);
1569
1570
1571
1572
1573
1575 }
1576 }
1577
1578
1579
1580
1581
1587 else
1588 {
1589
1591 }
1592
1593 return address;
1594 }
1595
1598
1599 if (!concurrent)
1600 {
1601
1603
1604
1605
1606
1607
1610 else
1612
1613 return address;
1614 }
1615
1616
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1643
1647
1648
1649 if (safe_index)
1651
1652
1653
1654
1655
1656 {
1657 const int progress_cols[] = {
1660 };
1661 const int64 progress_vals[] = {
1662 indexRelationId,
1664 };
1665
1667 }
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1707
1708
1710
1711
1713
1714
1715
1716
1719
1720
1721 if (safe_index)
1723
1724
1725
1726
1727
1728
1729
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1751
1752
1753
1754
1756
1757
1758
1759
1760
1761
1762
1763
1764 limitXmin = snapshot->xmin;
1765
1768
1769
1770
1771
1772
1773
1774
1775
1776
1779
1780
1781 if (safe_index)
1783
1784
1786
1787
1788
1789
1790
1791
1792
1796
1797
1798
1799
1800
1802
1803
1804
1805
1807
1809
1810
1811
1812
1813
1814
1815
1816
1817
1819
1820
1821
1822
1824
1826
1827 return address;
1828}
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842static void
1844{
1845
1846
1847
1848
1849
1850
1851
1852
1853
1856 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1857 errmsg("functions in index predicate must be marked IMMUTABLE")));
1858}
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869static void
1871 Oid *typeOids,
1872 Oid *collationOids,
1873 Oid *opclassOids,
1874 Datum *opclassOptions,
1875 int16 *colOptions,
1876 const List *attList,
1877 const List *exclusionOpNames,
1878 Oid relId,
1879 const char *accessMethodName,
1880 Oid accessMethodId,
1881 bool amcanorder,
1882 bool isconstraint,
1883 bool iswithoutoverlaps,
1884 Oid ddl_userid,
1885 int ddl_sec_context,
1886 int *ddl_save_nestlevel)
1887{
1890 int attn;
1892 Oid save_userid;
1893 int save_sec_context;
1894
1895
1896 if (exclusionOpNames)
1897 {
1902 nextExclOp = list_head(exclusionOpNames);
1903 }
1904 else
1905 nextExclOp = NULL;
1906
1907
1908
1909
1910
1911
1912
1913 if (iswithoutoverlaps)
1914 {
1915 if (exclusionOpNames == NIL)
1916 {
1920 }
1921 nextExclOp = NULL;
1922 }
1923
1926
1927
1928
1929
1930 attn = 0;
1931 foreach(lc, attList)
1932 {
1934 Oid atttype;
1935 Oid attcollation;
1936
1937
1938
1939
1940 if (attribute->name != NULL)
1941 {
1942
1945
1949 {
1950
1951 if (isconstraint)
1953 (errcode(ERRCODE_UNDEFINED_COLUMN),
1954 errmsg("column \"%s\" named in key does not exist",
1955 attribute->name)));
1956 else
1958 (errcode(ERRCODE_UNDEFINED_COLUMN),
1959 errmsg("column \"%s\" does not exist",
1960 attribute->name)));
1961 }
1964 atttype = attform->atttypid;
1965 attcollation = attform->attcollation;
1967 }
1968 else
1969 {
1970
1971 Node *expr = attribute->expr;
1972
1973 Assert(expr != NULL);
1974
1975 if (attn >= nkeycols)
1977 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1978 errmsg("expressions are not supported in included columns")));
1981
1982
1983
1984
1985
1988
1991 {
1992
1993
1994
1995
1997 }
1998 else
1999 {
2002 expr);
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2018 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2019 errmsg("functions in index expression must be marked IMMUTABLE")));
2020 }
2021 }
2022
2023 typeOids[attn] = atttype;
2024
2025
2026
2027
2028
2029 if (attn >= nkeycols)
2030 {
2033 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2034 errmsg("including column does not support a collation")));
2037 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2038 errmsg("including column does not support an operator class")));
2041 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2042 errmsg("including column does not support ASC/DESC options")));
2045 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2046 errmsg("including column does not support NULLS FIRST/LAST options")));
2047
2049 opclassOptions[attn] = (Datum) 0;
2050 colOptions[attn] = 0;
2052 attn++;
2053
2054 continue;
2055 }
2056
2057
2058
2059
2060
2061
2063 {
2065 {
2068 }
2071 {
2075 }
2076 }
2077
2078
2079
2080
2081
2082
2083
2085 {
2088 (errcode(ERRCODE_INDETERMINATE_COLLATION),
2089 errmsg("could not determine which collation to use for index expression"),
2090 errhint("Use the COLLATE clause to set the collation explicitly.")));
2091 }
2092 else
2093 {
2096 (errcode(ERRCODE_DATATYPE_MISMATCH),
2097 errmsg("collations are not supported by type %s",
2099 }
2100
2101 collationOids[attn] = attcollation;
2102
2103
2104
2105
2106
2107
2108
2110 {
2113 }
2115 atttype,
2116 accessMethodName,
2117 accessMethodId);
2119 {
2123 }
2124
2125
2126
2127
2128 if (nextExclOp)
2129 {
2131 Oid opid;
2132 Oid opfamily;
2133 int strat;
2134
2135
2136
2137
2138
2139
2140
2141
2142
2144 {
2147 }
2150 {
2154 }
2155
2156
2157
2158
2159
2160
2163 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2164 errmsg("operator %s is not commutative",
2166 errdetail("Only commutative operators can be used in exclusion constraints.")));
2167
2168
2169
2170
2173 if (strat == 0)
2175 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2176 errmsg("operator %s is not a member of operator family \"%s\"",
2179 errdetail("The exclusion operator must be related to the index operator class for the constraint.")));
2180
2184 nextExclOp = lnext(exclusionOpNames, nextExclOp);
2185 }
2186 else if (iswithoutoverlaps)
2187 {
2190 Oid opid;
2191
2192 if (attn == nkeycols - 1)
2194 else
2200 }
2201
2202
2203
2204
2205
2206
2207 colOptions[attn] = 0;
2208 if (amcanorder)
2209 {
2210
2212 colOptions[attn] |= INDOPTION_DESC;
2213
2215 {
2217 colOptions[attn] |= INDOPTION_NULLS_FIRST;
2218 }
2220 colOptions[attn] |= INDOPTION_NULLS_FIRST;
2221 }
2222 else
2223 {
2224
2227 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2228 errmsg("access method \"%s\" does not support ASC/DESC options",
2229 accessMethodName)));
2232 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2233 errmsg("access method \"%s\" does not support NULLS FIRST/LAST options",
2234 accessMethodName)));
2235 }
2236
2237
2239 {
2240 Assert(attn < nkeycols);
2241
2242 opclassOptions[attn] =
2244 NULL, NULL, false, false);
2245 }
2246 else
2247 opclassOptions[attn] = (Datum) 0;
2248
2249 attn++;
2250 }
2251}
2252
2253
2254
2255
2256
2257
2258
2261 const char *accessMethodName, Oid accessMethodId)
2262{
2263 char *schemaname;
2264 char *opcname;
2267 Oid opClassId,
2268 opInputType;
2269
2270 if (opclass == NIL)
2271 {
2272
2276 (errcode(ERRCODE_UNDEFINED_OBJECT),
2277 errmsg("data type %s has no default operator class for access method \"%s\"",
2279 errhint("You must specify an operator class for the index or define a default operator class for the data type.")));
2280 return opClassId;
2281 }
2282
2283
2284
2285
2286
2287
2289
2290 if (schemaname)
2291 {
2292
2293 Oid namespaceId;
2294
2300 }
2301 else
2302 {
2303
2307 (errcode(ERRCODE_UNDEFINED_OBJECT),
2308 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
2309 opcname, accessMethodName)));
2311 }
2312
2315 (errcode(ERRCODE_UNDEFINED_OBJECT),
2316 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
2318
2319
2320
2321
2322
2324 opClassId = opform->oid;
2325 opInputType = opform->opcintype;
2326
2329 (errcode(ERRCODE_DATATYPE_MISMATCH),
2330 errmsg("operator class \"%s\" does not accept data type %s",
2332
2334
2335 return opClassId;
2336}
2337
2338
2339
2340
2341
2342
2343
2346{
2348 int nexact = 0;
2349 int ncompatible = 0;
2350 int ncompatiblepreferred = 0;
2356
2357
2359
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2375
2377 Anum_pg_opclass_opcmethod,
2380
2382 NULL, 1, skey);
2383
2385 {
2387
2388
2389 if (!opclass->opcdefault)
2390 continue;
2391 if (opclass->opcintype == type_id)
2392 {
2393 nexact++;
2394 result = opclass->oid;
2395 }
2396 else if (nexact == 0 &&
2398 {
2400 {
2401 ncompatiblepreferred++;
2402 result = opclass->oid;
2403 }
2404 else if (ncompatiblepreferred == 0)
2405 {
2406 ncompatible++;
2407 result = opclass->oid;
2408 }
2409 }
2410 }
2411
2413
2415
2416
2417 if (nexact > 1)
2420 errmsg("there are multiple default operator classes for data type %s",
2422
2423 if (nexact == 1 ||
2424 ncompatiblepreferred == 1 ||
2425 (ncompatiblepreferred == 0 && ncompatible == 1))
2426 return result;
2427
2429}
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446void
2449{
2450 Oid amid;
2451 Oid opfamily;
2452 Oid opcintype;
2453
2455
2457
2459
2461 {
2462
2463
2464
2468 errcode(ERRCODE_UNDEFINED_OBJECT),
2472 errdetail("Could not translate compare type %d for operator family \"%s\", input type %s, access method \"%s\".",
2474
2475
2476
2477
2478
2479
2481 rhstype = opcintype;
2483 }
2484
2487 errcode(ERRCODE_UNDEFINED_OBJECT),
2491 errdetail("There is no suitable operator in operator family \"%s\" for access method \"%s\".",
2493}
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517char *
2519{
2521 int overhead = 0;
2522 int availchars;
2523 int name1chars;
2524 int name2chars;
2525 int ndx;
2526
2527 name1chars = strlen(name1);
2528 if (name2)
2529 {
2530 name2chars = strlen(name2);
2531 overhead++;
2532 }
2533 else
2534 name2chars = 0;
2536 overhead += strlen(label) + 1;
2537
2538 availchars = NAMEDATALEN - 1 - overhead;
2539 Assert(availchars > 0);
2540
2541
2542
2543
2544
2545
2546 while (name1chars + name2chars > availchars)
2547 {
2548 if (name1chars > name2chars)
2549 name1chars--;
2550 else
2551 name2chars--;
2552 }
2553
2554 name1chars = pg_mbcliplen(name1, name1chars, name1chars);
2555 if (name2)
2556 name2chars = pg_mbcliplen(name2, name2chars, name2chars);
2557
2558
2559 name = palloc(name1chars + name2chars + overhead + 1);
2560 memcpy(name, name1, name1chars);
2561 ndx = name1chars;
2562 if (name2)
2563 {
2564 name[ndx++] = '_';
2565 memcpy(name + ndx, name2, name2chars);
2566 ndx += name2chars;
2567 }
2569 {
2570 name[ndx++] = '_';
2572 }
2573 else
2574 name[ndx] = '\0';
2575
2576 return name;
2577}
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603char *
2605 const char *label, Oid namespaceid,
2606 bool isconstraint)
2607{
2608 int pass = 0;
2611
2612
2614
2615 for (;;)
2616 {
2618
2620 {
2621 if (!isconstraint ||
2623 break;
2624 }
2625
2626
2628 snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
2629 }
2630
2632}
2633
2634
2635
2636
2637
2638
2639static char *
2641 const List *colnames, const List *exclusionOpNames,
2642 bool primary, bool isconstraint)
2643{
2644 char *indexname;
2645
2646 if (primary)
2647 {
2648
2650 NULL,
2651 "pkey",
2652 namespaceId,
2653 true);
2654 }
2655 else if (exclusionOpNames != NIL)
2656 {
2659 "excl",
2660 namespaceId,
2661 true);
2662 }
2663 else if (isconstraint)
2664 {
2667 "key",
2668 namespaceId,
2669 true);
2670 }
2671 else
2672 {
2675 "idx",
2676 namespaceId,
2677 false);
2678 }
2679
2680 return indexname;
2681}
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694static char *
2696{
2698 int buflen = 0;
2700
2701 buf[0] = '\0';
2702 foreach(lc, colnames)
2703 {
2704 const char *name = (const char *) lfirst(lc);
2705
2706 if (buflen > 0)
2707 buf[buflen++] = '_';
2708
2709
2710
2711
2712
2714 buflen += strlen(buf + buflen);
2716 break;
2717 }
2719}
2720
2721
2722
2723
2724
2725
2726
2727
2728static List *
2730{
2733
2734 foreach(lc, indexElems)
2735 {
2737 const char *origname;
2738 const char *curname;
2739 int i;
2741
2742
2744 origname = ielem->indexcolname;
2745 else if (ielem->name)
2746 origname = ielem->name;
2747 else
2748 origname = "expr";
2749
2750
2751 curname = origname;
2753 {
2755 char nbuf[32];
2756 int nlen;
2757
2758 foreach(lc2, result)
2759 {
2760 if (strcmp(curname, (char *) lfirst(lc2)) == 0)
2761 break;
2762 }
2763 if (lc2 == NULL)
2764 break;
2765
2767
2768
2769 nlen = pg_mbcliplen(origname, strlen(origname),
2771 memcpy(buf, origname, nlen);
2772 strcpy(buf + nlen, nbuf);
2773 curname = buf;
2774 }
2775
2776
2778 }
2779 return result;
2780}
2781
2782
2783
2784
2785
2786
2787
2788
2789void
2791{
2794 bool concurrently = false;
2796 char *tablespacename = NULL;
2797
2798
2799 foreach(lc, stmt->params)
2800 {
2802
2803 if (strcmp(opt->defname, "verbose") == 0)
2805 else if (strcmp(opt->defname, "concurrently") == 0)
2807 else if (strcmp(opt->defname, "tablespace") == 0)
2809 else
2811 (errcode(ERRCODE_SYNTAX_ERROR),
2812 errmsg("unrecognized REINDEX option \"%s\"",
2815 }
2816
2817 if (concurrently)
2819 "REINDEX CONCURRENTLY");
2820
2824
2825
2826
2827
2828
2829 if (tablespacename != NULL)
2830 {
2832
2833
2836 {
2838
2844 }
2845 }
2846 else
2848
2849 switch (stmt->kind)
2850 {
2853 break;
2856 break;
2860
2861
2862
2863
2864
2865
2866
2870 "REINDEX DATABASE");
2872 break;
2873 default:
2874 elog(ERROR, "unrecognized object type: %d",
2875 (int) stmt->kind);
2876 break;
2877 }
2878}
2879
2880
2881
2882
2883
2884static void
2886{
2887 const RangeVar *indexRelation = stmt->relation;
2889 Oid indOid;
2890 char persistence;
2891 char relkind;
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2908 0,
2911
2912
2913
2914
2915
2918
2919 if (relkind == RELKIND_PARTITIONED_INDEX)
2922 persistence != RELPERSISTENCE_TEMP)
2924 else
2925 {
2927
2930 }
2931}
2932
2933
2934
2935
2936
2937
2938static void
2940 Oid relId, Oid oldRelId, void *arg)
2941{
2942 char relkind;
2945 Oid table_oid;
2946
2947
2948
2949
2950
2951
2954
2955
2956
2957
2958
2959
2960 if (relId != oldRelId && OidIsValid(oldRelId))
2961 {
2964 }
2965
2966
2968 return;
2969
2970
2971
2972
2973
2974
2976 if (!relkind)
2977 return;
2978 if (relkind != RELKIND_INDEX &&
2979 relkind != RELKIND_PARTITIONED_INDEX)
2981 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2982 errmsg("\"%s\" is not an index", relation->relname)));
2983
2984
2987 {
2989
2993 }
2994
2995
2996 if (relId != oldRelId)
2997 {
2998
2999
3000
3001
3003 {
3005 state->locked_table_oid = table_oid;
3006 }
3007 }
3008}
3009
3010
3011
3012
3013
3014static Oid
3016{
3017 Oid heapOid;
3018 bool result;
3020
3021
3022
3023
3024
3025
3026
3027
3028
3032 0,
3034
3035 if (get_rel_relkind(heapOid) == RELKIND_PARTITIONED_TABLE)
3039 {
3041
3042 if (!result)
3044 (errmsg("table \"%s\" has no indexes that can be reindexed concurrently",
3046 }
3047 else
3048 {
3050
3055 &newparams);
3056 if (!result)
3058 (errmsg("table \"%s\" has no indexes to reindex",
3060 }
3061
3062 return heapOid;
3063}
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073static void
3075{
3076
3077 Oid objectOid;
3085 int num_keys;
3086 bool concurrent_warning = false;
3087 bool tablespace_warning = false;
3088 const char *objectName = stmt->name;
3090
3094
3095
3096
3097
3098
3100
3104 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3105 errmsg("cannot reindex system catalogs concurrently")));
3106
3107
3108
3109
3110
3111
3112
3114 {
3116
3120 objectName);
3121 }
3122 else
3123 {
3125
3126 if (objectName && strcmp(objectName, get_database_name(objectOid)) != 0)
3128 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3129 errmsg("can only reindex the currently open database")));
3134 }
3135
3136
3137
3138
3139
3140
3141
3143 "ReindexMultipleTables",
3145
3146
3147
3148
3149
3150
3152 {
3153 num_keys = 1;
3155 Anum_pg_class_relnamespace,
3158 }
3159 else
3160 num_keys = 0;
3161
3162
3163
3164
3165
3166
3167
3171 {
3173 Oid relid = classtuple->oid;
3174
3175
3176
3177
3178
3179
3180
3181
3182 if (classtuple->relkind != RELKIND_RELATION &&
3183 classtuple->relkind != RELKIND_MATVIEW)
3184 continue;
3185
3186
3187 if (classtuple->relpersistence == RELPERSISTENCE_TEMP &&
3189 continue;
3190
3191
3192
3193
3194
3197 continue;
3200 continue;
3201
3202
3203
3204
3205
3206
3207 if (classtuple->relisshared &&
3209 continue;
3210
3211
3212
3213
3214
3217 {
3218 if (!concurrent_warning)
3220 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3221 errmsg("cannot reindex system catalogs concurrently, skipping all")));
3222 concurrent_warning = true;
3223 continue;
3224 }
3225
3226
3227
3228
3229
3231 {
3232 bool skip_rel = false;
3233
3234
3235
3236
3237
3238 if (RELKIND_HAS_STORAGE(classtuple->relkind) &&
3240 skip_rel = true;
3241
3242
3243
3244
3245
3247 skip_rel = true;
3248
3249 if (skip_rel)
3250 {
3251 if (!tablespace_warning)
3253 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3254 errmsg("cannot move system relations, skipping all")));
3255 tablespace_warning = true;
3256 continue;
3257 }
3258 }
3259
3260
3262
3263
3264
3265
3266
3267
3268
3269
3270 if (relid == RelationRelationId)
3271 relids = lcons_oid(relid, relids);
3272 else
3274
3276 }
3279
3280
3281
3282
3283
3285
3287}
3288
3289
3290
3291
3292static void
3294{
3296
3297 Assert(RELKIND_HAS_PARTITIONS(errinfo->relkind));
3298
3299 if (errinfo->relkind == RELKIND_PARTITIONED_TABLE)
3300 errcontext("while reindexing partitioned table \"%s.%s\"",
3302 else if (errinfo->relkind == RELKIND_PARTITIONED_INDEX)
3303 errcontext("while reindexing partitioned index \"%s.%s\"",
3305}
3306
3307
3308
3309
3310
3311
3312
3313static void
3315{
3321 List *inhoids;
3325
3326 Assert(RELKIND_HAS_PARTITIONS(relkind));
3327
3328
3329
3330
3331
3334 errinfo.relkind = relkind;
3336 errcallback.arg = &errinfo;
3339
3341 relkind == RELKIND_PARTITIONED_TABLE ?
3342 "REINDEX TABLE" : "REINDEX INDEX");
3343
3344
3346
3347
3348
3349
3350
3351
3352
3353
3356
3357
3359
3360
3361
3362
3363
3364 foreach(lc, inhoids)
3365 {
3369
3370
3371
3372
3373
3374 if (!RELKIND_HAS_STORAGE(partkind))
3375 continue;
3376
3377 Assert(partkind == RELKIND_INDEX ||
3378 partkind == RELKIND_RELATION);
3379
3380
3384 }
3385
3386
3387
3388
3389
3391
3392
3393
3394
3395
3396
3398}
3399
3400
3401
3402
3403
3404
3405
3406
3407static void
3409{
3411
3414
3415 foreach(l, relids)
3416 {
3418 char relkind;
3419 char relpersistence;
3420
3422
3423
3425
3426
3428 {
3431 continue;
3432 }
3433
3434
3435
3436
3437
3438
3439
3442 {
3444
3450 }
3451
3454
3455
3456
3457
3458
3459 Assert(!RELKIND_HAS_PARTITIONS(relkind));
3460
3462 relpersistence != RELPERSISTENCE_TEMP)
3463 {
3465
3470
3471 }
3472 else if (relkind == RELKIND_INDEX)
3473 {
3475
3480
3481 }
3482 else
3483 {
3484 bool result;
3486
3492 &newparams);
3493
3496 (errmsg("table \"%s.%s\" was reindexed",
3499
3501 }
3502
3504 }
3505
3507}
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533static bool
3535{
3536 typedef struct ReindexIndexInfo
3537 {
3538 Oid indexId;
3539 Oid tableId;
3540 Oid amId;
3541 bool safe;
3542 } ReindexIndexInfo;
3543 List *heapRelationIds = NIL;
3546 List *relationLocks = NIL;
3549 *lc2;
3552 char relkind;
3553 char *relationName = NULL;
3554 char *relationNamespace = NULL;
3556 const int progress_index[] = {
3561 };
3562 int64 progress_vals[4];
3563
3564
3565
3566
3567
3568
3569
3571 "ReindexConcurrent",
3573
3575 {
3576
3578
3581
3583
3585 }
3586
3588
3589
3590
3591
3592
3593 switch (relkind)
3594 {
3595 case RELKIND_RELATION:
3596 case RELKIND_MATVIEW:
3597 case RELKIND_TOASTVALUE:
3598 {
3599
3600
3601
3602
3604
3605
3607
3608
3609 heapRelationIds = lappend_oid(heapRelationIds, relationOid);
3610
3612
3615 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3616 errmsg("cannot reindex system catalogs concurrently")));
3617
3618
3620 {
3623
3624 if (!heapRelation)
3625 break;
3626 }
3627 else
3628 heapRelation = table_open(relationOid,
3630
3634 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3635 errmsg("cannot move system relation \"%s\"",
3637
3638
3640 {
3644
3645 if (!indexRelation->rd_index->indisvalid)
3647 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3648 errmsg("skipping reindex of invalid index \"%s.%s\"",
3651 errhint("Use DROP INDEX or REINDEX INDEX.")));
3652 else if (indexRelation->rd_index->indisexclusion)
3654 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3655 errmsg("cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping",
3658 else
3659 {
3660 ReindexIndexInfo *idx;
3661
3662
3664
3666 idx->indexId = cellOid;
3667
3668
3670
3672 }
3673
3675 }
3676
3677
3679 {
3680 Oid toastOid = heapRelation->rd_rel->reltoastrelid;
3683
3684
3686
3687
3688 heapRelationIds = lappend_oid(heapRelationIds, toastOid);
3689
3691
3693 {
3697
3698 if (!indexRelation->rd_index->indisvalid)
3700 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3701 errmsg("skipping reindex of invalid index \"%s.%s\"",
3704 errhint("Use DROP INDEX or REINDEX INDEX.")));
3705 else
3706 {
3707 ReindexIndexInfo *idx;
3708
3709
3710
3711
3712
3714
3716 idx->indexId = cellOid;
3718
3719
3721 }
3722
3724 }
3725
3727 }
3728
3730 break;
3731 }
3732 case RELKIND_INDEX:
3733 {
3737 ReindexIndexInfo *idx;
3738
3739
3741 break;
3742
3745 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3746 errmsg("cannot reindex system catalogs concurrently")));
3747
3748
3749
3750
3751
3752
3756 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3757 errmsg("cannot reindex invalid index on TOAST table")));
3758
3759
3760
3761
3762
3763
3764
3766 {
3769
3770 if (!heapRelation)
3771 break;
3772 }
3773 else
3776
3780 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3781 errmsg("cannot move system relation \"%s\"",
3783
3785
3786
3788
3789
3791
3792
3793
3794
3795
3797 idx->indexId = relationOid;
3799
3800
3802 break;
3803 }
3804
3805 case RELKIND_PARTITIONED_TABLE:
3806 case RELKIND_PARTITIONED_INDEX:
3807 default:
3808
3810 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3811 errmsg("cannot reindex this type of relation concurrently")));
3812 break;
3813 }
3814
3815
3816
3817
3818
3819
3820
3821
3822 if (indexIds == NIL)
3823 return false;
3824
3825
3826 if (params->tablespaceOid == GLOBALTABLESPACE_OID)
3828 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3829 errmsg("cannot move non-shared relation to tablespace \"%s\"",
3831
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859 foreach(lc, indexIds)
3860 {
3861 char *concurrentName;
3862 ReindexIndexInfo *idx = lfirst(lc);
3863 ReindexIndexInfo *newidx;
3864 Oid newIndexId;
3867 Oid save_userid;
3868 int save_sec_context;
3869 int save_nestlevel;
3872 Oid tablespaceid;
3873
3877
3878
3879
3880
3881
3882
3888
3889
3892
3893#ifdef USE_INJECTION_POINTS
3894 if (idx->safe)
3896 else
3898#endif
3899
3901 idx->amId = indexRel->rd_rel->relam;
3902
3903
3904 if (indexRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
3905 elog(ERROR, "cannot reindex a temporary table concurrently");
3906
3908
3910 progress_vals[1] = 0;
3911 progress_vals[2] = idx->indexId;
3912 progress_vals[3] = idx->amId;
3914
3915
3917 NULL,
3918 "ccnew",
3920 false);
3921
3922
3924 heapRel->rd_rel->relkind != RELKIND_TOASTVALUE)
3926 else
3927 tablespaceid = indexRel->rd_rel->reltablespace;
3928
3929
3931 idx->indexId,
3932 tablespaceid,
3933 concurrentName);
3934
3935
3936
3937
3938
3940
3941
3942
3943
3945
3947 newidx->indexId = newIndexId;
3948 newidx->safe = idx->safe;
3949 newidx->tableId = idx->tableId;
3950 newidx->amId = idx->amId;
3951
3952 newIndexIds = lappend(newIndexIds, newidx);
3953
3954
3955
3956
3957
3958
3959
3962 relationLocks = lappend(relationLocks, lockrelid);
3965 relationLocks = lappend(relationLocks, lockrelid);
3966
3968
3971
3972
3974
3975
3977
3979
3980
3981
3982
3983
3985 {
3987
3992 }
3993 }
3994
3995
3996
3997
3998
3999 foreach(lc, heapRelationIds)
4000 {
4004
4005
4007
4008
4011 relationLocks = lappend(relationLocks, lockrelid);
4012
4014
4015
4017 lockTags = lappend(lockTags, heaplocktag);
4018
4020
4021
4023 }
4024
4025
4026 foreach(lc, relationLocks)
4027 {
4029
4031 }
4032
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4056
4057 foreach(lc, newIndexIds)
4058 {
4059 ReindexIndexInfo *newidx = lfirst(lc);
4060
4061
4063
4064
4065
4066
4067
4068
4070
4071
4072 if (newidx->safe)
4074
4075
4077
4078
4079
4080
4081
4085 progress_vals[2] = newidx->indexId;
4086 progress_vals[3] = newidx->amId;
4088
4089
4091
4094 }
4095
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4115
4116 foreach(lc, newIndexIds)
4117 {
4118 ReindexIndexInfo *newidx = lfirst(lc);
4121
4123
4124
4125
4126
4127
4128
4130
4131
4132 if (newidx->safe)
4134
4135
4136
4137
4138
4141
4142
4143
4144
4145
4149 progress_vals[2] = newidx->indexId;
4150 progress_vals[3] = newidx->amId;
4152
4153 validate_index(newidx->tableId, newidx->indexId, snapshot);
4154
4155
4156
4157
4158
4159 limitXmin = snapshot->xmin;
4160
4163
4164
4165
4166
4167
4168
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4184
4186 }
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4200
4201
4202
4203
4204
4205
4207
4208 forboth(lc, indexIds, lc2, newIndexIds)
4209 {
4210 ReindexIndexInfo *oldidx = lfirst(lc);
4211 ReindexIndexInfo *newidx = lfirst(lc2);
4212 char *oldName;
4213
4214
4215
4216
4217
4218
4220
4221
4223 NULL,
4224 "ccold",
4226 false);
4227
4228
4229
4230
4231
4233
4234
4235
4236
4237
4239
4241
4242
4243
4244
4245
4246
4248
4249
4250
4251
4252
4253
4254
4255
4257 }
4258
4259
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4280
4281 foreach(lc, indexIds)
4282 {
4283 ReindexIndexInfo *oldidx = lfirst(lc);
4284
4285
4286
4287
4288
4289
4291
4292
4293
4294
4295
4297
4299
4301 }
4302
4303
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4322
4324
4325 {
4327
4328 foreach(lc, indexIds)
4329 {
4330 ReindexIndexInfo *idx = lfirst(lc);
4332
4333 object.classId = RelationRelationId;
4334 object.objectId = idx->indexId;
4335 object.objectSubId = 0;
4336
4338 }
4339
4340
4341
4342
4343
4346 }
4347
4350
4351
4352
4353
4354 foreach(lc, relationLocks)
4355 {
4357
4359 }
4360
4361
4363
4364
4366 {
4367 if (relkind == RELKIND_INDEX)
4369 (errmsg("index \"%s.%s\" was reindexed",
4370 relationNamespace, relationName),
4373 else
4374 {
4375 foreach(lc, newIndexIds)
4376 {
4377 ReindexIndexInfo *idx = lfirst(lc);
4378 Oid indOid = idx->indexId;
4379
4381 (errmsg("index \"%s.%s\" was reindexed",
4384
4385 }
4386
4388 (errmsg("table \"%s.%s\" was reindexed",
4389 relationNamespace, relationName),
4392 }
4393 }
4394
4396
4398
4399 return true;
4400}
4401
4402
4403
4404
4405
4406
4407
4408void
4410{
4417
4418
4419 Assert(partitionIdx->rd_rel->relkind == RELKIND_INDEX ||
4420 partitionIdx->rd_rel->relkind == RELKIND_PARTITIONED_INDEX);
4421
4422
4423
4424
4427 Anum_pg_inherits_inhrelid,
4431 Anum_pg_inherits_inhseqno,
4434 scan = systable_beginscan(pg_inherits, InheritsRelidSeqnoIndexId, true,
4435 NULL, 2, key);
4437
4439 {
4441 {
4442
4443
4444
4445
4447 }
4448 else
4449 {
4452 }
4453 }
4454 else
4455 {
4457
4459 {
4460
4461
4462
4465 }
4466 else
4467 {
4468
4469
4470
4471
4472
4473 if (inhForm->inhparent != parentOid)
4474 {
4475
4476 elog(ERROR, "bogus pg_inherit row: inhrelid %u inhparent %u",
4477 inhForm->inhrelid, inhForm->inhparent);
4478 }
4479
4480
4482 }
4483 }
4484
4485
4488
4489
4491 {
4494 }
4495
4496
4498
4500 {
4501
4502
4503
4504
4505
4507 {
4511
4515 partitionIdx->rd_index->indrelid);
4520 }
4521 else
4522 {
4524 RelationRelationId,
4527 RelationRelationId,
4529 }
4530
4531
4533 }
4534}
4535
4536
4537
4538
4539
4540static void
4542{
4546
4550 elog(ERROR, "cache lookup failed for relation %u", relationId);
4558}
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578static inline void
4580{
4581
4582
4583
4584
4587
4592}
Datum idx(PG_FUNCTION_ARGS)
bool has_privs_of_role(Oid member, Oid role)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
IndexAmRoutine * GetIndexAmRoutine(Oid amhandler)
StrategyNumber IndexAmTranslateCompareType(CompareType cmptype, Oid amoid, Oid opfamily, bool missing_ok)
bytea *(* amoptions_function)(Datum reloptions, bool validate)
char * get_am_name(Oid amOid)
void free_attrmap(AttrMap *map)
AttrMap * build_attrmap_by_name(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
#define InvalidAttrNumber
char * get_tablespace_name(Oid spc_oid)
Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)
Oid GetDefaultTablespace(char relpersistence, bool partitioned)
void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
void pgstat_progress_incr_param(int index, int64 incr)
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
void pgstat_progress_end_command(void)
@ PROGRESS_COMMAND_CREATE_INDEX
int bms_next_member(const Bitmapset *a, int prevbit)
bool bms_is_member(int x, const Bitmapset *a)
#define OidIsValid(objectId)
bool IsToastNamespace(Oid namespaceId)
bool IsSystemRelation(Relation relation)
bool IsCatalogRelationOid(Oid relid)
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
bool contain_mutable_functions_after_planning(Expr *expr)
char * get_database_name(Oid dbid)
char * defGetString(DefElem *def)
bool defGetBoolean(DefElem *def)
void performMultipleDeletions(const ObjectAddresses *objects, DropBehavior behavior, int flags)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
ObjectAddresses * new_object_addresses(void)
@ DEPENDENCY_PARTITION_PRI
@ DEPENDENCY_PARTITION_SEC
#define PERFORM_DELETION_CONCURRENT_LOCK
#define PERFORM_DELETION_INTERNAL
int errmsg_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void EventTriggerCollectSimpleCommand(ObjectAddress address, ObjectAddress secondaryObject, Node *parsetree)
#define palloc_object(type)
#define palloc_array(type, count)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
char * format_type_be(Oid type_oid)
void systable_endscan(SysScanDesc sysscan)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
bool allowSystemTableMods
int NewGUCNestLevel(void)
void RestrictSearchPath(void)
void AtEOXact_GUC(bool isCommit, int nestLevel)
int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
HeapTuple heap_copytuple(HeapTuple tuple)
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
void validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
Oid IndexGetRelation(Oid indexId, bool missing_ok)
void index_concurrently_set_dead(Oid heapId, Oid indexId)
Oid index_create(Relation heapRelation, const char *indexRelationName, Oid indexRelationId, Oid parentIndexRelid, Oid parentConstraintId, RelFileNumber relFileNumber, IndexInfo *indexInfo, const List *indexColNames, Oid accessMethodId, Oid tableSpaceId, const Oid *collationIds, const Oid *opclassIds, const Datum *opclassOptions, const int16 *coloptions, const NullableDatum *stattargets, Datum reloptions, bits16 flags, bits16 constr_flags, bool allow_system_table_mods, bool is_internal, Oid *constraintId)
void index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
void index_set_state_flags(Oid indexId, IndexStateFlagsAction action)
bool CompareIndexInfo(const IndexInfo *info1, const IndexInfo *info2, const Oid *collations1, const Oid *collations2, const Oid *opfamilies1, const Oid *opfamilies2, const AttrMap *attmap)
bool reindex_relation(const ReindexStmt *stmt, Oid relid, int flags, const ReindexParams *params)
IndexInfo * BuildIndexInfo(Relation index)
Oid index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, Oid tablespaceOid, const char *newName)
void index_check_primary_key(Relation heapRel, const IndexInfo *indexInfo, bool is_alter_table, const IndexStmt *stmt)
void index_concurrently_build(Oid heapRelationId, Oid indexRelationId)
void reindex_index(const ReindexStmt *stmt, Oid indexId, bool skip_constraint_checks, char persistence, const ReindexParams *params)
#define INDEX_CREATE_IS_PRIMARY
#define INDEX_CREATE_IF_NOT_EXISTS
#define REINDEX_REL_PROCESS_TOAST
#define INDEX_CREATE_PARTITIONED
#define REINDEXOPT_CONCURRENTLY
#define REINDEXOPT_MISSING_OK
#define INDEX_CREATE_INVALID
#define INDEX_CONSTR_CREATE_WITHOUT_OVERLAPS
#define INDEX_CREATE_ADD_CONSTRAINT
#define INDEX_CREATE_SKIP_BUILD
#define INDEX_CONSTR_CREATE_DEFERRABLE
#define REINDEXOPT_REPORT_PROGRESS
#define INDEX_CONSTR_CREATE_INIT_DEFERRED
#define INDEX_CREATE_CONCURRENT
#define REINDEXOPT_VERBOSE
#define REINDEX_REL_CHECK_CONSTRAINTS
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
static bool ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const ReindexParams *params)
void ExecReindex(ParseState *pstate, const ReindexStmt *stmt, bool isTopLevel)
ObjectAddress DefineIndex(Oid tableId, IndexStmt *stmt, Oid indexRelationId, Oid parentIndexId, Oid parentConstraintId, int total_parts, bool is_alter_table, bool check_rights, bool check_not_in_use, bool skip_build, bool quiet)
static void set_indexsafe_procflags(void)
char * ChooseRelationName(const char *name1, const char *name2, const char *label, Oid namespaceid, bool isconstraint)
static void reindex_error_callback(void *arg)
static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid *typeOids, Oid *collationOids, Oid *opclassOids, Datum *opclassOptions, int16 *colOptions, const List *attList, const List *exclusionOpNames, Oid relId, const char *accessMethodName, Oid accessMethodId, bool amcanorder, bool isconstraint, bool iswithoutoverlaps, Oid ddl_userid, int ddl_sec_context, int *ddl_save_nestlevel)
static void ReindexIndex(const ReindexStmt *stmt, const ReindexParams *params, bool isTopLevel)
void IndexSetParentIndex(Relation partitionIdx, Oid parentOid)
char * makeObjectName(const char *name1, const char *name2, const char *label)
Oid GetDefaultOpClass(Oid type_id, Oid am_id)
static char * ChooseIndexNameAddition(const List *colnames)
static void ReindexMultipleTables(const ReindexStmt *stmt, const ReindexParams *params)
static bool CompareOpclassOptions(const Datum *opts1, const Datum *opts2, int natts)
static void update_relispartition(Oid relationId, bool newval)
bool CheckIndexCompatible(Oid oldId, const char *accessMethodName, const List *attributeList, const List *exclusionOpNames, bool isWithoutOverlaps)
void WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
Oid ResolveOpClass(const List *opclass, Oid attrType, const char *accessMethodName, Oid accessMethodId)
static void ReindexPartitions(const ReindexStmt *stmt, Oid relid, const ReindexParams *params, bool isTopLevel)
struct ReindexErrorInfo ReindexErrorInfo
static Oid ReindexTable(const ReindexStmt *stmt, const ReindexParams *params, bool isTopLevel)
static void CheckPredicate(Expr *predicate)
static void ReindexMultipleInternal(const ReindexStmt *stmt, const List *relids, const ReindexParams *params)
static void RangeVarCallbackForReindexIndex(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
static List * ChooseIndexColumnNames(const List *indexElems)
void GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype, Oid *opid, StrategyNumber *strat)
static char * ChooseIndexName(const char *tabname, Oid namespaceId, const List *colnames, const List *exclusionOpNames, bool primary, bool isconstraint)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
#define INJECTION_POINT(name)
void CacheInvalidateRelcacheByRelid(Oid relid)
List * lcons_oid(Oid datum, List *list)
List * lappend(List *list, void *datum)
List * list_concat_copy(const List *list1, const List *list2)
List * lappend_oid(List *list, Oid datum)
void list_free(List *list)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress)
void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
#define VirtualTransactionIdIsValid(vxid)
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
#define VirtualTransactionIdEquals(vxid1, vxid2)
#define SetInvalidVirtualTransactionId(vxid)
#define AccessExclusiveLock
#define InplaceUpdateTupleLock
#define ShareUpdateExclusiveLock
char * get_rel_name(Oid relid)
Oid get_opclass_method(Oid opclass)
char get_rel_persistence(Oid relid)
bool get_index_isvalid(Oid index_oid)
Oid get_opclass_input_type(Oid opclass)
Oid get_opclass_family(Oid opclass)
Oid get_opfamily_member_for_cmptype(Oid opfamily, Oid lefttype, Oid righttype, CompareType cmptype)
bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)
char * get_opname(Oid opno)
Datum get_attoptions(Oid relid, int16 attnum)
char get_rel_relkind(Oid relid)
Oid get_rel_namespace(Oid relid)
RegProcedure get_opcode(Oid opno)
int get_op_opfamily_strategy(Oid opno, Oid opfamily)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
char * get_opfamily_name(Oid opfid, bool missing_ok)
bool type_is_collatable(Oid typid)
Oid get_opfamily_method(Oid opfid)
Oid getBaseType(Oid typid)
char * get_namespace_name(Oid nspid)
Oid get_relname_relid(const char *relname, Oid relnamespace)
Oid get_commutator(Oid opno)
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
IndexInfo * makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions, List *predicates, bool unique, bool nulls_not_distinct, bool isready, bool concurrent, bool summarizing, bool withoutoverlaps)
List * make_ands_implicit(Expr *clause)
int pg_mbcliplen(const char *mbstr, int len, int limit)
char * pstrdup(const char *in)
void pfree(void *pointer)
void MemoryContextDelete(MemoryContext context)
MemoryContext PortalContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define ALLOCSET_SMALL_SIZES
#define IsBootstrapProcessingMode()
#define SECURITY_RESTRICTED_OPERATION
#define CHECK_FOR_INTERRUPTS()
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
void SetUserIdAndSecContext(Oid userid, int sec_context)
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
char * NameListToString(const List *names)
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
bool isTempNamespace(Oid namespaceId)
Oid get_collation_oid(List *collname, bool missing_ok)
void DeconstructQualifiedName(const List *names, char **nspname_p, char **objname_p)
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Oid exprType(const Node *expr)
Oid exprCollation(const Node *expr)
#define IsA(nodeptr, _type_)
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
TYPCATEGORY TypeCategory(Oid type)
bool IsBinaryCoercible(Oid srctype, Oid targettype)
bool IsPreferredType(TYPCATEGORY category, Oid type)
int parser_errposition(ParseState *pstate, int location)
Oid compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
IndexStmt * generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, const AttrMap *attmap, Oid *constraintOid)
@ PARTITION_STRATEGY_HASH
@ REINDEX_OBJECT_DATABASE
PartitionKey RelationGetPartitionKey(Relation rel)
PartitionDesc RelationGetPartitionDesc(Relation rel, bool omit_detached)
FormData_pg_am * Form_pg_am
FormData_pg_attribute * Form_pg_attribute
static void fix_dependencies(ArchiveHandle *AH)
int errdetail_relkind_not_supported(char relkind)
FormData_pg_class * Form_pg_class
Oid get_relation_idx_constraint_oid(Oid relationId, Oid indexId)
void ConstraintSetParentConstraint(Oid childConstrId, Oid parentConstrId, Oid childTableId)
bool ConstraintNameExists(const char *conname, Oid namespaceid)
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
FormData_pg_index * Form_pg_index
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
void StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
bool has_superclass(Oid relationId)
FormData_pg_inherits * Form_pg_inherits
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define list_make1_oid(x1)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
FormData_pg_opclass * Form_pg_opclass
const char * pg_rusage_show(const PGRUsage *ru0)
void pg_rusage_init(PGRUsage *ru0)
size_t strlcpy(char *dst, const char *src, size_t siz)
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
static Datum Int32GetDatum(int32 X)
#define PROC_IS_AUTOVACUUM
VirtualTransactionId * GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, bool allDbs, int excludeVacuum, int *nvxids)
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
#define PROGRESS_CREATEIDX_PHASE_WAIT_4
#define PROGRESS_CREATEIDX_PHASE_BUILD
#define PROGRESS_CREATEIDX_PARTITIONS_DONE
#define PROGRESS_CREATEIDX_PHASE_WAIT_1
#define PROGRESS_CREATEIDX_COMMAND_CREATE_CONCURRENTLY
#define PROGRESS_CREATEIDX_ACCESS_METHOD_OID
#define PROGRESS_WAITFOR_DONE
#define PROGRESS_CREATEIDX_PHASE_WAIT_3
#define PROGRESS_WAITFOR_TOTAL
#define PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY
#define PROGRESS_CREATEIDX_COMMAND_CREATE
#define PROGRESS_WAITFOR_CURRENT_PID
#define PROGRESS_CREATEIDX_PHASE_WAIT_2
#define PROGRESS_CREATEIDX_PHASE
#define PROGRESS_CREATEIDX_PHASE_VALIDATE_IDXSCAN
#define PROGRESS_CREATEIDX_PHASE_WAIT_5
#define PROGRESS_CREATEIDX_INDEX_OID
#define PROGRESS_CREATEIDX_PARTITIONS_TOTAL
#define PROGRESS_CREATEIDX_COMMAND
char * format_operator(Oid operator_oid)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RELATION_IS_OTHER_TEMP(relation)
#define RelationGetNamespace(relation)
List * RelationGetIndexList(Relation relation)
List * RelationGetIndexPredicate(Relation relation)
List * RelationGetIndexExpressions(Relation relation)
void RelationGetExclusionInfo(Relation indexRelation, Oid **operators, Oid **procs, uint16 **strategies)
Datum transformRelOptions(Datum oldOptions, List *defList, const char *namspace, const char *const validnsps[], bool acceptOidsOff, bool isReset)
bytea * index_reloptions(amoptions_function amoptions, Datum reloptions, bool validate)
#define RelFileNumberIsValid(relnumber)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Snapshot GetTransactionSnapshot(void)
void UnregisterSnapshot(Snapshot snapshot)
void PushActiveSnapshot(Snapshot snapshot)
bool ActiveSnapshotSet(void)
Snapshot RegisterSnapshot(Snapshot snapshot)
void PopActiveSnapshot(void)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
#define HTEqualStrategyNumber
#define BTEqualStrategyNumber
#define ERRCODE_DUPLICATE_OBJECT
struct ErrorContextCallback * previous
void(* callback)(void *arg)
amoptions_function amoptions
amgettuple_function amgettuple
SortByNulls nulls_ordering
uint16 * ii_ExclusionStrats
AttrNumber ii_IndexAttrNumbers[INDEX_MAX_KEYS]
Oid values[FLEXIBLE_ARRAY_MEMBER]
#define FirstLowInvalidHeapAttributeNumber
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCacheLockedCopy1(int cacheId, Datum key1)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
#define SearchSysCacheExists1(cacheId, key1)
Relation try_table_open(Oid relationId, LOCKMODE lockmode)
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)
void CheckTableNotInUse(Relation rel, const char *stmt)
void SetRelationHasSubclass(Oid relationId, bool relhassubclass)
void RangeVarCallbackMaintainsTable(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
#define InvalidTransactionId
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
void CommandCounterIncrement(void)
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
void StartTransactionCommand(void)
void CommitTransactionCommand(void)