|
| 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 |
0 commit comments