Skip to content

Commit bbfc14b

Browse files
jfrochesamrose
andauthored
fix(pgmq): replace drop_queue function if exists (#1828)
* fix(pgmq): replace drop_queue function if exists We introduced a patch to override pgmq.drop_queue(TEXT) to conditionally drop objects only if they are part of the extension in `ansible/ansible/files/postgresql_extension_custom_scripts/pgmq/after-create.sql` . This script might have been installed on installations with existing 1.4.4 extensions. When the user tries to upgrade pgmq from 1.4.4 to 1.5.1, the upgrade process will fail because the upgrade script doesn't expect `pgmq.drop_queue(TEXT)` to exist. This change introduce the a patch to the pgmq extension to use `CREATE OR REPLACE FUNCTION` instead of `CREATE FUNCTION` for `pgmq.drop_queue(TEXT)` in the upgrade script from 1.4.5 to 1.5.0. * feat: test that the pgmq extension works well with the after create script We create a new custom nixos test for the pgmq extension to test that the extension works well with the after-create.sql script present in `ansible/files/postgresql_extension_custom_scripts/pgmq/after-create.sql`. * chore: bump versions to release post-rebase --------- Co-authored-by: Sam Rose <[email protected]>
1 parent 0987406 commit bbfc14b

File tree

7 files changed

+206
-6
lines changed

7 files changed

+206
-6
lines changed

ansible/vars.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ postgres_major:
1010

1111
# Full version strings for each major version
1212
postgres_release:
13-
postgresorioledb-17: "17.5.1.040-orioledb"
14-
postgres17: "17.6.1.019"
15-
postgres15: "15.14.1.019"
13+
postgresorioledb-17: "17.5.1.041-orioledb"
14+
postgres17: "17.6.1.020"
15+
postgres15: "15.14.1.020"
1616

1717
# Non Postgres Extensions
1818
pgbouncer_release: 1.19.0
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
From 31a9b2d736d8a85f113d592754f4832a0097bb2d Mon Sep 17 00:00:00 2001
2+
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Roche?= <[email protected]>
3+
Date: Thu, 9 Oct 2025 10:53:50 +0200
4+
Subject: [PATCH] fix: replace drop_queue function if exists
5+
6+
Function drop_queue might have been created by running `postgresql_extension_custom_scripts/pgmq/after-create.sql`
7+
on a previous version of the extension. In that case, running the migration script will fail because the function already exists.
8+
9+
We use `CREATE OR REPLACE FUNCTION` to avoid that issue.
10+
---
11+
pgmq-extension/sql/pgmq--1.4.5--1.5.0.sql | 2 +-
12+
1 file changed, 1 insertion(+), 1 deletion(-)
13+
14+
diff --git a/pgmq-extension/sql/pgmq--1.4.5--1.5.0.sql b/pgmq-extension/sql/pgmq--1.4.5--1.5.0.sql
15+
index 5754eed..de03788 100644
16+
--- a/pgmq-extension/sql/pgmq--1.4.5--1.5.0.sql
17+
+++ b/pgmq-extension/sql/pgmq--1.4.5--1.5.0.sql
18+
@@ -122,7 +122,7 @@ BEGIN
19+
END;
20+
$$ LANGUAGE plpgsql;
21+
22+
-CREATE FUNCTION pgmq.drop_queue(queue_name TEXT)
23+
+CREATE OR REPLACE FUNCTION pgmq.drop_queue(queue_name TEXT)
24+
RETURNS BOOLEAN AS $$
25+
DECLARE
26+
qtable TEXT := pgmq.format_table_name(queue_name, 'q');
27+
--
28+
2.51.0
29+

nix/ext/pgmq.nix renamed to nix/ext/pgmq/default.nix

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ let
99
pname = "pgmq";
1010

1111
# Load version configuration from external file
12-
allVersions = (builtins.fromJSON (builtins.readFile ./versions.json)).${pname};
12+
allVersions = (builtins.fromJSON (builtins.readFile ../versions.json)).${pname};
1313

1414
# Filter versions compatible with current PostgreSQL version
1515
supportedVersions = lib.filterAttrs (
@@ -37,6 +37,10 @@ let
3737
inherit hash;
3838
};
3939

40+
patches = lib.optionals (version == latestVersion) [
41+
./0001-fix-replace-drop_queue-function-if-exists.patch
42+
];
43+
4044
buildPhase = ''
4145
cd pgmq-extension
4246
'';

nix/ext/tests/default.nix

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ builtins.listToAttrs (
206206
"pg_graphql"
207207
"pg_jsonschema"
208208
"pg_net"
209-
"pgmq"
210209
"vector"
211210
"wrappers"
212211
]

nix/ext/tests/lib.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ def run_sql(self, query: str) -> str:
4141
f"""sudo -u postgres psql -t -A -F\",\" -c \"{query}\" """
4242
).strip()
4343

44+
def run_sql_file(self, file: str) -> str:
45+
return self.vm.succeed(
46+
f"""sudo -u postgres psql -v ON_ERROR_STOP=1 -f \"{file}\""""
47+
).strip()
48+
4449
def drop_extension(self):
4550
self.run_sql(f"DROP EXTENSION IF EXISTS {self.extension_name};")
4651

nix/ext/tests/pgmq.nix

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
{ self, pkgs }:
2+
let
3+
pname = "pgmq";
4+
inherit (pkgs) lib;
5+
installedExtension =
6+
postgresMajorVersion: self.packages.${pkgs.system}."psql_${postgresMajorVersion}/exts/${pname}-all";
7+
versions = postgresqlMajorVersion: (installedExtension postgresqlMajorVersion).versions;
8+
postgresqlWithExtension =
9+
postgresql:
10+
let
11+
majorVersion = lib.versions.major postgresql.version;
12+
pkg = pkgs.buildEnv {
13+
name = "postgresql-${majorVersion}-${pname}";
14+
paths = [
15+
postgresql
16+
postgresql.lib
17+
(installedExtension majorVersion)
18+
];
19+
passthru = {
20+
inherit (postgresql) version psqlSchema;
21+
lib = pkg;
22+
withPackages = _: pkg;
23+
};
24+
nativeBuildInputs = [ pkgs.makeWrapper ];
25+
pathsToLink = [
26+
"/"
27+
"/bin"
28+
"/lib"
29+
];
30+
postBuild = ''
31+
wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib
32+
wrapProgram $out/bin/pg_ctl --set NIX_PGLIBDIR $out/lib
33+
wrapProgram $out/bin/pg_upgrade --set NIX_PGLIBDIR $out/lib
34+
'';
35+
};
36+
in
37+
pkg;
38+
psql_15 = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15;
39+
psql_17 = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17;
40+
in
41+
self.inputs.nixpkgs.lib.nixos.runTest {
42+
name = "timescaledb";
43+
hostPkgs = pkgs;
44+
nodes.server =
45+
{ config, ... }:
46+
{
47+
services.postgresql = {
48+
enable = true;
49+
package = (postgresqlWithExtension psql_15);
50+
settings = (installedExtension "15").defaultSettings or { };
51+
};
52+
53+
specialisation.postgresql17.configuration = {
54+
services.postgresql = {
55+
package = lib.mkForce psql_17;
56+
};
57+
58+
systemd.services.postgresql-migrate = {
59+
serviceConfig = {
60+
Type = "oneshot";
61+
RemainAfterExit = true;
62+
User = "postgres";
63+
Group = "postgres";
64+
StateDirectory = "postgresql";
65+
WorkingDirectory = "${builtins.dirOf config.services.postgresql.dataDir}";
66+
};
67+
script =
68+
let
69+
oldPostgresql = psql_15;
70+
newPostgresql = psql_17;
71+
oldDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${oldPostgresql.psqlSchema}";
72+
newDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${newPostgresql.psqlSchema}";
73+
in
74+
''
75+
if [[ ! -d ${newDataDir} ]]; then
76+
install -d -m 0700 -o postgres -g postgres "${newDataDir}"
77+
${newPostgresql}/bin/initdb -D "${newDataDir}"
78+
${newPostgresql}/bin/pg_upgrade --old-datadir "${oldDataDir}" --new-datadir "${newDataDir}" \
79+
--old-bindir "${oldPostgresql}/bin" --new-bindir "${newPostgresql}/bin"
80+
else
81+
echo "${newDataDir} already exists"
82+
fi
83+
'';
84+
};
85+
86+
systemd.services.postgresql = {
87+
after = [ "postgresql-migrate.service" ];
88+
requires = [ "postgresql-migrate.service" ];
89+
};
90+
};
91+
};
92+
testScript =
93+
{ nodes, ... }:
94+
let
95+
pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17";
96+
in
97+
''
98+
from pathlib import Path
99+
versions = {
100+
"15": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "15"))}],
101+
"17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}],
102+
}
103+
extension_name = "${pname}"
104+
support_upgrade = True
105+
pg17_configuration = "${pg17-configuration}"
106+
ext_has_background_worker = ${
107+
if (installedExtension "15") ? hasBackgroundWorker then "True" else "False"
108+
}
109+
sql_test_directory = Path("${../../tests}")
110+
pg_regress_test_name = "${(installedExtension "15").pgRegressTestName or pname}"
111+
112+
${builtins.readFile ./lib.py}
113+
114+
start_all()
115+
116+
server.wait_for_unit("multi-user.target")
117+
server.wait_for_unit("postgresql.service")
118+
119+
test = PostgresExtensionTest(server, extension_name, versions, sql_test_directory, support_upgrade)
120+
121+
with subtest("Check upgrade path with postgresql 15"):
122+
test.check_upgrade_path("15")
123+
test.run_sql_file("${../../../ansible/files/postgresql_extension_custom_scripts/pgmq/after-create.sql}")
124+
125+
with subtest("Check pg_regress with postgresql 15 after extension upgrade"):
126+
test.check_pg_regress(Path("${psql_15}/lib/pgxs/src/test/regress/pg_regress"), "15", pg_regress_test_name)
127+
128+
last_version = None
129+
with subtest("Check the install of the last version of the extension"):
130+
last_version = test.check_install_last_version("15")
131+
test.run_sql_file("${../../../ansible/files/postgresql_extension_custom_scripts/pgmq/after-create.sql}")
132+
133+
if ext_has_background_worker:
134+
with subtest("Test switch_${pname}_version"):
135+
test.check_switch_extension_with_background_worker(Path("${psql_15}/lib/${pname}.so"), "15")
136+
137+
with subtest("Check pg_regress with postgresql 15 after installing the last version"):
138+
test.check_pg_regress(Path("${psql_15}/lib/pgxs/src/test/regress/pg_regress"), "15", pg_regress_test_name)
139+
140+
with subtest("switch to postgresql 17"):
141+
server.succeed(
142+
f"{pg17_configuration}/bin/switch-to-configuration test >&2"
143+
)
144+
145+
with subtest("Check last version of the extension after postgresql upgrade"):
146+
test.assert_version_matches(last_version)
147+
test.run_sql_file("${../../../ansible/files/postgresql_extension_custom_scripts/pgmq/after-create.sql}")
148+
149+
with subtest("Check upgrade path with postgresql 17"):
150+
test.check_upgrade_path("17")
151+
test.run_sql_file("${../../../ansible/files/postgresql_extension_custom_scripts/pgmq/after-create.sql}")
152+
153+
with subtest("Check pg_regress with postgresql 17 after extension upgrade"):
154+
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
155+
156+
with subtest("Check the install of the last version of the extension"):
157+
test.check_install_last_version("17")
158+
test.run_sql_file("${../../../ansible/files/postgresql_extension_custom_scripts/pgmq/after-create.sql}")
159+
160+
with subtest("Check pg_regress with postgresql 17 after installing the last version"):
161+
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
162+
'';
163+
}

nix/packages/postgres.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
../ext/pgroonga.nix
2323
../ext/index_advisor.nix
2424
../ext/wal2json.nix
25-
../ext/pgmq.nix
25+
../ext/pgmq
2626
../ext/pg_repack.nix
2727
../ext/pg-safeupdate.nix
2828
../ext/plpgsql-check.nix

0 commit comments

Comments
 (0)