From dea6b55a32571369820002b95dcabde3c2cdc317 Mon Sep 17 00:00:00 2001 From: Alexey Kondratov Date: Wed, 23 Sep 2020 18:21:16 +0300 Subject: [PATCH v34 5/8] Refactor and reuse set_rel_tablespace() --- src/backend/catalog/index.c | 73 ++++++++++++++++++++------------ src/backend/commands/indexcmds.c | 35 --------------- src/include/catalog/index.h | 2 + 3 files changed, 49 insertions(+), 61 deletions(-) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index aaac698eb0..8911959336 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; @@ -3722,26 +3721,11 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, options->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 && - (options->tablespaceOid != oldTablespaceOid || - (options->tablespaceOid == MyDatabaseTableSpace && OidIsValid(oldTablespaceOid)))) + set_rel_tablespace(indexId, options->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 @@ -3749,14 +3733,6 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, */ RelationDropStorage(iRel); - /* Update the pg_class row */ - rd_rel->reltablespace = options->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 */ @@ -4064,6 +4040,51 @@ reindex_relation(Oid relid, int flags, ReindexOptions *options) 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 849fecc861..2379d7d1a8 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -2930,41 +2930,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 5db1d70064..9543ca9c61 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -150,6 +150,8 @@ extern Oid IndexGetRelation(Oid indexId, bool missing_ok); extern void reindex_index(Oid indexId, bool skip_constraint_checks, char relpersistence, ReindexOptions *options); +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