Skip to content

Support DROP TABLE ... CASCADE and RESTRICT - #3155

Open
zachmu wants to merge 1 commit into
mainfrom
zachmu/issue3120
Open

Support DROP TABLE ... CASCADE and RESTRICT#3155
zachmu wants to merge 1 commit into
mainfrom
zachmu/issue3120

Conversation

@zachmu

@zachmu zachmu commented Aug 20, 2026

Copy link
Copy Markdown
Member

Adds support for DROP TABLE ... CASCADE and RESTRICT.

Fixes #3120.

Fixes #3120.

DROP TABLE ... CASCADE previously failed with 'CASCADE is not yet
supported' (and RESTRICT with a similar error). RESTRICT is the default
behavior in Postgres, so it is now handled by the standard DROP TABLE
path. CASCADE converts to a new DropTableCascade node that first drops
the foreign key constraints on other tables that reference the dropped
tables (via the same sql.ForeignKeyTable interface calls the engine's
DROP TABLE execution uses), then delegates the actual drop to the
standard DROP TABLE path, which keeps its existing dependency
bookkeeping such as dropping sequences owned by the tables' columns.

Table names without an explicit schema are resolved against the search
path, and IF EXISTS skips missing tables as before.

Not yet cascaded (dependency tracking does not cover them yet): views
that reference a dropped table (they are left in place, matching the
behavior of plain DROP TABLE), and tables/functions/procedures using a
dropped table's row type as a column or parameter type (these still
error, as without CASCADE).
@itoqa

itoqa Bot commented Aug 20, 2026

Copy link
Copy Markdown

Ito QA test results
Commit: 94bfd08: 14 test cases ran, 14 passed ✅.

Summary

Coverage spans normal and edge-case table removal behavior, including dependency handling, cascading cleanup, rollback safety, concurrent operations, qualified and quoted names, schema resolution, metadata consistency, and preservation of related data and objects. It also checks that invalid operations fail safely without damaging existing protections or usability.

Safe to merge — the run found no PR-attributable regressions or new failures across the exercised database behaviors, and all checks passed. No merge blocker was identified.

Tests run by Ito

View full run

Result Severity Type Description
General Dropping the parent and middle tables removes only those requested tables. The external child and its data remain available, and its old foreign key no longer blocks new rows.
General Dropping the parent table removed the foreign key from both metadata views, and the child table still worked normally.
General Dropping a table with quote characters in its schema and table names removed the intended table and its owned sequence. A similarly named table and the surrounding schema stayed intact.
General The cascade command returned an error for a missing table, and the target table and external child were still present afterward. The child still rejected an invalid row, so its foreign-key protection was not lost.
General Two sessions tried to drop the same parent table at once. One succeeded, the other got a safe missing-table error, and the child table stayed usable with consistent foreign-key metadata.
Cascade Dropping the parent table removed the parent but kept the child table and its existing row. A new child row with an unknown parent value was also accepted after the drop.
Database A DROP TABLE command using the current database, schema, and table name succeeded. The table was gone when checked afterward.
Database A DROP TABLE command naming a different database was rejected, and the protected table stayed intact.
Dependency Dropping a table with CASCADE was refused because another table uses its row type, and both tables stayed available.
Resolution The database found the unqualified table through the active search path and also found the explicitly named table in another schema. Both tables were removed successfully.
Rev A failed table drop was rolled back cleanly. The parent table and its dependent function still worked, and the child table continued to reject an invalid foreign-key value.
Sequence Dropping the table with CASCADE removed both the table and its generated sequence. Looking up the old sequence then returned a relation-not-found error instead of generating another value.
Standard Dropping a parent table with a child table that depends on it returned a clear dependency error, both with the default behavior and with RESTRICT. An unrelated table was removed successfully.
View Dropping the base table removed it while keeping the dependent view in the catalog. Querying the view returned the expected invalid-dependency error.

Tip

Reply with @itoqa to send us feedback on this test run.

@github-actions

Copy link
Copy Markdown
Contributor
Main PR
Total 42090 42090
Successful 18980 19174
Failures 23110 22916
Partial Successes1 5461 5457
Main PR
Successful 45.0938% 45.5548%
Failures 54.9062% 54.4452%

${\color{red}Regressions (1)}$

updatable_views

QUERY:          CREATE VIEW rw_view3 AS SELECT * FROM rw_view2 WITH CHECK OPTION;
RECEIVED ERROR: View 'regression.rw_view1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them

${\color{lightgreen}Progressions (168)}$

aggregates

QUERY: drop table minmaxtest cascade;
QUERY: drop table t1 cascade;
QUERY: create temp table t1(f1 int, f2 bigint);
QUERY: select f1 from t1 left join t2 using (f1) group by f1;
QUERY: select f1 from t1 left join t2 using (f1) group by t1.f1;
QUERY: select t1.f1 from t1 left join t2 using (f1) group by t1.f1;

alter_table

QUERY: drop table atacc2 cascade;
QUERY: create table atacc2 (test2 int) inherits (atacc1);
QUERY: insert into atacc2 (test) values (-3);
QUERY: create table p1 (f1 int, f2 int);
QUERY: drop table p1 cascade;
QUERY: create table p1 (f1 int, f2 int);
QUERY: drop table p1 cascade;
QUERY: create table p1 (f1 int, f2 int);
QUERY: alter table only p1 drop column f1;
QUERY: drop table p1 cascade;
QUERY: create table p1 (f1 int, f2 int);
QUERY: alter table only p1 drop column f1;
QUERY: drop table p1 cascade;
QUERY: create table p1(id int, name text);
QUERY: create table p2(id2 int, name text, height int);
QUERY: alter table only p1 drop column name;
QUERY: alter table p2 drop column name;
QUERY: alter table p2 drop column height;
QUERY: drop table p1, p2 cascade;
QUERY: create table p1 (f1 int);
QUERY: insert into p1 values (1,2,'abc');
QUERY: drop table p1 cascade;
QUERY: DROP TABLE test_drop_constr_parent CASCADE;
QUERY: create table p1 (b int, a int not null) partition by range (b);
QUERY: insert into p1 (a, b) values (2, 3);
QUERY: drop table perm_part_parent cascade;
QUERY: drop table temp_part_parent cascade;

constraints

QUERY: DROP TABLE ATACC1 CASCADE;
QUERY: CREATE TABLE ATACC1 (TEST INT, TEST2 INT
	CHECK (TEST > 0), CHECK (TEST2 > 10) NO INHERIT);
QUERY: DROP TABLE ATACC1 CASCADE;

copy2

QUERY: DROP TABLE rls_t1 CASCADE;

copyselect

QUERY: drop table test3;

create_function_sql

QUERY: DROP TABLE functest1 CASCADE;
QUERY: DROP TABLE functest3 CASCADE;

Footnotes

  1. These are tests that we're marking as Successful, however they do not match the expected output in some way. This is due to small differences, such as different wording on the error messages, or the column names being incorrect while the data itself is correct.

@coffeegoddd

Copy link
Copy Markdown
Contributor

@zachmu DOLT

read_tests from_latency_median to_latency_median is_faster
covering_index_scan_postgres 2.43 2.43 0
groupby_scan_postgres 75.82 74.46 0
index_join_postgres 2.22 2.22 0
index_join_scan_postgres 1.58 1.58 0
index_scan_postgres 493.24 484.44 0
oltp_point_select 0.36 0.36 0
oltp_read_only 6.32 6.32 0
select_random_points 0.7 0.7 0
select_random_ranges 1.01 1.01 0
table_scan_postgres 493.24 493.24 0
types_table_scan_postgres 1235.62 1213.57 0
write_tests from_latency_median to_latency_median is_faster
bulk_insert 0.001 0.001 0
oltp_delete_insert_postgres 6.67 6.67 0
oltp_insert 3.36 3.36 0
oltp_read_write 13.22 13.22 0
oltp_update_index 3.55 3.55 0
oltp_update_non_index 3.25 3.25 0
oltp_write_only 7.04 6.91 0
types_delete_insert_postgres 7.17 7.17 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DROP TABLE CASCADE support

2 participants