@@ -6,6 +6,137 @@ declare
66begin
77
88 set local search_path = ' ' ;
9+
10+ /*
11+ Override the pgmq.drop_queue to check if relevant tables are owned
12+ by the pgmq extension before attempting to run
13+ `alter extension pgmq drop table ...`
14+ this is necessary becasue, to enable nightly logical backups to include user queues
15+ we automatically detach them from pgmq.
16+
17+ this update is backwards compatible with version 1.4.4 but should be removed once we're on
18+ physical backups everywhere
19+ */
20+ -- Detach and delete the official function
21+ alter extension pgmq drop function pgmq .drop_queue ;
22+ drop function pgmq .drop_queue ;
23+
24+ -- Create and reattach the patched function
25+ CREATE FUNCTION pgmq .drop_queue(queue_name TEXT )
26+ RETURNS BOOLEAN AS $func$
27+ DECLARE
28+ qtable TEXT := pgmq .format_table_name (queue_name, ' q' );
29+ qtable_seq TEXT := qtable || ' _msg_id_seq' ;
30+ fq_qtable TEXT := ' pgmq.' || qtable;
31+ atable TEXT := pgmq .format_table_name (queue_name, ' a' );
32+ fq_atable TEXT := ' pgmq.' || atable;
33+ partitioned BOOLEAN ;
34+ BEGIN
35+ EXECUTE FORMAT(
36+ $QUERY$
37+ SELECT is_partitioned FROM pgmq .meta WHERE queue_name = %L
38+ $QUERY$,
39+ queue_name
40+ ) INTO partitioned;
41+
42+ -- NEW CONDITIONAL CHECK
43+ if exists (
44+ select 1
45+ from pg_class c
46+ join pg_depend d on c .oid = d .objid
47+ join pg_extension e on d .refobjid = e .oid
48+ where c .relname = qtable and e .extname = ' pgmq'
49+ ) then
50+
51+ EXECUTE FORMAT(
52+ $QUERY$
53+ ALTER EXTENSION pgmq DROP TABLE pgmq .%I
54+ $QUERY$,
55+ qtable
56+ );
57+
58+ end if;
59+
60+ -- NEW CONDITIONAL CHECK
61+ if exists (
62+ select 1
63+ from pg_class c
64+ join pg_depend d on c .oid = d .objid
65+ join pg_extension e on d .refobjid = e .oid
66+ where c .relname = qtable_seq and e .extname = ' pgmq'
67+ ) then
68+ EXECUTE FORMAT(
69+ $QUERY$
70+ ALTER EXTENSION pgmq DROP SEQUENCE pgmq.%I
71+ $QUERY$,
72+ qtable_seq
73+ );
74+
75+ end if;
76+
77+ -- NEW CONDITIONAL CHECK
78+ if exists (
79+ select 1
80+ from pg_class c
81+ join pg_depend d on c .oid = d .objid
82+ join pg_extension e on d .refobjid = e .oid
83+ where c .relname = atable and e .extname = ' pgmq'
84+ ) then
85+
86+ EXECUTE FORMAT(
87+ $QUERY$
88+ ALTER EXTENSION pgmq DROP TABLE pgmq .%I
89+ $QUERY$,
90+ atable
91+ );
92+
93+ end if;
94+
95+ -- NO CHANGES PAST THIS POINT
96+
97+ EXECUTE FORMAT(
98+ $QUERY$
99+ DROP TABLE IF EXISTS pgmq.%I
100+ $QUERY$,
101+ qtable
102+ );
103+
104+ EXECUTE FORMAT(
105+ $QUERY$
106+ DROP TABLE IF EXISTS pgmq.%I
107+ $QUERY$,
108+ atable
109+ );
110+
111+ IF EXISTS (
112+ SELECT 1
113+ FROM information_schema .tables
114+ WHERE table_name = ' meta' and table_schema = ' pgmq'
115+ ) THEN
116+ EXECUTE FORMAT(
117+ $QUERY$
118+ DELETE FROM pgmq .meta WHERE queue_name = %L
119+ $QUERY$,
120+ queue_name
121+ );
122+ END IF;
123+
124+ IF partitioned THEN
125+ EXECUTE FORMAT(
126+ $QUERY$
127+ DELETE FROM %I .part_config where parent_table in (%L, %L)
128+ $QUERY$,
129+ pgmq ._get_pg_partman_schema (), fq_qtable, fq_atable
130+ );
131+ END IF;
132+
133+ RETURN TRUE;
134+ END;
135+ $func$ LANGUAGE plpgsql;
136+
137+ alter extension pgmq add function pgmq .drop_queue ;
138+
139+
9140 update pg_extension set extowner = ' postgres' ::regrole where extname = ' pgmq' ;
10141
11142 for r in (select * from pg_depend where refobjid = extoid) loop
0 commit comments