From 39880842d7af31dcbfcffe7219250b31102955d5 Mon Sep 17 00:00:00 2001 From: Alexey Kondratov Date: Wed, 20 Jan 2021 20:21:12 +0300 Subject: [PATCH v5 1/2] Extract common part from ATExecSetTableSpaceNoStorage for a future usage --- src/backend/commands/tablecmds.c | 95 +++++++++++++++++++------------- src/include/commands/tablecmds.h | 2 + 2 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 8687e9a97c..ec9c440e4e 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -13291,6 +13291,59 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) list_free(reltoastidxids); } +/* + * SetRelationTableSpace - 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. Note that caller is responsible for doing + * CommandCounterIncrement() to make tablespace changes visible. + */ +bool +SetRelationTableSpace(Oid reloid, Oid tablespaceOid) +{ + Relation pg_class; + HeapTuple tuple; + Form_pg_class rd_rel; + bool changed = false; + + /* 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); + + /* MyDatabaseTableSpace is stored as InvalidOid. */ + if (tablespaceOid == MyDatabaseTableSpace) + tablespaceOid = InvalidOid; + + /* No work if no change in tablespace. */ + if (tablespaceOid != rd_rel->reltablespace) + { + /* Update the pg_class row. */ + rd_rel->reltablespace = tablespaceOid; + CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + + /* Record dependency on tablespace. */ + changeDependencyOnTablespace(RelationRelationId, + reloid, rd_rel->reltablespace); + + changed = true; + } + + InvokeObjectPostAlterHook(RelationRelationId, reloid, 0); + + heap_freetuple(tuple); + table_close(pg_class, RowExclusiveLock); + + return changed; +} + /* * Special handling of ALTER TABLE SET TABLESPACE for relations with no * storage that have an interest in preserving tablespace. @@ -13301,10 +13354,6 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) static void ATExecSetTableSpaceNoStorage(Relation rel, Oid newTableSpace) { - HeapTuple tuple; - Oid oldTableSpace; - Relation pg_class; - Form_pg_class rd_rel; Oid reloid = RelationGetRelid(rel); /* @@ -13319,41 +13368,9 @@ ATExecSetTableSpaceNoStorage(Relation rel, Oid newTableSpace) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("only shared relations can be placed in pg_global tablespace"))); - /* - * No work if no change in tablespace. - */ - oldTableSpace = rel->rd_rel->reltablespace; - if (newTableSpace == oldTableSpace || - (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0)) - { - InvokeObjectPostAlterHook(RelationRelationId, reloid, 0); - return; - } - - /* 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); - - /* update the pg_class row */ - rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - - /* Record dependency on tablespace */ - changeDependencyOnTablespace(RelationRelationId, - reloid, rd_rel->reltablespace); - - InvokeObjectPostAlterHook(RelationRelationId, reloid, 0); - - heap_freetuple(tuple); - - table_close(pg_class, RowExclusiveLock); - - /* Make sure the reltablespace change is visible */ - CommandCounterIncrement(); + if (SetRelationTableSpace(reloid, newTableSpace)) + /* Make sure the reltablespace change is visible */ + CommandCounterIncrement(); } /* diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 08c463d3c4..4ee7853027 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -61,6 +61,8 @@ extern void ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_ extern void SetRelationHasSubclass(Oid relationId, bool relhassubclass); +extern bool SetRelationTableSpace(Oid reloid, Oid tablespaceOid); + extern ObjectAddress renameatt(RenameStmt *stmt); extern ObjectAddress RenameConstraint(RenameStmt *stmt); base-commit: 881933f194221abcce07fb134ebe8685e5bb58dd -- 2.20.1