Skip to content

Commit d2ef3f6

Browse files
committed
add test highlighting the drop_queue issue. raises exception
1 parent 22d1c60 commit d2ef3f6

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
This test confirms that the pgmq after-create supautils hook
3+
that replaces the drop_queue function is inter-operable with
4+
the infra hook that detaches pgmq queues from the pgmq
5+
extension's ownership prior to taking logical backups
6+
*/
7+
-- Create a queue
8+
select pgmq.create('lb-test');
9+
create
10+
--------
11+
12+
(1 row)
13+
14+
-- Add a record
15+
select
16+
*
17+
from
18+
pgmq.send(
19+
queue_name:='lb-test',
20+
msg:='{"foo": "bar1"}'
21+
);
22+
send
23+
------
24+
1
25+
(1 row)
26+
27+
/*
28+
COPY/PASTE of the on-pause hook that
29+
- detaches ownership of queues from the extension
30+
- updates identity columns to avoid pg_dump segfault
31+
*/
32+
do $$
33+
declare
34+
tbl record;
35+
seq_name text;
36+
new_seq_name text;
37+
archive_table_name text;
38+
begin
39+
-- Loop through each table in the pgmq schema starting with 'q_'
40+
-- Rebuild the pkey column's default to avoid pg_dumpall segfaults
41+
for tbl in
42+
select c.relname as table_name
43+
from pg_catalog.pg_attribute a
44+
join pg_catalog.pg_class c on c.oid = a.attrelid
45+
join pg_catalog.pg_namespace n on n.oid = c.relnamespace
46+
where n.nspname = 'pgmq'
47+
and c.relname like 'q_%'
48+
and a.attname = 'msg_id'
49+
and a.attidentity in ('a', 'd') -- 'a' for ALWAYS, 'd' for BY DEFAULT
50+
loop
51+
-- Check if msg_id is an IDENTITY column for idempotency
52+
-- Define sequence names
53+
seq_name := 'pgmq.' || format ('"%s_msg_id_seq"', tbl.table_name);
54+
new_seq_name := 'pgmq.' || format ('"%s_msg_id_seq2"', tbl.table_name);
55+
archive_table_name := regexp_replace(tbl.table_name, '^q_', 'a_');
56+
-- Execute dynamic SQL to perform the required operations
57+
execute format('
58+
create sequence %s;
59+
select setval(''%s'', nextval(''%s''));
60+
alter table %s."%s" alter column msg_id drop identity;
61+
alter table %s."%s" alter column msg_id set default nextval(''%s'');
62+
alter sequence %s rename to %s;
63+
alter sequence %s owner to postgres;',
64+
-- Parameters for format placeholders
65+
new_seq_name,
66+
new_seq_name, seq_name,
67+
'pgmq', tbl.table_name,
68+
'pgmq', tbl.table_name,
69+
new_seq_name,
70+
-- alter seq
71+
new_seq_name, format('"%s_msg_id_seq"', tbl.table_name),
72+
-- set owner
73+
seq_name
74+
);
75+
end loop;
76+
-- No tables should be owned by the extension.
77+
-- We want them to be included in logical backups
78+
for tbl in
79+
select c.relname as table_name
80+
from pg_class c
81+
join pg_depend d
82+
on c.oid = d.objid
83+
join pg_extension e
84+
on d.refobjid = e.oid
85+
where
86+
c.relkind in ('r', 'p', 'u')
87+
and e.extname = 'pgmq'
88+
and (c.relname like 'q_%' or c.relname like 'a_%')
89+
loop
90+
execute format('
91+
alter extension pgmq drop table pgmq."%s";',
92+
tbl.table_name
93+
);
94+
end loop;
95+
end $$;
96+
-- Now confirm that pgmq.drop_queue still works
97+
select pgmq.drop_queue('lb-test');
98+
ERROR: table pgmq."q_lb-test" is not a member of extension "pgmq"
99+
CONTEXT: SQL statement "
100+
ALTER EXTENSION pgmq DROP TABLE pgmq."q_lb-test"
101+
"
102+
PL/pgSQL function pgmq.drop_queue(text,boolean) line 8 at EXECUTE
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
This test confirms that the pgmq after-create supautils hook
3+
that replaces the drop_queue function is inter-operable with
4+
the infra hook that detaches pgmq queues from the pgmq
5+
extension's ownership prior to taking logical backups
6+
*/
7+
8+
-- Create a queue
9+
select pgmq.create('lb-test');
10+
11+
-- Add a record
12+
select
13+
*
14+
from
15+
pgmq.send(
16+
queue_name:='lb-test',
17+
msg:='{"foo": "bar1"}'
18+
);
19+
20+
21+
/*
22+
COPY/PASTE of the on-pause hook that
23+
- detaches ownership of queues from the extension
24+
- updates identity columns to avoid pg_dump segfault
25+
*/
26+
27+
do $$
28+
declare
29+
tbl record;
30+
seq_name text;
31+
new_seq_name text;
32+
archive_table_name text;
33+
begin
34+
-- Loop through each table in the pgmq schema starting with 'q_'
35+
-- Rebuild the pkey column's default to avoid pg_dumpall segfaults
36+
for tbl in
37+
select c.relname as table_name
38+
from pg_catalog.pg_attribute a
39+
join pg_catalog.pg_class c on c.oid = a.attrelid
40+
join pg_catalog.pg_namespace n on n.oid = c.relnamespace
41+
where n.nspname = 'pgmq'
42+
and c.relname like 'q_%'
43+
and a.attname = 'msg_id'
44+
and a.attidentity in ('a', 'd') -- 'a' for ALWAYS, 'd' for BY DEFAULT
45+
loop
46+
-- Check if msg_id is an IDENTITY column for idempotency
47+
-- Define sequence names
48+
seq_name := 'pgmq.' || format ('"%s_msg_id_seq"', tbl.table_name);
49+
new_seq_name := 'pgmq.' || format ('"%s_msg_id_seq2"', tbl.table_name);
50+
archive_table_name := regexp_replace(tbl.table_name, '^q_', 'a_');
51+
-- Execute dynamic SQL to perform the required operations
52+
execute format('
53+
create sequence %s;
54+
select setval(''%s'', nextval(''%s''));
55+
alter table %s."%s" alter column msg_id drop identity;
56+
alter table %s."%s" alter column msg_id set default nextval(''%s'');
57+
alter sequence %s rename to %s;
58+
alter sequence %s owner to postgres;',
59+
-- Parameters for format placeholders
60+
new_seq_name,
61+
new_seq_name, seq_name,
62+
'pgmq', tbl.table_name,
63+
'pgmq', tbl.table_name,
64+
new_seq_name,
65+
-- alter seq
66+
new_seq_name, format('"%s_msg_id_seq"', tbl.table_name),
67+
-- set owner
68+
seq_name
69+
);
70+
end loop;
71+
-- No tables should be owned by the extension.
72+
-- We want them to be included in logical backups
73+
for tbl in
74+
select c.relname as table_name
75+
from pg_class c
76+
join pg_depend d
77+
on c.oid = d.objid
78+
join pg_extension e
79+
on d.refobjid = e.oid
80+
where
81+
c.relkind in ('r', 'p', 'u')
82+
and e.extname = 'pgmq'
83+
and (c.relname like 'q_%' or c.relname like 'a_%')
84+
loop
85+
execute format('
86+
alter extension pgmq drop table pgmq."%s";',
87+
tbl.table_name
88+
);
89+
end loop;
90+
end $$;
91+
92+
-- Now confirm that pgmq.drop_queue still works
93+
select pgmq.drop_queue('lb-test');

0 commit comments

Comments
 (0)