Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ begin
this update is backwards compatible with version 1.4.4 but should be removed once we're on
physical backups everywhere
*/
-- Detach and delete the official function
if extversion = '1.4.4' then
alter extension pgmq drop function pgmq.drop_queue;
drop function pgmq.drop_queue;
else -- 1.5.1+
alter extension pgmq drop function pgmq.drop_queue(TEXT);
drop function pgmq.drop_queue(TEXT);
end if;
-- detach both historical drop_queue signatures, if present as extension members
if to_regprocedure('pgmq.drop_queue(text)') is not null then
alter extension pgmq drop function pgmq.drop_queue(text);
end if;
if to_regprocedure('pgmq.drop_queue(text, boolean)') is not null then
alter extension pgmq drop function pgmq.drop_queue(text, boolean);
end if;

drop function if exists pgmq.drop_queue(text);
drop function if exists pgmq.drop_queue(text, boolean);

-- Create and reattach the patched function
CREATE FUNCTION pgmq.drop_queue(queue_name TEXT)
Expand Down Expand Up @@ -143,11 +145,17 @@ BEGIN
END;
$func$ LANGUAGE plpgsql;

if extversion = '1.4.4' then
alter extension pgmq add function pgmq.drop_queue;
else -- 1.5.1+
alter extension pgmq add function pgmq.drop_queue(TEXT);
end if;
alter extension pgmq add function pgmq.drop_queue(text);

-- compat shim, not reattached: keeps ALTER EXTENSION UPDATE from ever touching it
CREATE OR REPLACE FUNCTION pgmq.drop_queue(queue_name TEXT, partitioned BOOLEAN)
RETURNS BOOLEAN AS $shim$
BEGIN
RETURN pgmq.drop_queue(queue_name);
END;
$shim$ LANGUAGE plpgsql;

alter function pgmq.drop_queue(text, boolean) owner to postgres;


update pg_extension set extowner = 'postgres'::regrole where extname = 'pgmq';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- clear a leftover drop_queue(text, boolean) compat shim from a prior
-- install: it isn't an extension member, so DROP EXTENSION never removes it,
-- and pgmq's own install script would otherwise collide with it
drop function if exists pgmq.drop_queue(text, boolean);
Comment thread
imor marked this conversation as resolved.
84 changes: 84 additions & 0 deletions nix/ext/tests/pgmq-drop-queue-overload.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{ self, pkgs }:
let
pname = "pgmq";
inherit (pkgs) lib;
system = pkgs.pkgsLinux.stdenv.hostPlatform.system;
testLib = import ./lib.nix { inherit self pkgs; };

installedExtension = self.legacyPackages.${system}."psql_15".exts."${pname}";
versions = installedExtension.versions;
in
pkgs.testers.runNixOSTest {
name = "pgmq-drop-queue-overload";
nodes.server =
{ ... }:
{
imports = [
(testLib.makeSupabaseTestConfig {
majorVersion = "15";
})
];
};
testScript =
{ ... }:
let
versionList = lib.concatStringsSep ", " (map (v: ''"${v}"'') versions);
in
''
versions = [${versionList}]

def sql(query):
return server.succeed(
"psql -U supabase_admin -d postgres -t -A -F',' -c \"" + query.replace('"', '\\"') + "\""
).strip()

def drop_queue_overloads():
# owned flag first: pg_get_function_identity_arguments() can itself
# contain a comma ("queue_name text, partitioned boolean"), so put the
# single-char flag first and split on the first comma only.
out = sql(
"select (d.objid is not null), pg_get_function_identity_arguments(p.oid) "
"from pg_proc p "
"left join pg_depend d on d.objid = p.oid and d.deptype = 'e' "
" and d.refobjid = (select oid from pg_extension where extname = 'pgmq') "
"where p.pronamespace = 'pgmq'::regnamespace and p.proname = 'drop_queue' "
"order by 2;"
)
return [line.split(",", 1) for line in out.splitlines() if line]

# every calling convention drop_queue has ever supported still works
def check_callers(qname):
sql(f"select pgmq.create('{qname}_a'); select pgmq.drop_queue('{qname}_a');")
sql(f"select pgmq.create('{qname}_b'); select pgmq.drop_queue('{qname}_b', false);")
# WRONG flag on purpose (queue isn't partitioned) - must still
# succeed, safely ignored in favour of pgmq.meta
sql(f"select pgmq.create('{qname}_c'); select pgmq.drop_queue('{qname}_c', true);")
sql(
f"select pgmq.create('{qname}_d'); "
f"select pgmq.drop_queue(queue_name => '{qname}_d', partitioned => true);"
)

start_all()
server.wait_for_unit("supabase-db-init.service")

# fresh install of each pinned version: check the overload split, then the callers
for version in versions:
with subtest(f"install pgmq {version}"):
server.succeed("psql -U supabase_admin -d postgres -c 'DROP EXTENSION IF EXISTS pgmq;'")
server.succeed(
f"psql -U supabase_admin -d postgres -c \"CREATE EXTENSION pgmq WITH VERSION '{version}' CASCADE;\""
)

overloads = drop_queue_overloads()
print(f"[{version}] drop_queue overloads: {overloads}")
assert overloads == [
["t", "queue_name text"],
["f", "queue_name text, partitioned boolean"],
], (
f"[{version}] expected one extension-owned drop_queue(text) plus "
f"an unattached drop_queue(text, boolean) compat shim, got: {overloads}"
)

check_callers(f"q_{version.replace('.', '_')}")
'';
}
3 changes: 1 addition & 2 deletions nix/tests/expected/pgmq.out
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ order by
pgmq | delete | postgres
pgmq | detach_archive | postgres
pgmq | drop_queue | postgres
pgmq | drop_queue | postgres
pgmq | format_table_name | postgres
pgmq | list_queues | postgres
pgmq | metrics | postgres
Expand All @@ -198,7 +197,7 @@ order by
pgmq | send_batch | postgres
pgmq | set_vt | postgres
pgmq | validate_queue_name | postgres
(40 rows)
(39 rows)

-- assert search_path is preserved after after-create script is run
show search_path;
Expand Down
Loading
Loading