From 2e1527b479b352c862c83fa1cf6d65d6f40df2c4 Mon Sep 17 00:00:00 2001 From: Tim Chang Date: Tue, 24 Sep 2024 12:44:19 -0400 Subject: [PATCH] Add temp OID support for type, index, and constraint creation (#335) Normal OIDs were still being consumed in some cases during temp table creation even with temp oid buffer on. To fix this, ensure that the appropriate temp table dependent objects also use temp OID. - Redirect type creation functions to use temp OID when it's a TSQL temp table. - Redirect constraint creation to use temp OID in those cases as well. - Remove workaround for indexes on temp tables. Previously, we needed to force indexes on temp tables to consume normal OIDs. With changes described in lines 1+2 above, we can now remove the workaround added in OID Wraparound #232 and properly allow indexes to use temp oid buffer. Task: BABEL-4750 Signed-off-by: Tim Chang --- src/backend/catalog/catalog.c | 4 ++-- src/backend/catalog/heap.c | 28 +++++++++++++++++++++-- src/backend/catalog/index.c | 7 +----- src/backend/catalog/pg_constraint.c | 12 ++++++++-- src/backend/commands/tablecmds.c | 2 +- src/backend/utils/cache/relcache.c | 2 +- src/backend/utils/misc/queryenvironment.c | 19 +++++++++++++++ src/include/catalog/catalog.h | 3 +-- src/include/utils/queryenvironment.h | 3 +++ 9 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 4a5cdf745bf..9906d43e632 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -540,7 +540,7 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) * created by bootstrap have preassigned OIDs, so there's no need. */ RelFileNumber -GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence, bool override_temp) +GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence) { RelFileLocatorBackend rlocator; char *rpath; @@ -584,7 +584,7 @@ GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence, b rlocator.backend = backend; use_bbf_oid_buffer = (relpersistence == RELPERSISTENCE_TEMP && sql_dialect == SQL_DIALECT_TSQL - && GetNewTempOidWithIndex_hook && temp_oid_buffer_size > 0 && !override_temp); + && GetNewTempOidWithIndex_hook && temp_oid_buffer_size > 0); do { diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 0d04af9658d..00c704f5cbe 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -72,6 +72,7 @@ #include "storage/predicate.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/guc.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -1310,7 +1311,7 @@ heap_create_with_catalog(const char *relname, if (!OidIsValid(relid)) relid = GetNewRelFileNumber(reltablespace, pg_class_desc, - relpersistence, false); + relpersistence); } /* @@ -1409,8 +1410,31 @@ heap_create_with_catalog(const char *relname, /* * We'll make an array over the composite type, too. For largely * historical reasons, the array type's OID is assigned first. + * + * For temp tables, we use temp OID assignment code here as well. */ - new_array_oid = AssignTypeArrayOid(); + if (is_enr && useTempOidBuffer()) + { + Relation pg_type; + + /* We should not be creating TSQL Temp Tables in pg_upgrade. */ + Assert(!IsBinaryUpgrade); + + pg_type = table_open(TypeRelationId, AccessShareLock); + new_array_oid = GetNewTempOidWithIndex_hook(pg_type, TypeOidIndexId, Anum_pg_type_oid); + + Assert(!OidIsValid(reltypeid)); + + /* + * We also assign reltypeid here. It would usually be assigned during AddNewRelationType + * if the value provided is InvalidOid. Since we are providing a value, it won't + * try to call GetNewOidWithIndex. + */ + reltypeid = GetNewTempOidWithIndex_hook(pg_type, TypeOidIndexId, Anum_pg_type_oid); + table_close(pg_type, AccessShareLock); + } + else + new_array_oid = AssignTypeArrayOid(); /* * Make the pg_type entry for the composite type. The OID of the diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 88e289a1999..db58faac987 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -962,12 +962,7 @@ index_create(Relation heapRelation, } else { - /* - * Index OIDs must be kept in normal OID range due to deletion issues. - * Since deletion is sorted by OID, adding indexes to temp OID range - * causes deletion order issues. - */ - indexRelationId = GetNewRelFileNumber(tableSpaceId, pg_class, relpersistence, is_enr); + indexRelationId = GetNewRelFileNumber(tableSpaceId, pg_class, relpersistence); } } diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index e5c9c6dbe31..d7e7603bc4e 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -22,16 +22,20 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/namespace.h" #include "catalog/objectaccess.h" #include "catalog/pg_constraint.h" #include "catalog/pg_operator.h" #include "catalog/pg_type.h" #include "commands/defrem.h" #include "commands/tablecmds.h" +#include "parser/parser.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/guc.h" #include "utils/lsyscache.h" +#include "utils/queryenvironment.h" #include "utils/rel.h" #include "utils/syscache.h" @@ -172,8 +176,12 @@ CreateConstraintEntry(const char *constraintName, values[i] = (Datum) NULL; } - conOid = GetNewOidWithIndex(conDesc, ConstraintOidIndexId, - Anum_pg_constraint_oid); + if (useTempOidBufferForOid(relId) && isTempNamespace(constraintNamespace)) + conOid = GetNewTempOidWithIndex_hook(conDesc, ConstraintOidIndexId, + Anum_pg_constraint_oid); + else + conOid = GetNewOidWithIndex(conDesc, ConstraintOidIndexId, + Anum_pg_constraint_oid); values[Anum_pg_constraint_oid - 1] = ObjectIdGetDatum(conOid); values[Anum_pg_constraint_conname - 1] = NameGetDatum(&cname); values[Anum_pg_constraint_connamespace - 1] = ObjectIdGetDatum(constraintNamespace); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f67b6f4c6a3..b14cc9eb7eb 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -14707,7 +14707,7 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) * need to allocate a new one in the new tablespace. */ newrelfilenumber = GetNewRelFileNumber(newTableSpace, NULL, - rel->rd_rel->relpersistence, false); + rel->rd_rel->relpersistence); /* Open old and new relation */ newrlocator = rel->rd_locator; diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index a9b8aa9c09b..169f1363863 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -3722,7 +3722,7 @@ RelationSetNewRelfilenumber(Relation relation, char persistence) { /* Allocate a new relfilenumber */ newrelfilenumber = GetNewRelFileNumber(relation->rd_rel->reltablespace, - NULL, persistence, false); + NULL, persistence); } else if (relation->rd_rel->relkind == RELKIND_INDEX) { diff --git a/src/backend/utils/misc/queryenvironment.c b/src/backend/utils/misc/queryenvironment.c index 63b0fc1bec3..5ad05618329 100644 --- a/src/backend/utils/misc/queryenvironment.c +++ b/src/backend/utils/misc/queryenvironment.c @@ -1442,6 +1442,25 @@ void ENRRollbackSubtransaction(SubTransactionId subid, QueryEnvironment *queryEn MemoryContextSwitchTo(oldcxt); } +/* + * Simple check for whether to use temp OID buffer. + */ +bool useTempOidBuffer() +{ + return sql_dialect == SQL_DIALECT_TSQL + && GetNewTempOidWithIndex_hook + && temp_oid_buffer_size > 0; +} + +/* Simple check for whether to use temp OID buffer given an existing OID. */ +bool useTempOidBufferForOid(Oid relId) +{ + return sql_dialect == SQL_DIALECT_TSQL + && GetNewTempOidWithIndex_hook + && temp_oid_buffer_size > 0 + && get_ENR_withoid(currentQueryEnv, relId, ENR_TSQL_TEMP); +} + /* * Drop all the temp tables registered as ENR in the given query environment. */ diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 029ce8c80ee..ef91723bd0d 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -42,8 +42,7 @@ extern Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn); extern RelFileNumber GetNewRelFileNumber(Oid reltablespace, Relation pg_class, - char relpersistence, - bool override_temp); + char relpersistence); typedef Oid (*GetNewTempObjectId_hook_type) (void); extern GetNewTempObjectId_hook_type GetNewTempObjectId_hook; diff --git a/src/include/utils/queryenvironment.h b/src/include/utils/queryenvironment.h index d2bfad5f443..9c0eaf8aded 100644 --- a/src/include/utils/queryenvironment.h +++ b/src/include/utils/queryenvironment.h @@ -150,6 +150,9 @@ extern void ENRCommitChanges(QueryEnvironment *queryEnv); extern void ENRRollbackChanges(QueryEnvironment *queryEnv); extern void ENRRollbackSubtransaction(SubTransactionId subid, QueryEnvironment *queryEnv); +extern bool useTempOidBuffer(void); +extern bool useTempOidBufferForOid(Oid relId); + typedef EphemeralNamedRelation (*pltsql_get_tsql_enr_from_oid_hook_type) (Oid oid); extern PGDLLIMPORT pltsql_get_tsql_enr_from_oid_hook_type pltsql_get_tsql_enr_from_oid_hook;