From 520d1c54d6988d69768178b4abf03c5837654b9a Mon Sep 17 00:00:00 2001 From: Alexey Kondratov Date: Wed, 23 Sep 2020 18:21:16 +0300 Subject: [PATCH v31 3/5] Refactor and reuse set_rel_tablespace() --- src/backend/catalog/index.c | 74 ++++++++++++++++++++------------ src/backend/commands/indexcmds.c | 35 --------------- src/include/catalog/index.h | 2 + 3 files changed, 49 insertions(+), 62 deletions(-) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 532c11e9dd..b317f556df 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3607,7 +3607,6 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, Relation iRel, heapRelation; Oid heapId; - Oid oldTablespaceOid; IndexInfo *indexInfo; volatile bool skipped_constraint = false; PGRUsage ru0; @@ -3723,41 +3722,17 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, tablespaceOid = InvalidOid; /* - * Set the new tablespace for the relation. Do that only in the - * case where the reindex caller wishes to enforce a new tablespace. + * Set the new tablespace for the relation if requested. */ - oldTablespaceOid = iRel->rd_rel->reltablespace; if (set_tablespace && - (tablespaceOid != oldTablespaceOid || - (tablespaceOid == MyDatabaseTableSpace && OidIsValid(oldTablespaceOid)))) + set_rel_tablespace(indexId, tablespaceOid)) { - Relation pg_class; - Form_pg_class rd_rel; - HeapTuple tuple; - - /* First get a modifiable copy of the relation's pg_class row */ - pg_class = table_open(RelationRelationId, RowExclusiveLock); - - tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(indexId)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", indexId); - rd_rel = (Form_pg_class) GETSTRUCT(tuple); - /* * Mark the relation as ready to be dropped at transaction commit, * before making visible the new tablespace change so as this won't * miss things. */ RelationDropStorage(iRel); - - /* Update the pg_class row */ - rd_rel->reltablespace = tablespaceOid; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - - heap_freetuple(tuple); - - table_close(pg_class, RowExclusiveLock); - RelationAssumeNewRelfilenode(iRel); /* Make sure the reltablespace change is visible */ @@ -4063,6 +4038,51 @@ reindex_relation(Oid relid, int flags, int options, Oid tablespaceOid) return result; } +/* + * set_rel_tablespace - modify relation tablespace in the pg_class entry. + * + * 'reloid' is an Oid of relation to be modified. + * 'tablespaceOid' is an Oid of new tablespace. + * + * Catalog modification is done only if tablespaceOid is different from + * the currently set. Returned bool value is indicating whether any changes + * were made or not. + */ +bool +set_rel_tablespace(Oid reloid, Oid tablespaceOid) +{ + Relation pg_class; + HeapTuple tuple; + Form_pg_class rd_rel; + bool changed = false; + Oid oldTablespaceOid; + + /* Get a modifiable copy of the relation's pg_class row. */ + pg_class = table_open(RelationRelationId, RowExclusiveLock); + + tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(reloid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for relation %u", reloid); + rd_rel = (Form_pg_class) GETSTRUCT(tuple); + + /* No work if no change in tablespace. */ + oldTablespaceOid = rd_rel->reltablespace; + if (tablespaceOid != oldTablespaceOid || + (tablespaceOid == MyDatabaseTableSpace && OidIsValid(oldTablespaceOid))) + { + /* Update the pg_class row. */ + rd_rel->reltablespace = (tablespaceOid == MyDatabaseTableSpace) ? + InvalidOid : tablespaceOid; + CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + + changed = true; + } + + heap_freetuple(tuple); + table_close(pg_class, RowExclusiveLock); + + return changed; +} /* ---------------------------------------------------------------- * System index reindexing support diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 59111b59d8..e16dd2e8a0 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -2933,41 +2933,6 @@ reindex_error_callback(void *arg) errinfo->relnamespace, errinfo->relname); } -/* - * This is mostly duplicating ATExecSetTableSpaceNoStorage, - * which should maybe be factored out to a library function. - */ -static void -set_rel_tablespace(Oid reloid, Oid tablespaceOid) -{ - Relation pg_class; - HeapTuple tuple; - Form_pg_class rd_rel; - Oid oldTablespaceOid; - - /* Get a modifiable copy of the relation's pg_class row */ - pg_class = table_open(RelationRelationId, RowExclusiveLock); - - tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(reloid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", reloid); - rd_rel = (Form_pg_class) GETSTRUCT(tuple); - - /* No work if no change in tablespace. */ - oldTablespaceOid = rd_rel->reltablespace; - if (tablespaceOid != oldTablespaceOid || - (tablespaceOid == MyDatabaseTableSpace && OidIsValid(oldTablespaceOid))) - { - /* Update the pg_class row */ - rd_rel->reltablespace = (tablespaceOid == MyDatabaseTableSpace) ? - InvalidOid : tablespaceOid; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - } - - heap_freetuple(tuple); - table_close(pg_class, RowExclusiveLock); -} - /* * ReindexPartitions * diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 178ddce63c..14af380c5f 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -149,6 +149,8 @@ extern Oid IndexGetRelation(Oid indexId, bool missing_ok); extern void reindex_index(Oid indexId, bool skip_constraint_checks, char relpersistence, int options, Oid tablespaceOid); +extern bool set_rel_tablespace(Oid reloid, Oid tablespaceOid); + /* Flag bits for reindex_relation(): */ #define REINDEX_REL_PROCESS_TOAST 0x01 #define REINDEX_REL_SUPPRESS_INDEX_USE 0x02 -- 2.17.0