Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit bd1ad1b

Browse files
committed
Replace pg_class.relhasexclusion with pg_index.indisexclusion.
There isn't any need to track this state on a table-wide basis, and trying to do so introduces undesirable semantic fuzziness. Move the flag to pg_index, where it clearly describes just a single index and can be immutable after index creation.
1 parent 88452d5 commit bd1ad1b

File tree

8 files changed

+52
-77
lines changed

8 files changed

+52
-77
lines changed

doc/src/sgml/catalogs.sgml

+11-15
Original file line numberDiff line numberDiff line change
@@ -1706,17 +1706,6 @@
17061706
</entry>
17071707
</row>
17081708

1709-
<row>
1710-
<entry><structfield>relhasexclusion</structfield></entry>
1711-
<entry><type>bool</type></entry>
1712-
<entry></entry>
1713-
<entry>
1714-
For a table, true if the table has (or once had) any exclusion
1715-
constraints; for an index, true if the index supports an exclusion
1716-
constraint
1717-
</entry>
1718-
</row>
1719-
17201709
<row>
17211710
<entry><structfield>relhasrules</structfield></entry>
17221711
<entry><type>bool</type></entry>
@@ -2046,8 +2035,7 @@
20462035
<para>
20472036
<literal>pg_class.relchecks</literal> needs to agree with the
20482037
number of check-constraint entries found in this table for each
2049-
relation. Also, <literal>pg_class.relhasexclusion</literal> must
2050-
be true if there are any exclusion-constraint entries for the relation.
2038+
relation.
20512039
</para>
20522040
</note>
20532041

@@ -3056,12 +3044,20 @@
30563044
(<structfield>indisunique</> should always be true when this is true)</entry>
30573045
</row>
30583046

3047+
<row>
3048+
<entry><structfield>indisexclusion</structfield></entry>
3049+
<entry><type>bool</type></entry>
3050+
<entry></entry>
3051+
<entry>If true, this index supports an exclusion constraint</entry>
3052+
</row>
3053+
30593054
<row>
30603055
<entry><structfield>indimmediate</structfield></entry>
30613056
<entry><type>bool</type></entry>
30623057
<entry></entry>
3063-
<entry>If true, the uniqueness check is enforced immediately on insertion
3064-
(<structfield>indisunique</> should always be true when this is true)</entry>
3058+
<entry>If true, the uniqueness check is enforced immediately on
3059+
insertion
3060+
(irrelevant if <structfield>indisunique</> is not true)</entry>
30653061
</row>
30663062

30673063
<row>

src/backend/catalog/heap.c

-1
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,6 @@ InsertPgClassTuple(Relation pg_class_desc,
703703
values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
704704
values[Anum_pg_class_relhasoids - 1] = BoolGetDatum(rd_rel->relhasoids);
705705
values[Anum_pg_class_relhaspkey - 1] = BoolGetDatum(rd_rel->relhaspkey);
706-
values[Anum_pg_class_relhasexclusion - 1] = BoolGetDatum(rd_rel->relhasexclusion);
707706
values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
708707
values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers);
709708
values[Anum_pg_class_relhassubclass - 1] = BoolGetDatum(rd_rel->relhassubclass);

src/backend/catalog/index.c

+10-21
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,11 @@ static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
9696
Oid *classOids,
9797
int16 *coloptions,
9898
bool primary,
99+
bool isexclusion,
99100
bool immediate,
100101
bool isvalid);
101102
static void index_update_stats(Relation rel,
102-
bool hasindex, bool isprimary, bool hasexclusion,
103+
bool hasindex, bool isprimary,
103104
Oid reltoastidxid, double reltuples);
104105
static void IndexCheckExclusion(Relation heapRelation,
105106
Relation indexRelation,
@@ -523,6 +524,7 @@ UpdateIndexRelation(Oid indexoid,
523524
Oid *classOids,
524525
int16 *coloptions,
525526
bool primary,
527+
bool isexclusion,
526528
bool immediate,
527529
bool isvalid)
528530
{
@@ -591,6 +593,7 @@ UpdateIndexRelation(Oid indexoid,
591593
values[Anum_pg_index_indnatts - 1] = Int16GetDatum(indexInfo->ii_NumIndexAttrs);
592594
values[Anum_pg_index_indisunique - 1] = BoolGetDatum(indexInfo->ii_Unique);
593595
values[Anum_pg_index_indisprimary - 1] = BoolGetDatum(primary);
596+
values[Anum_pg_index_indisexclusion - 1] = BoolGetDatum(isexclusion);
594597
values[Anum_pg_index_indimmediate - 1] = BoolGetDatum(immediate);
595598
values[Anum_pg_index_indisclustered - 1] = BoolGetDatum(false);
596599
values[Anum_pg_index_indisvalid - 1] = BoolGetDatum(isvalid);
@@ -819,7 +822,6 @@ index_create(Relation heapRelation,
819822
indexRelation->rd_rel->relam = accessMethodObjectId;
820823
indexRelation->rd_rel->relkind = RELKIND_INDEX;
821824
indexRelation->rd_rel->relhasoids = false;
822-
indexRelation->rd_rel->relhasexclusion = is_exclusion;
823825

824826
/*
825827
* store index's pg_class entry
@@ -854,7 +856,7 @@ index_create(Relation heapRelation,
854856
* ----------------
855857
*/
856858
UpdateIndexRelation(indexRelationId, heapRelationId, indexInfo,
857-
classObjectId, coloptions, isprimary,
859+
classObjectId, coloptions, isprimary, is_exclusion,
858860
!deferrable,
859861
!concurrent);
860862

@@ -1024,7 +1026,6 @@ index_create(Relation heapRelation,
10241026
index_update_stats(heapRelation,
10251027
true,
10261028
isprimary,
1027-
is_exclusion,
10281029
InvalidOid,
10291030
heapRelation->rd_rel->reltuples);
10301031
/* Make the above update visible */
@@ -1190,7 +1191,6 @@ index_constraint_create(Relation heapRelation,
11901191
index_update_stats(heapRelation,
11911192
true,
11921193
true,
1193-
false,
11941194
InvalidOid,
11951195
heapRelation->rd_rel->reltuples);
11961196

@@ -1375,7 +1375,7 @@ BuildIndexInfo(Relation index)
13751375
ii->ii_PredicateState = NIL;
13761376

13771377
/* fetch exclusion constraint info if any */
1378-
if (index->rd_rel->relhasexclusion)
1378+
if (indexStruct->indisexclusion)
13791379
{
13801380
RelationGetExclusionInfo(index,
13811381
&ii->ii_ExclusionOps,
@@ -1486,7 +1486,6 @@ FormIndexDatum(IndexInfo *indexInfo,
14861486
*
14871487
* hasindex: set relhasindex to this value
14881488
* isprimary: if true, set relhaspkey true; else no change
1489-
* hasexclusion: if true, set relhasexclusion true; else no change
14901489
* reltoastidxid: if not InvalidOid, set reltoastidxid to this value;
14911490
* else no change
14921491
* reltuples: set reltuples to this value
@@ -1503,7 +1502,7 @@ FormIndexDatum(IndexInfo *indexInfo,
15031502
*/
15041503
static void
15051504
index_update_stats(Relation rel,
1506-
bool hasindex, bool isprimary, bool hasexclusion,
1505+
bool hasindex, bool isprimary,
15071506
Oid reltoastidxid, double reltuples)
15081507
{
15091508
BlockNumber relpages = RelationGetNumberOfBlocks(rel);
@@ -1542,9 +1541,9 @@ index_update_stats(Relation rel,
15421541
* It is safe to use a non-transactional update even though our
15431542
* transaction could still fail before committing. Setting relhasindex
15441543
* true is safe even if there are no indexes (VACUUM will eventually fix
1545-
* it), likewise for relhaspkey and relhasexclusion. And of course the
1546-
* relpages and reltuples counts are correct (or at least more so than the
1547-
* old values) regardless.
1544+
* it), likewise for relhaspkey. And of course the relpages and reltuples
1545+
* counts are correct (or at least more so than the old values)
1546+
* regardless.
15481547
*/
15491548

15501549
pg_class = heap_open(RelationRelationId, RowExclusiveLock);
@@ -1597,14 +1596,6 @@ index_update_stats(Relation rel,
15971596
dirty = true;
15981597
}
15991598
}
1600-
if (hasexclusion)
1601-
{
1602-
if (!rd_rel->relhasexclusion)
1603-
{
1604-
rd_rel->relhasexclusion = true;
1605-
dirty = true;
1606-
}
1607-
}
16081599
if (OidIsValid(reltoastidxid))
16091600
{
16101601
Assert(rd_rel->relkind == RELKIND_TOASTVALUE);
@@ -1760,13 +1751,11 @@ index_build(Relation heapRelation,
17601751
index_update_stats(heapRelation,
17611752
true,
17621753
isprimary,
1763-
(indexInfo->ii_ExclusionOps != NULL),
17641754
(heapRelation->rd_rel->relkind == RELKIND_TOASTVALUE) ?
17651755
RelationGetRelid(indexRelation) : InvalidOid,
17661756
stats->heap_tuples);
17671757

17681758
index_update_stats(indexRelation,
1769-
false,
17701759
false,
17711760
false,
17721761
InvalidOid,

src/backend/commands/vacuum.c

+4-13
Original file line numberDiff line numberDiff line change
@@ -524,21 +524,12 @@ vac_update_relstats(Relation relation,
524524

525525
/*
526526
* If we have discovered that there are no indexes, then there's no
527-
* primary key either, nor any exclusion constraints. This could be done
528-
* more thoroughly...
527+
* primary key either. This could be done more thoroughly...
529528
*/
530-
if (!hasindex)
529+
if (pgcform->relhaspkey && !hasindex)
531530
{
532-
if (pgcform->relhaspkey)
533-
{
534-
pgcform->relhaspkey = false;
535-
dirty = true;
536-
}
537-
if (pgcform->relhasexclusion && pgcform->relkind != RELKIND_INDEX)
538-
{
539-
pgcform->relhasexclusion = false;
540-
dirty = true;
541-
}
531+
pgcform->relhaspkey = false;
532+
dirty = true;
542533
}
543534

544535
/* We also clear relhasrules and relhastriggers if needed */

src/backend/parser/parse_utilcmd.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
949949
* certainly isn't. If it is or might be from a constraint, we have to
950950
* fetch the pg_constraint record.
951951
*/
952-
if (index->primary || index->unique || idxrelrec->relhasexclusion)
952+
if (index->primary || index->unique || idxrec->indisexclusion)
953953
{
954954
Oid constraintId = get_index_constraint(source_relid);
955955

@@ -970,7 +970,7 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
970970
index->initdeferred = conrec->condeferred;
971971

972972
/* If it's an exclusion constraint, we need the operator names */
973-
if (idxrelrec->relhasexclusion)
973+
if (idxrec->indisexclusion)
974974
{
975975
Datum *elems;
976976
int nElems;

src/include/catalog/catversion.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201101111
56+
#define CATALOG_VERSION_NO 201101251
5757

5858
#endif

src/include/catalog/pg_class.h

+11-13
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO
6161
int2 relchecks; /* # of CHECK constraints for class */
6262
bool relhasoids; /* T if we generate OIDs for rows of rel */
6363
bool relhaspkey; /* has (or has had) PRIMARY KEY index */
64-
bool relhasexclusion; /* has (or has had) exclusion constraint */
6564
bool relhasrules; /* has (or has had) any rules */
6665
bool relhastriggers; /* has (or has had) any TRIGGERs */
6766
bool relhassubclass; /* has (or has had) derived classes */
@@ -93,7 +92,7 @@ typedef FormData_pg_class *Form_pg_class;
9392
* ----------------
9493
*/
9594

96-
#define Natts_pg_class 27
95+
#define Natts_pg_class 26
9796
#define Anum_pg_class_relname 1
9897
#define Anum_pg_class_relnamespace 2
9998
#define Anum_pg_class_reltype 3
@@ -114,13 +113,12 @@ typedef FormData_pg_class *Form_pg_class;
114113
#define Anum_pg_class_relchecks 18
115114
#define Anum_pg_class_relhasoids 19
116115
#define Anum_pg_class_relhaspkey 20
117-
#define Anum_pg_class_relhasexclusion 21
118-
#define Anum_pg_class_relhasrules 22
119-
#define Anum_pg_class_relhastriggers 23
120-
#define Anum_pg_class_relhassubclass 24
121-
#define Anum_pg_class_relfrozenxid 25
122-
#define Anum_pg_class_relacl 26
123-
#define Anum_pg_class_reloptions 27
116+
#define Anum_pg_class_relhasrules 21
117+
#define Anum_pg_class_relhastriggers 22
118+
#define Anum_pg_class_relhassubclass 23
119+
#define Anum_pg_class_relfrozenxid 24
120+
#define Anum_pg_class_relacl 25
121+
#define Anum_pg_class_reloptions 26
124122

125123
/* ----------------
126124
* initial contents of pg_class
@@ -132,13 +130,13 @@ typedef FormData_pg_class *Form_pg_class;
132130
*/
133131

134132
/* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
135-
DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 28 0 t f f f f f 3 _null_ _null_ ));
133+
DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 28 0 t f f f f 3 _null_ _null_ ));
136134
DESCR("");
137-
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 19 0 f f f f f f 3 _null_ _null_ ));
135+
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 19 0 f f f f f 3 _null_ _null_ ));
138136
DESCR("");
139-
DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 25 0 t f f f f f 3 _null_ _null_ ));
137+
DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 25 0 t f f f f 3 _null_ _null_ ));
140138
DESCR("");
141-
DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 27 0 t f f f f f 3 _null_ _null_ ));
139+
DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 26 0 t f f f f 3 _null_ _null_ ));
142140
DESCR("");
143141

144142
#define RELKIND_INDEX 'i' /* secondary index */

src/include/catalog/pg_index.h

+13-11
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ CATALOG(pg_index,2610) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO
3535
int2 indnatts; /* number of columns in index */
3636
bool indisunique; /* is this a unique index? */
3737
bool indisprimary; /* is this index for primary key? */
38+
bool indisexclusion; /* is this index for exclusion constraint? */
3839
bool indimmediate; /* is uniqueness enforced immediately? */
3940
bool indisclustered; /* is this the index last clustered by? */
4041
bool indisvalid; /* is this index valid for use by queries? */
@@ -63,22 +64,23 @@ typedef FormData_pg_index *Form_pg_index;
6364
* compiler constants for pg_index
6465
* ----------------
6566
*/
66-
#define Natts_pg_index 15
67+
#define Natts_pg_index 16
6768
#define Anum_pg_index_indexrelid 1
6869
#define Anum_pg_index_indrelid 2
6970
#define Anum_pg_index_indnatts 3
7071
#define Anum_pg_index_indisunique 4
7172
#define Anum_pg_index_indisprimary 5
72-
#define Anum_pg_index_indimmediate 6
73-
#define Anum_pg_index_indisclustered 7
74-
#define Anum_pg_index_indisvalid 8
75-
#define Anum_pg_index_indcheckxmin 9
76-
#define Anum_pg_index_indisready 10
77-
#define Anum_pg_index_indkey 11
78-
#define Anum_pg_index_indclass 12
79-
#define Anum_pg_index_indoption 13
80-
#define Anum_pg_index_indexprs 14
81-
#define Anum_pg_index_indpred 15
73+
#define Anum_pg_index_indisexclusion 6
74+
#define Anum_pg_index_indimmediate 7
75+
#define Anum_pg_index_indisclustered 8
76+
#define Anum_pg_index_indisvalid 9
77+
#define Anum_pg_index_indcheckxmin 10
78+
#define Anum_pg_index_indisready 11
79+
#define Anum_pg_index_indkey 12
80+
#define Anum_pg_index_indclass 13
81+
#define Anum_pg_index_indoption 14
82+
#define Anum_pg_index_indexprs 15
83+
#define Anum_pg_index_indpred 16
8284

8385
/*
8486
* Index AMs that support ordered scans must support these two indoption

0 commit comments

Comments
 (0)