aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-07-07 15:43:22 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-07-07 15:43:22 -0400
commitf3faf35f370f558670c8213a08f2683f3811ffc7 (patch)
treea3fc688cca623fc04b98e70c81be137c3bba4003 /src/backend
parenta8aaa0c786b3a27706172cc7979684a122ebb706 (diff)
downloadpostgresql-f3faf35f370f558670c8213a08f2683f3811ffc7.tar.gz
postgresql-f3faf35f370f558670c8213a08f2683f3811ffc7.zip
Don't create pg_type entries for sequences or toast tables.
Commit f7f70d5e2 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
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/heap.c75
-rw-r--r--src/backend/catalog/toasting.c20
-rw-r--r--src/backend/commands/tablecmds.c22
-rw-r--r--src/backend/nodes/makefuncs.c6
-rw-r--r--src/backend/utils/adt/pg_upgrade_support.c11
-rw-r--r--src/backend/utils/cache/relcache.c13
6 files changed, 67 insertions, 80 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index fd04e82b20e..3985326df62 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -1000,7 +1000,9 @@ AddNewRelationTuple(Relation pg_class_desc,
/* relispartition is always set by updating this tuple later */
new_rel_reltup->relispartition = false;
- new_rel_desc->rd_att->tdtypeid = new_type_oid;
+ /* fill rd_att's type ID with something sane even if reltype is zero */
+ new_rel_desc->rd_att->tdtypeid = new_type_oid ? new_type_oid : RECORDOID;
+ new_rel_desc->rd_att->tdtypmod = -1;
/* Now build and insert the tuple */
InsertPgClassTuple(pg_class_desc, new_rel_desc, new_rel_oid,
@@ -1085,6 +1087,7 @@ AddNewRelationType(const char *typeName,
*
* Output parameters:
* typaddress: if not null, gets the object address of the new pg_type entry
+ * (this must be null if the relkind is one that doesn't get a pg_type entry)
*
* Returns the OID of the new relation
* --------------------------------
@@ -1118,8 +1121,6 @@ heap_create_with_catalog(const char *relname,
Oid existing_relid;
Oid old_type_oid;
Oid new_type_oid;
- ObjectAddress new_type_addr;
- Oid new_array_oid = InvalidOid;
TransactionId relfrozenxid;
MultiXactId relminmxid;
@@ -1262,44 +1263,46 @@ heap_create_with_catalog(const char *relname,
new_rel_desc->rd_rel->relrewrite = relrewrite;
/*
- * Decide whether to create an array type over the relation's rowtype.
- * Array types are made except where the use of a relation as such is an
+ * Decide whether to create a pg_type entry for the relation's rowtype.
+ * These types are made except where the use of a relation as such is an
* implementation detail: toast tables, sequences and indexes.
*/
if (!(relkind == RELKIND_SEQUENCE ||
relkind == RELKIND_TOASTVALUE ||
relkind == RELKIND_INDEX ||
relkind == RELKIND_PARTITIONED_INDEX))
- new_array_oid = AssignTypeArrayOid();
-
- /*
- * Since defining a relation also defines a complex type, we add a new
- * system type corresponding to the new relation. The OID of the type can
- * be preselected by the caller, but if reltypeid is InvalidOid, we'll
- * generate a new OID for it.
- *
- * NOTE: we could get a unique-index failure here, in case someone else is
- * creating the same type name in parallel but hadn't committed yet when
- * we checked for a duplicate name above.
- */
- new_type_addr = AddNewRelationType(relname,
- relnamespace,
- relid,
- relkind,
- ownerid,
- reltypeid,
- new_array_oid);
- new_type_oid = new_type_addr.objectId;
- if (typaddress)
- *typaddress = new_type_addr;
-
- /*
- * Now make the array type if wanted.
- */
- if (OidIsValid(new_array_oid))
{
+ Oid new_array_oid;
+ ObjectAddress new_type_addr;
char *relarrayname;
+ /*
+ * We'll make an array over the composite type, too. For largely
+ * historical reasons, the array type's OID is assigned first.
+ */
+ new_array_oid = AssignTypeArrayOid();
+
+ /*
+ * Make the pg_type entry for the composite type. The OID of the
+ * composite type can be preselected by the caller, but if reltypeid
+ * is InvalidOid, we'll generate a new OID for it.
+ *
+ * NOTE: we could get a unique-index failure here, in case someone
+ * else is creating the same type name in parallel but hadn't
+ * committed yet when we checked for a duplicate name above.
+ */
+ new_type_addr = AddNewRelationType(relname,
+ relnamespace,
+ relid,
+ relkind,
+ ownerid,
+ reltypeid,
+ new_array_oid);
+ new_type_oid = new_type_addr.objectId;
+ if (typaddress)
+ *typaddress = new_type_addr;
+
+ /* Now create the array type. */
relarrayname = makeArrayTypeName(relname, relnamespace);
TypeCreate(new_array_oid, /* force the type's OID to this */
@@ -1336,6 +1339,14 @@ heap_create_with_catalog(const char *relname,
pfree(relarrayname);
}
+ else
+ {
+ /* Caller should not be expecting a type to be created. */
+ Assert(reltypeid == InvalidOid);
+ Assert(typaddress == NULL);
+
+ new_type_oid = InvalidOid;
+ }
/*
* now create an entry in pg_class for the relation.
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 3f7ab8d389b..8b8888af5ed 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -34,9 +34,6 @@
#include "utils/rel.h"
#include "utils/syscache.h"
-/* Potentially set by pg_upgrade_support functions */
-Oid binary_upgrade_next_toast_pg_type_oid = InvalidOid;
-
static void CheckAndCreateToastTable(Oid relOid, Datum reloptions,
LOCKMODE lockmode, bool check);
static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
@@ -135,7 +132,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
Relation toast_rel;
Relation class_rel;
Oid toast_relid;
- Oid toast_typid = InvalidOid;
Oid namespaceid;
char toast_relname[NAMEDATALEN];
char toast_idxname[NAMEDATALEN];
@@ -181,8 +177,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
* problem that it might take up an OID that will conflict with some
* old-cluster table we haven't seen yet.
*/
- if (!OidIsValid(binary_upgrade_next_toast_pg_class_oid) ||
- !OidIsValid(binary_upgrade_next_toast_pg_type_oid))
+ if (!OidIsValid(binary_upgrade_next_toast_pg_class_oid))
return false;
}
@@ -234,17 +229,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
else
namespaceid = PG_TOAST_NAMESPACE;
- /*
- * Use binary-upgrade override for pg_type.oid, if supplied. We might be
- * in the post-schema-restore phase where we are doing ALTER TABLE to
- * create TOAST tables that didn't exist in the old cluster.
- */
- if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_toast_pg_type_oid))
- {
- toast_typid = binary_upgrade_next_toast_pg_type_oid;
- binary_upgrade_next_toast_pg_type_oid = InvalidOid;
- }
-
/* Toast table is shared if and only if its parent is. */
shared_relation = rel->rd_rel->relisshared;
@@ -255,7 +239,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
namespaceid,
rel->rd_rel->reltablespace,
toastOid,
- toast_typid,
+ InvalidOid,
InvalidOid,
rel->rd_rel->relowner,
table_relation_toast_am(rel),
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index f79044f39fc..42330692e76 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -11001,8 +11001,8 @@ ATPrepAlterColumnType(List **wqueue,
tab->relkind == RELKIND_FOREIGN_TABLE)
{
/*
- * For composite types, do this check now. Tables will check it later
- * when the table is being rewritten.
+ * For composite types and foreign tables, do this check now. Regular
+ * tables will check it later when the table is being rewritten.
*/
find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
}
@@ -12564,8 +12564,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
/*
* Also change the ownership of the table's row type, if it has one
*/
- if (tuple_class->relkind != RELKIND_INDEX &&
- tuple_class->relkind != RELKIND_PARTITIONED_INDEX)
+ if (OidIsValid(tuple_class->reltype))
AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId);
/*
@@ -15009,9 +15008,10 @@ AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid,
AlterRelationNamespaceInternal(classRel, RelationGetRelid(rel), oldNspOid,
nspOid, true, objsMoved);
- /* Fix the table's row type too */
- AlterTypeNamespaceInternal(rel->rd_rel->reltype,
- nspOid, false, false, objsMoved);
+ /* Fix the table's row type too, if it has one */
+ if (OidIsValid(rel->rd_rel->reltype))
+ AlterTypeNamespaceInternal(rel->rd_rel->reltype,
+ nspOid, false, false, objsMoved);
/* Fix other dependent stuff */
if (rel->rd_rel->relkind == RELKIND_RELATION ||
@@ -15206,11 +15206,11 @@ AlterSeqNamespaces(Relation classRel, Relation rel,
true, objsMoved);
/*
- * Sequences have entries in pg_type. We need to be careful to move
- * them to the new namespace, too.
+ * Sequences used to have entries in pg_type, but no longer do. If we
+ * ever re-instate that, we'll need to move the pg_type entry to the
+ * new namespace, too (using AlterTypeNamespaceInternal).
*/
- AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
- newNspOid, false, false, objsMoved);
+ Assert(RelationGetForm(seqRel)->reltype == InvalidOid);
/* Now we can close it. Keep the lock till end of transaction. */
relation_close(seqRel, NoLock);
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index b442b5a29ef..49de285f01e 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -145,8 +145,10 @@ makeWholeRowVar(RangeTblEntry *rte,
/* relation: the rowtype is a named composite type */
toid = get_rel_type_id(rte->relid);
if (!OidIsValid(toid))
- elog(ERROR, "could not find type OID for relation %u",
- rte->relid);
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("relation \"%s\" does not have a composite type",
+ get_rel_name(rte->relid))));
result = makeVar(varno,
InvalidAttrNumber,
toid,
diff --git a/src/backend/utils/adt/pg_upgrade_support.c b/src/backend/utils/adt/pg_upgrade_support.c
index 18f2ee8226c..14d9eb2b5b3 100644
--- a/src/backend/utils/adt/pg_upgrade_support.c
+++ b/src/backend/utils/adt/pg_upgrade_support.c
@@ -52,17 +52,6 @@ binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS)
}
Datum
-binary_upgrade_set_next_toast_pg_type_oid(PG_FUNCTION_ARGS)
-{
- Oid typoid = PG_GETARG_OID(0);
-
- CHECK_IS_BINARY_UPGRADE;
- binary_upgrade_next_toast_pg_type_oid = typoid;
-
- PG_RETURN_VOID();
-}
-
-Datum
binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)
{
Oid reloid = PG_GETARG_OID(0);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0b9eb00d2de..a2453cf1f42 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -506,9 +506,10 @@ RelationBuildTupleDesc(Relation relation)
AttrMissing *attrmiss = NULL;
int ndef = 0;
- /* copy some fields from pg_class row to rd_att */
- relation->rd_att->tdtypeid = relation->rd_rel->reltype;
- relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
+ /* fill rd_att's type ID fields (compare heap.c's AddNewRelationTuple) */
+ relation->rd_att->tdtypeid =
+ relation->rd_rel->reltype ? relation->rd_rel->reltype : RECORDOID;
+ relation->rd_att->tdtypmod = -1; /* just to be sure */
constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext,
sizeof(TupleConstr));
@@ -1886,7 +1887,7 @@ formrdesc(const char *relationName, Oid relationReltype,
relation->rd_att->tdrefcount = 1; /* mark as refcounted */
relation->rd_att->tdtypeid = relationReltype;
- relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
+ relation->rd_att->tdtypmod = -1; /* just to be sure */
/*
* initialize tuple desc info
@@ -5692,8 +5693,8 @@ load_relcache_init_file(bool shared)
rel->rd_att = CreateTemplateTupleDesc(relform->relnatts);
rel->rd_att->tdrefcount = 1; /* mark as refcounted */
- rel->rd_att->tdtypeid = relform->reltype;
- rel->rd_att->tdtypmod = -1; /* unnecessary, but... */
+ rel->rd_att->tdtypeid = relform->reltype ? relform->reltype : RECORDOID;
+ rel->rd_att->tdtypmod = -1; /* just to be sure */
/* next read all the attribute tuple form data entries */
has_not_null = false;