* RelationSetNewRelfilenode * * Assign a new relfilenode (physical file name), and possibly a new * persistence setting, to the relation. * * This allows a full rewrite of the relation to be done with transactional * safety (since the filenode assignment can be rolled back). Note however * that there is no simple way to access the relation's old data for the * remainder of the current tra
| 3893 | * Caller must already hold exclusive lock on the relation. |
| 3894 | */ |
| 3895 | void |
| 3896 | RelationSetNewRelfilenode(Relation relation, char persistence) |
| 3897 | { |
| 3898 | Oid newrelfilenode; |
| 3899 | Relation pg_class; |
| 3900 | HeapTuple tuple; |
| 3901 | Form_pg_class classform; |
| 3902 | MultiXactId minmulti = InvalidMultiXactId; |
| 3903 | TransactionId freezeXid = InvalidTransactionId; |
| 3904 | RelFileNode newrnode; |
| 3905 | |
| 3906 | /* Allocate a new relfilenode */ |
| 3907 | newrelfilenode = GetNewRelFileNode(relation->rd_rel->reltablespace, NULL, |
| 3908 | persistence); |
| 3909 | |
| 3910 | /* |
| 3911 | * Get a writable copy of the pg_class tuple for the given relation. |
| 3912 | */ |
| 3913 | pg_class = table_open(RelationRelationId, RowExclusiveLock); |
| 3914 | |
| 3915 | tuple = SearchSysCacheCopy1(RELOID, |
| 3916 | ObjectIdGetDatum(RelationGetRelid(relation))); |
| 3917 | if (!HeapTupleIsValid(tuple)) |
| 3918 | elog(ERROR, "could not find tuple for relation %u", |
| 3919 | RelationGetRelid(relation)); |
| 3920 | classform = (Form_pg_class) GETSTRUCT(tuple); |
| 3921 | |
| 3922 | /* |
| 3923 | * Schedule unlinking of the old storage at transaction commit. |
| 3924 | */ |
| 3925 | RelationDropStorage(relation); |
| 3926 | |
| 3927 | |
| 3928 | /* |
| 3929 | * Create storage for the main fork of the new relfilenode. If it's a |
| 3930 | * table-like object, call into the table AM to do so, which'll also |
| 3931 | * create the table's init fork if needed. |
| 3932 | * |
| 3933 | * NOTE: If relevant for the AM, any conflict in relfilenode value will be |
| 3934 | * caught here, if GetNewRelFileNode messes up for any reason. |
| 3935 | */ |
| 3936 | newrnode = relation->rd_node; |
| 3937 | newrnode.relNode = newrelfilenode; |
| 3938 | |
| 3939 | switch (relation->rd_rel->relkind) |
| 3940 | { |
| 3941 | case RELKIND_INDEX: |
| 3942 | case RELKIND_SEQUENCE: |
| 3943 | { |
| 3944 | /* handle these directly, at least for now */ |
| 3945 | SMgrRelation srel; |
| 3946 | |
| 3947 | srel = RelationCreateStorage(newrnode, persistence, |
| 3948 | 0 /* default storage implementation */, |
| 3949 | relation); |
| 3950 | smgrclose(srel); |
| 3951 | } |
| 3952 | break; |
no test coverage detected