* ALTER TABLE DETACH PARTITION * * Return the address of the relation that is no longer a partition of rel. * * If concurrent mode is requested, we run in two transactions. A side- * effect is that this command cannot run in a multi-part ALTER TABLE. * Currently, that's enforced by the grammar. * * The strategy for concurrency is to first modify the partition's * pg_inherit catalog row t
| 22157 | * metadata (pg_inherits and pg_class.relpartbounds). |
| 22158 | */ |
| 22159 | static ObjectAddress |
| 22160 | ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, |
| 22161 | RangeVar *name, bool concurrent) |
| 22162 | { |
| 22163 | Relation partRel; |
| 22164 | ObjectAddress address; |
| 22165 | Oid defaultPartOid; |
| 22166 | |
| 22167 | /* |
| 22168 | * We must lock the default partition, because detaching this partition |
| 22169 | * will change its partition constraint. |
| 22170 | */ |
| 22171 | defaultPartOid = |
| 22172 | get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, true)); |
| 22173 | |
| 22174 | /* GPDB_14_MERGE_FIXME: detach partition is not supported now. We need to |
| 22175 | * implement how to control cmd which will be executed in two transactions. |
| 22176 | */ |
| 22177 | if (concurrent) |
| 22178 | ereport(ERROR, |
| 22179 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 22180 | errmsg("cannot support detach partitions concurrently now"))); |
| 22181 | |
| 22182 | if (OidIsValid(defaultPartOid)) |
| 22183 | { |
| 22184 | /* |
| 22185 | * Concurrent detaching when a default partition exists is not |
| 22186 | * supported. The main problem is that the default partition |
| 22187 | * constraint would change. And there's a definitional problem: what |
| 22188 | * should happen to the tuples that are being inserted that belong to |
| 22189 | * the partition being detached? Putting them on the partition being |
| 22190 | * detached would be wrong, since they'd become "lost" after the |
| 22191 | * detaching completes but we cannot put them in the default partition |
| 22192 | * either until we alter its partition constraint. |
| 22193 | * |
| 22194 | * I think we could solve this problem if we effected the constraint |
| 22195 | * change before committing the first transaction. But the lock would |
| 22196 | * have to remain AEL and it would cause concurrent query planning to |
| 22197 | * be blocked, so changing it that way would be even worse. |
| 22198 | */ |
| 22199 | if (concurrent) |
| 22200 | ereport(ERROR, |
| 22201 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
| 22202 | errmsg("cannot detach partitions concurrently when a default partition exists"))); |
| 22203 | LockRelationOid(defaultPartOid, AccessExclusiveLock); |
| 22204 | } |
| 22205 | |
| 22206 | /* |
| 22207 | * In concurrent mode, the partition is locked with share-update-exclusive |
| 22208 | * in the first transaction. This allows concurrent transactions to be |
| 22209 | * doing DML to the partition. |
| 22210 | */ |
| 22211 | partRel = table_openrv(name, concurrent ? ShareUpdateExclusiveLock : |
| 22212 | AccessExclusiveLock); |
| 22213 | |
| 22214 | /* |
| 22215 | * Check inheritance conditions and either delete the pg_inherits row (in |
| 22216 | * non-concurrent mode) or just set the inhdetachpending flag. |
no test coverage detected