cockroachdb / cockroachdb/cockroach

sql: ALTER DATABASE/SCHEMA ... RENAME is incorrectly blocked by a dependent trigger

Open
#172,756 2 comments 0 reactions 0 assignees View on GitHub
A-schema-descriptors A-sql-trigger C-bug O-agent O-support T-sql-foundations
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

**Describe the problem**

`ALTER DATABASE ... RENAME` (and `ALTER SCHEMA ... RENAME`) fails when a table in the database/schema has a **trigger** whose function references another table in the same database/schema. The rename is rejected as though a view/function query rewrite were required, but a database/schema rename only changes the name prefix — it does not rename any object referenced inside the trigger — so it should be allowed (the same way an ordinary FK does not block the rename).

A customer on v25.4.5 hit this while renaming a database. With a database `db` containing tables `parent` and `child` (where `child` has a trigger whose function references `parent`):

```
> ALTER DATABASE db RENAME TO db2;
ERROR: cannot rename database because relation "db.public.child" depends on relation "db.public.parent"
SQLSTATE: 2BP01
HINT: consider dropping "db.public.child" first
```

`SHOW CREATE TABLE` on the "dependent" table showed only ordinary FKs (which do **not** block renames), which is what made this confusing — `SHOW CREATE TABLE` does not display triggers. The actual blocker is a trigger on the child table whose function references the parent table.

**To Reproduce**

Reproduced on master (`v26.4.0-alpha` dev build):

```sql
CREATE DATABASE db;
USE db;
CREATE TABLE parent (id INT PRIMARY KEY);
CREATE TABLE child (id INT PRIMARY KEY);
CREATE FUNCTION f() RETURNS TRIGGER LANGUAGE PLpgSQL AS $$
DECLARE n INT;
BEGIN SELECT count(*) INTO n FROM parent; RETURN NEW; END;
$$;
CREATE TRIGGER t BEFORE INSERT ON child FOR EACH ROW EXECUTE FUNCTION f();

ALTER DATABASE db RENAME TO db2;
```

produces:

```
ERROR: cannot rename database because relation "db.public.child" depends on relation "db.public.parent"
SQLSTATE: 2BP01
HINT: consider dropping "db.public.child" first
```

`ALTER SCHEMA ... RENAME` is affected identically (`cannot rename schema because relation "d.sc.child" depends on relation "d.sc.parent"`).

Behavior isolating the cause (all verified):
- plain FK only, no trigger → rename **succeeds**
- add the trigger above → rename **fails** with the error
- drop the FK but keep the trigger → still **fails**
- drop the trigger → **succeeds**

**Expected behavior**

The rename should succeed. Like a plain FK, a trigger should not block a database/schema rename: the rename changes only the name prefix, not any identifier referenced inside the trigger body.

**Root cause**

[`maybeFailOnDependentDescInRename`](https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/rename_database.go) (in `pkg/sql/rename_database.go`, also called from `pkg/sql/alter_schema.go`) iterates each table's `dependedOnBy` back-references and returns an error on *any* of them, skipping only sequences. A trigger records a dependency in the referenced table's `dependedOnBy` (the table holding the trigger, `child`, appears in `parent`'s `dependedOnBy` — hence the "child depends on parent" wording), so a trigger trips the guard the same as a view or function.

**Relationship to other issues**

- This is **not** #10083 and should not be scoped to it. #10083 tracks removing rename restrictions for objects whose stored query references another object **by name** — renaming the *table/column* requires rewriting that stored query, which is hard. A **database/schema** rename never renames a referenced identifier — only the prefix changes — so this is a smaller, separable fix that does not depend on #10083.
- Related to #83233 (referencing objects by ID rather than name in function bodies).

**Note on scope:** a trigger may still need special handling if its function body references a database/schema name *explicitly*; that case should be considered when scoping the fix.

**Environment**
- CockroachDB version: v25.4.5 (also reproduces on master)
- Discovered via a support escalation

**Additional context**

Impact: customers with triggers cannot rename a database or schema without first dropping the triggers, renaming, and recreating them.

Jira: CRDB-66018

Contributor guide

Open the contributing guide

Research direction

Start with pkg/sql/rename_database.go and maybeFailOnDependentDescInRename, then compare its caller in pkg/sql/alter_schema.go. Run the supplied trigger reproduction for both database and schema renames, and inspect how dependencies are classified. Done means these renames no longer fail solely because of a trigger, while explicit database or schema references in a function body remain considered.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, sql
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
67/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.