* Disallow ALTER TABLE (and similar commands) when the current backend has * any open reference to the target table besides the one just acquired by * the calling command; this implies there's an open cursor or active plan. * We need this check because our lock doesn't protect us against stomping * on our own foot, only other people's feet! * * For ALTER TABLE, the only case known to cause s
| 4705 | * The statement name (eg, "ALTER TABLE") is passed for use in error messages. |
| 4706 | */ |
| 4707 | void |
| 4708 | CheckTableNotInUse(Relation rel, const char *stmt) |
| 4709 | { |
| 4710 | int expected_refcnt; |
| 4711 | |
| 4712 | expected_refcnt = rel->rd_isnailed ? 2 : 1; |
| 4713 | |
| 4714 | /* |
| 4715 | * XXX For a bitmap index, since vacuum (or vacuum full) is currently done through |
| 4716 | * reindex_index, the reference count could be 2 (or 3). We set it |
| 4717 | * here until vacuum is done properly. |
| 4718 | */ |
| 4719 | if (expected_refcnt == 1 && |
| 4720 | RelationIsBitmapIndex(rel) && |
| 4721 | (rel->rd_refcnt == 2 || rel->rd_refcnt == 3)) |
| 4722 | expected_refcnt = rel->rd_refcnt; |
| 4723 | |
| 4724 | if (rel->rd_refcnt != expected_refcnt) |
| 4725 | ereport(ERROR, |
| 4726 | (errcode(ERRCODE_OBJECT_IN_USE), |
| 4727 | /* translator: first %s is a SQL command, eg ALTER TABLE */ |
| 4728 | errmsg("cannot %s \"%s\" because it is being used by active queries in this session", |
| 4729 | stmt, RelationGetRelationName(rel)))); |
| 4730 | |
| 4731 | if (rel->rd_rel->relkind != RELKIND_INDEX && |
| 4732 | rel->rd_rel->relkind != RELKIND_PARTITIONED_INDEX && |
| 4733 | AfterTriggerPendingOnRel(RelationGetRelid(rel))) |
| 4734 | ereport(ERROR, |
| 4735 | (errcode(ERRCODE_OBJECT_IN_USE), |
| 4736 | /* translator: first %s is a SQL command, eg ALTER TABLE */ |
| 4737 | errmsg("cannot %s \"%s\" because it has pending trigger events", |
| 4738 | stmt, RelationGetRelationName(rel)))); |
| 4739 | } |
| 4740 | |
| 4741 | /* |
| 4742 | * AlterTableLookupRelation |
no test coverage detected