Bug on drop extension dependencies ?

Started by Marcos Pegoraro6 months ago6 messages
#1Marcos Pegoraro
marcos@f10.com.br

Working with several schemas and the same structure, I created an extension
on one of those schemas, and it worked fine for all schemas. But then I
don't need that schema anymore, and when I drop it with cascade, it drops
that extension too, and doing that it drops all constraints related to it.

So, should there be an exception when I try to drop that schema ?

mydb=# create schema ten_1;
CREATE SCHEMA
mydb=# set search_path to ten_1;
SET
mydb=# create extension btree_gist;
CREATE EXTENSION
--Extension was created on ten_1 schema.

mydb=# create table ten_1.mytable(pk integer generated always as identity,
id integer, myrange tstzrange, constraint rangeexclude EXCLUDE USING gist
(id WITH =, myrange WITH &&));
CREATE TABLE
mydb=# insert into ten_1.mytable(id, myrange)
values(1,'[2025/01/01,2025/02/01)'),(1,'[2025/01/10,2025/02/20)');
ERROR: conflicting key value violates exclusion constraint "rangeexclude"
DETAIL: Key (id, myrange)=(1, ["2025-01-10 00:00:00-03","2025-02-20
00:00:00-03")) conflicts with existing key (id, myrange)=(1, ["2025-01-01
00:00:00-03","2025-02-01 00:00:00-03")).

--As expected gives me an error
--Then I create another schema with same tables

mydb=# create schema ten_2;
CREATE SCHEMA
mydb=# create table ten_2.mytable(pk integer generated always as identity,
id integer, myrange tstzrange, constraint rangeexclude EXCLUDE USING gist
(id WITH =, myrange WITH &&));
CREATE TABLE
mydb=# insert into ten_2.mytable(id, myrange)
values(1,'[2025/01/01,2025/02/01)'),(1,'[2025/01/10,2025/02/20)');
ERROR: conflicting key value violates exclusion constraint "rangeexclude"
DETAIL: Key (id, myrange)=(1, ["2025-01-10 00:00:00-03","2025-02-20
00:00:00-03")) conflicts with existing key (id, myrange)=(1, ["2025-01-01
00:00:00-03","2025-02-01 00:00:00-03")).

--Fine, as expected too.
--Those two constraints are fine.

mydb=# select oid, conname, conrelid::regclass from pg_constraint where
conrelid in (select oid from pg_class where relname = 'mytable');
-[ RECORD 1 ]-----------
oid | 135979570
conname | rangeexclude
conrelid | ten_2.mytable
-[ RECORD 2 ]-----------
oid | 135979562
conname | rangeexclude
conrelid | ten_1.mytable

--But then I didn't want that ten_1 anymore, so I droped it.
--If I use client_min_messages = notice I'll receive a hint that the
exception is being dropped. But I didn't read that because I want to drop
everything on that schema, but only on that schema.

mydb=# set client_min_messages = warning;
SET
mydb=# drop schema ten_1 cascade;
DROP SCHEMA

--Ten_2 is still there, but not exactly the same

mydb=# insert into ten_2.mytable(id, myrange)
values(1,'[2025/01/01,2025/02/01)'),(1,'[2025/01/10,2025/02/20)');
INSERT 0 2

--Records were inserted
--And those two constraints were removed because my extension was removed.

So, dropping a schema could drop constraints on dozen or hundreds of other
schemas, I think this should raise an exception.

I don't know how to fix it, but I think it's a bug.

regards
Marcos

#2David G. Johnston
david.g.johnston@gmail.com
In reply to: Marcos Pegoraro (#1)
Re: Bug on drop extension dependencies ?

On Sat, Jul 12, 2025 at 11:31 AM Marcos Pegoraro <marcos@f10.com.br> wrote:

--If I use client_min_messages = notice I'll receive a hint that the
exception is being dropped. But I didn't read that because I want to drop
everything on that schema, but only on that schema.

mydb=# set client_min_messages = warning;
SET
mydb=# drop schema ten_1 cascade;
DROP SCHEMA

I don't know how to fix it, but I think it's a bug.

You told it to cascade and it will happily remove anything within the
database to comply. It is not a bug. The docs even make that point
explicitly:

"Using the CASCADE option might make the command remove objects in other
schemas besides the one(s) named."

Probably should have made the extension owned by a superuser and schemas
owned by some less-privileged user so that couldn't happen. Or just give
the extension its own schema.

David J.

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: David G. Johnston (#2)
Re: Bug on drop extension dependencies ?

"David G. Johnston" <david.g.johnston@gmail.com> writes:

On Sat, Jul 12, 2025 at 11:31 AM Marcos Pegoraro <marcos@f10.com.br> wrote:

I don't know how to fix it, but I think it's a bug.

You told it to cascade and it will happily remove anything within the
database to comply. It is not a bug. The docs even make that point
explicitly:

Indeed. If we put a restriction on this case then we'd just need to
invent a "REALLY CASCADE" option that did the more aggressive thing.

In any case, AFAICS the SQL spec says what CASCADE means, and this
is what it means. There's no intermediate step between RESTRICT
(don't drop any dependent objects) and CASCADE (drop every directly
or indirectly dependent object).

I grant that there could sometimes be a use for intermediate levels of
aggressiveness, but it's hard to see exactly where to draw the line
that wouldn't be extremely application-specific.

regards, tom lane

#4Marcos Pegoraro
marcos@f10.com.br
In reply to: Tom Lane (#3)
Re: Bug on drop extension dependencies ?

Em sáb., 12 de jul. de 2025 às 16:07, Tom Lane <tgl@sss.pgh.pa.us> escreveu:

Indeed. If we put a restriction on this case then we'd just need to
invent a "REALLY CASCADE" option that did the more aggressive thing.

I understand that it's not possible to prevent DROP ... CASCADE from
executing. However, the subsequent deletion of constraints, triggers, or
functions will affect the behavior of other schemas, so I think it's
reasonable to at least explicitly state in the log which objects were
deleted due to that command.

regards
Marcos

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Marcos Pegoraro (#4)
Re: Bug on drop extension dependencies ?

Marcos Pegoraro <marcos@f10.com.br> writes:

I understand that it's not possible to prevent DROP ... CASCADE from
executing. However, the subsequent deletion of constraints, triggers, or
functions will affect the behavior of other schemas, so I think it's
reasonable to at least explicitly state in the log which objects were
deleted due to that command.

[ shrug... ] We do report that. For example:

regression=# create table t1(f1 int primary key);
CREATE TABLE
regression=# create table t2(f2 int references t1);
CREATE TABLE
regression=# drop table t1;
ERROR: cannot drop table t1 because other objects depend on it
DETAIL: constraint t2_f2_fkey on table t2 depends on table t1
HINT: Use DROP ... CASCADE to drop the dependent objects too.
regression=# drop table t1 cascade;
NOTICE: drop cascades to constraint t2_f2_fkey on table t2
DROP TABLE

At default log settings, the ERROR/DETAIL would appear in the log,
while the NOTICE would not. Either way, there is plenty of
opportunity to observe what will or did get dropped.

regards, tom lane

#6David G. Johnston
david.g.johnston@gmail.com
In reply to: Marcos Pegoraro (#4)
Re: Bug on drop extension dependencies ?

On Sunday, July 13, 2025, Marcos Pegoraro <marcos@f10.com.br> wrote:

Em sáb., 12 de jul. de 2025 às 16:07, Tom Lane <tgl@sss.pgh.pa.us>
escreveu:

Indeed. If we put a restriction on this case then we'd just need to
invent a "REALLY CASCADE" option that did the more aggressive thing.

I understand that it's not possible to prevent DROP ... CASCADE from
executing. However, the subsequent deletion of constraints, triggers, or
functions will affect the behavior of other schemas, so I think it's
reasonable to at least explicitly state in the log which objects were
deleted due to that command.

Then install an event trigger and log every object that gets dropped at any
time.

David J.