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

Commit 86ff085

Browse files
committed
Don't require pg_class.dat to contain correct relnatts values.
Practically everybody who's ever added a column to one of the bootstrap catalogs has been burnt by the need to update the relnatts field in the initial pg_class data to match. Now that we use Perl scripts to generate postgres.bki, we can have the machines take care of that, by filling the field during genbki.pl. While at it, use the BKI_DEFAULTS mechanism to eliminate repetitive specifications of other column values in pg_class.dat, too. They weren't particularly a maintenance problem, but this way is prettier (certainly the spotty previous usage of BKI_DEFAULTS wasn't pretty). No catversion bump needed, since this doesn't actually change the contents of postgres.bki. Per gripe from Justin Pryzby, though this is quite different from his originally proposed solution. Amit Langote, John Naylor, Tom Lane Discussion: https://postgr.es/m/20200212182337.GZ1412@telsasoft.com
1 parent 317906f commit 86ff085

File tree

3 files changed

+42
-66
lines changed

3 files changed

+42
-66
lines changed

src/backend/catalog/genbki.pl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,15 @@
184184
'PG_CATALOG_NAMESPACE');
185185

186186

187+
# Fill in pg_class.relnatts by looking at the referenced catalog's schema.
188+
# This is ugly but there's no better place; Catalog::AddDefaultValues
189+
# can't do it, for lack of easy access to the other catalog.
190+
foreach my $row (@{ $catalog_data{pg_class} })
191+
{
192+
$row->{relnatts} = scalar(@{ $catalogs{ $row->{relname} }->{columns} });
193+
}
194+
195+
187196
# Build lookup tables.
188197

189198
# access method OID lookup

src/include/catalog/pg_class.dat

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,15 @@
1414

1515
# Note: only bootstrap catalogs, ie those marked BKI_BOOTSTRAP, need to
1616
# have entries here. Be sure that the OIDs listed here match those given in
17-
# their CATALOG and BKI_ROWTYPE_OID macros, and that the relnatts values are
18-
# correct.
19-
20-
# Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId;
21-
# similarly, "1" in relminmxid stands for FirstMultiXactId
17+
# their CATALOG and BKI_ROWTYPE_OID macros.
2218

2319
{ oid => '1247',
24-
relname => 'pg_type', reltype => 'pg_type', relam => 'heap',
25-
relfilenode => '0', relpages => '0', reltuples => '0', relallvisible => '0',
26-
reltoastrelid => '0', relhasindex => 'f', relisshared => 'f',
27-
relpersistence => 'p', relkind => 'r', relnatts => '31', relchecks => '0',
28-
relhasrules => 'f', relhastriggers => 'f', relhassubclass => 'f',
29-
relrowsecurity => 'f', relforcerowsecurity => 'f', relispopulated => 't',
30-
relreplident => 'n', relispartition => 'f', relfrozenxid => '3',
31-
relminmxid => '1', relacl => '_null_', reloptions => '_null_',
32-
relpartbound => '_null_' },
20+
relname => 'pg_type', reltype => 'pg_type' },
3321
{ oid => '1249',
34-
relname => 'pg_attribute', reltype => 'pg_attribute', relam => 'heap',
35-
relfilenode => '0', relpages => '0', reltuples => '0', relallvisible => '0',
36-
reltoastrelid => '0', relhasindex => 'f', relisshared => 'f',
37-
relpersistence => 'p', relkind => 'r', relnatts => '25', relchecks => '0',
38-
relhasrules => 'f', relhastriggers => 'f', relhassubclass => 'f',
39-
relrowsecurity => 'f', relforcerowsecurity => 'f', relispopulated => 't',
40-
relreplident => 'n', relispartition => 'f', relfrozenxid => '3',
41-
relminmxid => '1', relacl => '_null_', reloptions => '_null_',
42-
relpartbound => '_null_' },
22+
relname => 'pg_attribute', reltype => 'pg_attribute' },
4323
{ oid => '1255',
44-
relname => 'pg_proc', reltype => 'pg_proc', relam => 'heap',
45-
relfilenode => '0', relpages => '0', reltuples => '0', relallvisible => '0',
46-
reltoastrelid => '0', relhasindex => 'f', relisshared => 'f',
47-
relpersistence => 'p', relkind => 'r', relnatts => '29', relchecks => '0',
48-
relhasrules => 'f', relhastriggers => 'f', relhassubclass => 'f',
49-
relrowsecurity => 'f', relforcerowsecurity => 'f', relispopulated => 't',
50-
relreplident => 'n', relispartition => 'f', relfrozenxid => '3',
51-
relminmxid => '1', relacl => '_null_', reloptions => '_null_',
52-
relpartbound => '_null_' },
24+
relname => 'pg_proc', reltype => 'pg_proc' },
5325
{ oid => '1259',
54-
relname => 'pg_class', reltype => 'pg_class', relam => 'heap',
55-
relfilenode => '0', relpages => '0', reltuples => '0', relallvisible => '0',
56-
reltoastrelid => '0', relhasindex => 'f', relisshared => 'f',
57-
relpersistence => 'p', relkind => 'r', relnatts => '33', relchecks => '0',
58-
relhasrules => 'f', relhastriggers => 'f', relhassubclass => 'f',
59-
relrowsecurity => 'f', relforcerowsecurity => 'f', relispopulated => 't',
60-
relreplident => 'n', relispartition => 'f', relfrozenxid => '3',
61-
relminmxid => '1', relacl => '_null_', reloptions => '_null_',
62-
relpartbound => '_null_' },
26+
relname => 'pg_class', reltype => 'pg_class' },
6327

6428
]

src/include/catalog/pg_class.h

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
/* ----------------
2525
* pg_class definition. cpp turns this into
2626
* typedef struct FormData_pg_class
27+
*
28+
* Note that the BKI_DEFAULT values below are only used for rows describing
29+
* BKI_BOOTSTRAP catalogs, since only those rows appear in pg_class.dat.
2730
* ----------------
2831
*/
2932
CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,RelationRelation_Rowtype_Id) BKI_SCHEMA_MACRO
@@ -47,41 +50,41 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
4750
Oid relowner BKI_DEFAULT(PGUID);
4851

4952
/* access method; 0 if not a table / index */
50-
Oid relam BKI_LOOKUP(pg_am);
53+
Oid relam BKI_DEFAULT(heap) BKI_LOOKUP(pg_am);
5154

5255
/* identifier of physical storage file */
5356
/* relfilenode == 0 means it is a "mapped" relation, see relmapper.c */
54-
Oid relfilenode;
57+
Oid relfilenode BKI_DEFAULT(0);
5558

5659
/* identifier of table space for relation (0 means default for database) */
5760
Oid reltablespace BKI_DEFAULT(0) BKI_LOOKUP(pg_tablespace);
5861

5962
/* # of blocks (not always up-to-date) */
60-
int32 relpages;
63+
int32 relpages BKI_DEFAULT(0);
6164

6265
/* # of tuples (not always up-to-date) */
63-
float4 reltuples;
66+
float4 reltuples BKI_DEFAULT(0);
6467

6568
/* # of all-visible blocks (not always up-to-date) */
66-
int32 relallvisible;
69+
int32 relallvisible BKI_DEFAULT(0);
6770

6871
/* OID of toast table; 0 if none */
69-
Oid reltoastrelid;
72+
Oid reltoastrelid BKI_DEFAULT(0);
7073

7174
/* T if has (or has had) any indexes */
72-
bool relhasindex;
75+
bool relhasindex BKI_DEFAULT(f);
7376

7477
/* T if shared across databases */
75-
bool relisshared;
78+
bool relisshared BKI_DEFAULT(f);
7679

7780
/* see RELPERSISTENCE_xxx constants below */
78-
char relpersistence;
81+
char relpersistence BKI_DEFAULT(p);
7982

8083
/* see RELKIND_xxx constants below */
81-
char relkind;
84+
char relkind BKI_DEFAULT(r);
8285

8386
/* number of user attributes */
84-
int16 relnatts;
87+
int16 relnatts BKI_DEFAULT(0); /* genbki.pl will fill this in */
8588

8689
/*
8790
* Class pg_attribute must contain exactly "relnatts" user attributes
@@ -90,51 +93,51 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
9093
*/
9194

9295
/* # of CHECK constraints for class */
93-
int16 relchecks;
96+
int16 relchecks BKI_DEFAULT(0);
9497

9598
/* has (or has had) any rules */
96-
bool relhasrules;
99+
bool relhasrules BKI_DEFAULT(f);
97100

98101
/* has (or has had) any TRIGGERs */
99-
bool relhastriggers;
102+
bool relhastriggers BKI_DEFAULT(f);
100103

101104
/* has (or has had) child tables or indexes */
102-
bool relhassubclass;
105+
bool relhassubclass BKI_DEFAULT(f);
103106

104107
/* row security is enabled or not */
105-
bool relrowsecurity;
108+
bool relrowsecurity BKI_DEFAULT(f);
106109

107110
/* row security forced for owners or not */
108-
bool relforcerowsecurity;
111+
bool relforcerowsecurity BKI_DEFAULT(f);
109112

110113
/* matview currently holds query results */
111-
bool relispopulated;
114+
bool relispopulated BKI_DEFAULT(t);
112115

113116
/* see REPLICA_IDENTITY_xxx constants */
114-
char relreplident;
117+
char relreplident BKI_DEFAULT(n);
115118

116119
/* is relation a partition? */
117-
bool relispartition;
120+
bool relispartition BKI_DEFAULT(f);
118121

119122
/* heap for rewrite during DDL, link to original rel */
120123
Oid relrewrite BKI_DEFAULT(0);
121124

122125
/* all Xids < this are frozen in this rel */
123-
TransactionId relfrozenxid;
126+
TransactionId relfrozenxid BKI_DEFAULT(3); /* FirstNormalTransactionId */
124127

125128
/* all multixacts in this rel are >= this; it is really a MultiXactId */
126-
TransactionId relminmxid;
129+
TransactionId relminmxid BKI_DEFAULT(1); /* FirstMultiXactId */
127130

128131
#ifdef CATALOG_VARLEN /* variable-length fields start here */
129132
/* NOTE: These fields are not present in a relcache entry's rd_rel field. */
130133
/* access permissions */
131-
aclitem relacl[1];
134+
aclitem relacl[1] BKI_DEFAULT(_null_);
132135

133136
/* access-method-specific options */
134-
text reloptions[1];
137+
text reloptions[1] BKI_DEFAULT(_null_);
135138

136139
/* partition bound node tree */
137-
pg_node_tree relpartbound;
140+
pg_node_tree relpartbound BKI_DEFAULT(_null_);
138141
#endif
139142
} FormData_pg_class;
140143

0 commit comments

Comments
 (0)