Skip to content

Commit f3faf35

Browse files
committed
Don't create pg_type entries for sequences or toast tables.
Commit f7f70d5 left one inconsistency behind: we're still creating pg_type entries for the composite types of sequences and toast tables, but not arrays over those composites. But there seems precious little reason to have named composite types for toast tables, and not much more to have them for sequences (especially given the thought that sequences may someday not be standalone relations at all). So, let's close that inconsistency by removing these composite types, rather than adding arrays for them. This buys back a little bit of the initial pg_type bloat added by the previous patch, and could be a significant savings in a large database with many toast tables. Aside from a small logic rearrangement in heap_create_with_catalog, this patch mostly needs to clean up some places that were assuming that pg_class.reltype always has a valid value. Those are really pre-existing bugs, given that it's documented otherwise; notably, the plpgsql changes fix code that gives "cache lookup failed for type 0" on indexes today. But none of these seem interesting enough to back-patch. Also, remove the pg_dump/pg_upgrade infrastructure for propagating a toast table's pg_type OID into the new database, since we no longer need that. Discussion: https://postgr.es/m/761F1389-C6A8-4C15-80CE-950C961F5341@gmail.com
1 parent a8aaa0c commit f3faf35

File tree

12 files changed

+102
-123
lines changed

12 files changed

+102
-123
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1895,7 +1895,8 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
18951895
</para>
18961896
<para>
18971897
The OID of the data type that corresponds to this table's row type,
1898-
if any (zero for indexes, which have no <structname>pg_type</structname> entry)
1898+
if any (zero for indexes, sequences, and toast tables, which have
1899+
no <structname>pg_type</structname> entry)
18991900
</para></entry>
19001901
</row>
19011902

src/backend/catalog/heap.c

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,9 @@ AddNewRelationTuple(Relation pg_class_desc,
10001000
/* relispartition is always set by updating this tuple later */
10011001
new_rel_reltup->relispartition = false;
10021002

1003-
new_rel_desc->rd_att->tdtypeid = new_type_oid;
1003+
/* fill rd_att's type ID with something sane even if reltype is zero */
1004+
new_rel_desc->rd_att->tdtypeid = new_type_oid ? new_type_oid : RECORDOID;
1005+
new_rel_desc->rd_att->tdtypmod = -1;
10041006

10051007
/* Now build and insert the tuple */
10061008
InsertPgClassTuple(pg_class_desc, new_rel_desc, new_rel_oid,
@@ -1085,6 +1087,7 @@ AddNewRelationType(const char *typeName,
10851087
*
10861088
* Output parameters:
10871089
* typaddress: if not null, gets the object address of the new pg_type entry
1090+
* (this must be null if the relkind is one that doesn't get a pg_type entry)
10881091
*
10891092
* Returns the OID of the new relation
10901093
* --------------------------------
@@ -1118,8 +1121,6 @@ heap_create_with_catalog(const char *relname,
11181121
Oid existing_relid;
11191122
Oid old_type_oid;
11201123
Oid new_type_oid;
1121-
ObjectAddress new_type_addr;
1122-
Oid new_array_oid = InvalidOid;
11231124
TransactionId relfrozenxid;
11241125
MultiXactId relminmxid;
11251126

@@ -1262,44 +1263,46 @@ heap_create_with_catalog(const char *relname,
12621263
new_rel_desc->rd_rel->relrewrite = relrewrite;
12631264

12641265
/*
1265-
* Decide whether to create an array type over the relation's rowtype.
1266-
* Array types are made except where the use of a relation as such is an
1266+
* Decide whether to create a pg_type entry for the relation's rowtype.
1267+
* These types are made except where the use of a relation as such is an
12671268
* implementation detail: toast tables, sequences and indexes.
12681269
*/
12691270
if (!(relkind == RELKIND_SEQUENCE ||
12701271
relkind == RELKIND_TOASTVALUE ||
12711272
relkind == RELKIND_INDEX ||
12721273
relkind == RELKIND_PARTITIONED_INDEX))
1273-
new_array_oid = AssignTypeArrayOid();
1274-
1275-
/*
1276-
* Since defining a relation also defines a complex type, we add a new
1277-
* system type corresponding to the new relation. The OID of the type can
1278-
* be preselected by the caller, but if reltypeid is InvalidOid, we'll
1279-
* generate a new OID for it.
1280-
*
1281-
* NOTE: we could get a unique-index failure here, in case someone else is
1282-
* creating the same type name in parallel but hadn't committed yet when
1283-
* we checked for a duplicate name above.
1284-
*/
1285-
new_type_addr = AddNewRelationType(relname,
1286-
relnamespace,
1287-
relid,
1288-
relkind,
1289-
ownerid,
1290-
reltypeid,
1291-
new_array_oid);
1292-
new_type_oid = new_type_addr.objectId;
1293-
if (typaddress)
1294-
*typaddress = new_type_addr;
1295-
1296-
/*
1297-
* Now make the array type if wanted.
1298-
*/
1299-
if (OidIsValid(new_array_oid))
13001274
{
1275+
Oid new_array_oid;
1276+
ObjectAddress new_type_addr;
13011277
char *relarrayname;
13021278

1279+
/*
1280+
* We'll make an array over the composite type, too. For largely
1281+
* historical reasons, the array type's OID is assigned first.
1282+
*/
1283+
new_array_oid = AssignTypeArrayOid();
1284+
1285+
/*
1286+
* Make the pg_type entry for the composite type. The OID of the
1287+
* composite type can be preselected by the caller, but if reltypeid
1288+
* is InvalidOid, we'll generate a new OID for it.
1289+
*
1290+
* NOTE: we could get a unique-index failure here, in case someone
1291+
* else is creating the same type name in parallel but hadn't
1292+
* committed yet when we checked for a duplicate name above.
1293+
*/
1294+
new_type_addr = AddNewRelationType(relname,
1295+
relnamespace,
1296+
relid,
1297+
relkind,
1298+
ownerid,
1299+
reltypeid,
1300+
new_array_oid);
1301+
new_type_oid = new_type_addr.objectId;
1302+
if (typaddress)
1303+
*typaddress = new_type_addr;
1304+
1305+
/* Now create the array type. */
13031306
relarrayname = makeArrayTypeName(relname, relnamespace);
13041307

13051308
TypeCreate(new_array_oid, /* force the type's OID to this */
@@ -1336,6 +1339,14 @@ heap_create_with_catalog(const char *relname,
13361339

13371340
pfree(relarrayname);
13381341
}
1342+
else
1343+
{
1344+
/* Caller should not be expecting a type to be created. */
1345+
Assert(reltypeid == InvalidOid);
1346+
Assert(typaddress == NULL);
1347+
1348+
new_type_oid = InvalidOid;
1349+
}
13391350

13401351
/*
13411352
* now create an entry in pg_class for the relation.

src/backend/catalog/toasting.c

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@
3434
#include "utils/rel.h"
3535
#include "utils/syscache.h"
3636

37-
/* Potentially set by pg_upgrade_support functions */
38-
Oid binary_upgrade_next_toast_pg_type_oid = InvalidOid;
39-
4037
static void CheckAndCreateToastTable(Oid relOid, Datum reloptions,
4138
LOCKMODE lockmode, bool check);
4239
static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
@@ -135,7 +132,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
135132
Relation toast_rel;
136133
Relation class_rel;
137134
Oid toast_relid;
138-
Oid toast_typid = InvalidOid;
139135
Oid namespaceid;
140136
char toast_relname[NAMEDATALEN];
141137
char toast_idxname[NAMEDATALEN];
@@ -181,8 +177,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
181177
* problem that it might take up an OID that will conflict with some
182178
* old-cluster table we haven't seen yet.
183179
*/
184-
if (!OidIsValid(binary_upgrade_next_toast_pg_class_oid) ||
185-
!OidIsValid(binary_upgrade_next_toast_pg_type_oid))
180+
if (!OidIsValid(binary_upgrade_next_toast_pg_class_oid))
186181
return false;
187182
}
188183

@@ -234,17 +229,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
234229
else
235230
namespaceid = PG_TOAST_NAMESPACE;
236231

237-
/*
238-
* Use binary-upgrade override for pg_type.oid, if supplied. We might be
239-
* in the post-schema-restore phase where we are doing ALTER TABLE to
240-
* create TOAST tables that didn't exist in the old cluster.
241-
*/
242-
if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_toast_pg_type_oid))
243-
{
244-
toast_typid = binary_upgrade_next_toast_pg_type_oid;
245-
binary_upgrade_next_toast_pg_type_oid = InvalidOid;
246-
}
247-
248232
/* Toast table is shared if and only if its parent is. */
249233
shared_relation = rel->rd_rel->relisshared;
250234

@@ -255,7 +239,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
255239
namespaceid,
256240
rel->rd_rel->reltablespace,
257241
toastOid,
258-
toast_typid,
242+
InvalidOid,
259243
InvalidOid,
260244
rel->rd_rel->relowner,
261245
table_relation_toast_am(rel),

src/backend/commands/tablecmds.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11001,8 +11001,8 @@ ATPrepAlterColumnType(List **wqueue,
1100111001
tab->relkind == RELKIND_FOREIGN_TABLE)
1100211002
{
1100311003
/*
11004-
* For composite types, do this check now. Tables will check it later
11005-
* when the table is being rewritten.
11004+
* For composite types and foreign tables, do this check now. Regular
11005+
* tables will check it later when the table is being rewritten.
1100611006
*/
1100711007
find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
1100811008
}
@@ -12564,8 +12564,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
1256412564
/*
1256512565
* Also change the ownership of the table's row type, if it has one
1256612566
*/
12567-
if (tuple_class->relkind != RELKIND_INDEX &&
12568-
tuple_class->relkind != RELKIND_PARTITIONED_INDEX)
12567+
if (OidIsValid(tuple_class->reltype))
1256912568
AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId);
1257012569

1257112570
/*
@@ -15009,9 +15008,10 @@ AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid,
1500915008
AlterRelationNamespaceInternal(classRel, RelationGetRelid(rel), oldNspOid,
1501015009
nspOid, true, objsMoved);
1501115010

15012-
/* Fix the table's row type too */
15013-
AlterTypeNamespaceInternal(rel->rd_rel->reltype,
15014-
nspOid, false, false, objsMoved);
15011+
/* Fix the table's row type too, if it has one */
15012+
if (OidIsValid(rel->rd_rel->reltype))
15013+
AlterTypeNamespaceInternal(rel->rd_rel->reltype,
15014+
nspOid, false, false, objsMoved);
1501515015

1501615016
/* Fix other dependent stuff */
1501715017
if (rel->rd_rel->relkind == RELKIND_RELATION ||
@@ -15206,11 +15206,11 @@ AlterSeqNamespaces(Relation classRel, Relation rel,
1520615206
true, objsMoved);
1520715207

1520815208
/*
15209-
* Sequences have entries in pg_type. We need to be careful to move
15210-
* them to the new namespace, too.
15209+
* Sequences used to have entries in pg_type, but no longer do. If we
15210+
* ever re-instate that, we'll need to move the pg_type entry to the
15211+
* new namespace, too (using AlterTypeNamespaceInternal).
1521115212
*/
15212-
AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
15213-
newNspOid, false, false, objsMoved);
15213+
Assert(RelationGetForm(seqRel)->reltype == InvalidOid);
1521415214

1521515215
/* Now we can close it. Keep the lock till end of transaction. */
1521615216
relation_close(seqRel, NoLock);

src/backend/nodes/makefuncs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,10 @@ makeWholeRowVar(RangeTblEntry *rte,
145145
/* relation: the rowtype is a named composite type */
146146
toid = get_rel_type_id(rte->relid);
147147
if (!OidIsValid(toid))
148-
elog(ERROR, "could not find type OID for relation %u",
149-
rte->relid);
148+
ereport(ERROR,
149+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
150+
errmsg("relation \"%s\" does not have a composite type",
151+
get_rel_name(rte->relid))));
150152
result = makeVar(varno,
151153
InvalidAttrNumber,
152154
toid,

src/backend/utils/adt/pg_upgrade_support.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,6 @@ binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS)
5151
PG_RETURN_VOID();
5252
}
5353

54-
Datum
55-
binary_upgrade_set_next_toast_pg_type_oid(PG_FUNCTION_ARGS)
56-
{
57-
Oid typoid = PG_GETARG_OID(0);
58-
59-
CHECK_IS_BINARY_UPGRADE;
60-
binary_upgrade_next_toast_pg_type_oid = typoid;
61-
62-
PG_RETURN_VOID();
63-
}
64-
6554
Datum
6655
binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)
6756
{

src/backend/utils/cache/relcache.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,9 +506,10 @@ RelationBuildTupleDesc(Relation relation)
506506
AttrMissing *attrmiss = NULL;
507507
int ndef = 0;
508508

509-
/* copy some fields from pg_class row to rd_att */
510-
relation->rd_att->tdtypeid = relation->rd_rel->reltype;
511-
relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
509+
/* fill rd_att's type ID fields (compare heap.c's AddNewRelationTuple) */
510+
relation->rd_att->tdtypeid =
511+
relation->rd_rel->reltype ? relation->rd_rel->reltype : RECORDOID;
512+
relation->rd_att->tdtypmod = -1; /* just to be sure */
512513

513514
constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext,
514515
sizeof(TupleConstr));
@@ -1886,7 +1887,7 @@ formrdesc(const char *relationName, Oid relationReltype,
18861887
relation->rd_att->tdrefcount = 1; /* mark as refcounted */
18871888

18881889
relation->rd_att->tdtypeid = relationReltype;
1889-
relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
1890+
relation->rd_att->tdtypmod = -1; /* just to be sure */
18901891

18911892
/*
18921893
* initialize tuple desc info
@@ -5692,8 +5693,8 @@ load_relcache_init_file(bool shared)
56925693
rel->rd_att = CreateTemplateTupleDesc(relform->relnatts);
56935694
rel->rd_att->tdrefcount = 1; /* mark as refcounted */
56945695

5695-
rel->rd_att->tdtypeid = relform->reltype;
5696-
rel->rd_att->tdtypmod = -1; /* unnecessary, but... */
5696+
rel->rd_att->tdtypeid = relform->reltype ? relform->reltype : RECORDOID;
5697+
rel->rd_att->tdtypmod = -1; /* just to be sure */
56975698

56985699
/* next read all the attribute tuple form data entries */
56995700
has_not_null = false;

src/bin/pg_dump/pg_dump.c

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
272272
PQExpBuffer upgrade_buffer,
273273
Oid pg_type_oid,
274274
bool force_array_type);
275-
static bool binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
275+
static void binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
276276
PQExpBuffer upgrade_buffer, Oid pg_rel_oid);
277277
static void binary_upgrade_set_pg_class_oids(Archive *fout,
278278
PQExpBuffer upgrade_buffer,
@@ -4493,56 +4493,31 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
44934493
destroyPQExpBuffer(upgrade_query);
44944494
}
44954495

4496-
static bool
4496+
static void
44974497
binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
44984498
PQExpBuffer upgrade_buffer,
44994499
Oid pg_rel_oid)
45004500
{
45014501
PQExpBuffer upgrade_query = createPQExpBuffer();
45024502
PGresult *upgrade_res;
45034503
Oid pg_type_oid;
4504-
bool toast_set = false;
45054504

4506-
/*
4507-
* We only support old >= 8.3 for binary upgrades.
4508-
*
4509-
* We purposefully ignore toast OIDs for partitioned tables; the reason is
4510-
* that versions 10 and 11 have them, but 12 does not, so emitting them
4511-
* causes the upgrade to fail.
4512-
*/
45134505
appendPQExpBuffer(upgrade_query,
4514-
"SELECT c.reltype AS crel, t.reltype AS trel "
4506+
"SELECT c.reltype AS crel "
45154507
"FROM pg_catalog.pg_class c "
4516-
"LEFT JOIN pg_catalog.pg_class t ON "
4517-
" (c.reltoastrelid = t.oid AND c.relkind <> '%c') "
45184508
"WHERE c.oid = '%u'::pg_catalog.oid;",
4519-
RELKIND_PARTITIONED_TABLE, pg_rel_oid);
4509+
pg_rel_oid);
45204510

45214511
upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
45224512

45234513
pg_type_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "crel")));
45244514

4525-
binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
4526-
pg_type_oid, false);
4527-
4528-
if (!PQgetisnull(upgrade_res, 0, PQfnumber(upgrade_res, "trel")))
4529-
{
4530-
/* Toast tables do not have pg_type array rows */
4531-
Oid pg_type_toast_oid = atooid(PQgetvalue(upgrade_res, 0,
4532-
PQfnumber(upgrade_res, "trel")));
4533-
4534-
appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type toast oid\n");
4535-
appendPQExpBuffer(upgrade_buffer,
4536-
"SELECT pg_catalog.binary_upgrade_set_next_toast_pg_type_oid('%u'::pg_catalog.oid);\n\n",
4537-
pg_type_toast_oid);
4538-
4539-
toast_set = true;
4540-
}
4515+
if (OidIsValid(pg_type_oid))
4516+
binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
4517+
pg_type_oid, false);
45414518

45424519
PQclear(upgrade_res);
45434520
destroyPQExpBuffer(upgrade_query);
4544-
4545-
return toast_set;
45464521
}
45474522

45484523
static void
@@ -17209,8 +17184,11 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
1720917184
{
1721017185
binary_upgrade_set_pg_class_oids(fout, query,
1721117186
tbinfo->dobj.catId.oid, false);
17212-
binary_upgrade_set_type_oids_by_rel_oid(fout, query,
17213-
tbinfo->dobj.catId.oid);
17187+
17188+
/*
17189+
* In older PG versions a sequence will have a pg_type entry, but v14
17190+
* and up don't use that, so don't attempt to preserve the type OID.
17191+
*/
1721417192
}
1721517193

1721617194
if (tbinfo->is_identity_sequence)

src/include/catalog/binary_upgrade.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
extern PGDLLIMPORT Oid binary_upgrade_next_pg_type_oid;
1818
extern PGDLLIMPORT Oid binary_upgrade_next_array_pg_type_oid;
19-
extern PGDLLIMPORT Oid binary_upgrade_next_toast_pg_type_oid;
2019

2120
extern PGDLLIMPORT Oid binary_upgrade_next_heap_pg_class_oid;
2221
extern PGDLLIMPORT Oid binary_upgrade_next_index_pg_class_oid;

0 commit comments

Comments
 (0)