Skip to content

Commit 5325c4e

Browse files
jfrochesamrose
andauthored
feat: support multiple versions of the pg_plan_filter extension (#1873)
* feat: support multiple versions of the pg_plan_filter extension Build multiple versions of the pg_plan_filter extension on different PostgreSQL versions. Add test for the extension and their upgrade on PostgreSQL 15 and 17. * chore: update release suffix for testing * chore: bump to release --------- Co-authored-by: Sam Rose <[email protected]>
1 parent 8b8c4e4 commit 5325c4e

File tree

4 files changed

+218
-22
lines changed

4 files changed

+218
-22
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.069-orioledb"
14-
postgres17: "17.6.1.048"
15-
postgres15: "15.14.1.048"
13+
postgresorioledb-17: "17.5.1.070-orioledb"
14+
postgres17: "17.6.1.049"
15+
postgres15: "15.14.1.049"
1616

1717
# Non Postgres Extensions
1818
pgbouncer_release: 1.19.0

nix/ext/pg_plan_filter.nix

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,87 @@
11
{
2+
pkgs,
23
lib,
34
stdenv,
45
fetchFromGitHub,
56
postgresql,
7+
makeWrapper,
68
}:
79

8-
stdenv.mkDerivation rec {
9-
pname = "pg_plan_filter";
10-
version = "5081a7b5cb890876e67d8e7486b6a64c38c9a492";
10+
let
11+
pname = "plan_filter";
12+
build =
13+
version: rev: hash:
14+
stdenv.mkDerivation rec {
15+
inherit pname version;
1116

12-
buildInputs = [ postgresql ];
17+
buildInputs = [ postgresql ];
1318

14-
src = fetchFromGitHub {
15-
owner = "pgexperts";
16-
repo = pname;
17-
rev = "${version}";
18-
hash = "sha256-YNeIfmccT/DtOrwDmpYFCuV2/P6k3Zj23VWBDkOh6sw=";
19-
};
19+
src = fetchFromGitHub {
20+
owner = "pgexperts";
21+
repo = pname;
22+
inherit rev hash;
23+
};
24+
25+
installPhase = ''
26+
runHook preInstall
27+
28+
mkdir -p $out/share/postgresql/extension
29+
30+
# Install versioned library
31+
install -Dm755 ${pname}${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix}
32+
33+
if [[ "${version}" == "${latestVersion}" ]]; then
34+
cp *.sql $out/share/postgresql/extension/
35+
fi
36+
37+
runHook postInstall
38+
'';
2039

21-
installPhase = ''
22-
mkdir -p $out/{lib,share/postgresql/extension}
40+
meta = with lib; {
41+
description = "Filter PostgreSQL statements by execution plans";
42+
homepage = "https://github.com/pgexperts/${pname}";
43+
platforms = postgresql.meta.platforms;
44+
license = licenses.postgresql;
45+
};
46+
};
47+
allVersions = (builtins.fromJSON (builtins.readFile ./versions.json)).pg_plan_filter;
48+
supportedVersions = lib.filterAttrs (
49+
_: value: builtins.elem (lib.versions.major postgresql.version) value.postgresql
50+
) allVersions;
51+
versions = lib.naturalSort (lib.attrNames supportedVersions);
52+
latestVersion = lib.last versions;
53+
numberOfVersions = builtins.length versions;
54+
packages = builtins.attrValues (
55+
lib.mapAttrs (name: value: build name value.rev value.hash) supportedVersions
56+
);
57+
in
58+
pkgs.buildEnv {
59+
name = pname;
60+
paths = packages;
61+
nativeBuildInputs = [ makeWrapper ];
62+
pathsToLink = [
63+
"/lib"
64+
"/share/postgresql/extension"
65+
];
66+
postBuild = ''
67+
ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix}
2368
24-
cp *${postgresql.dlSuffix} $out/lib
25-
cp *.sql $out/share/postgresql/extension
69+
# checks
70+
(set -x
71+
test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${
72+
toString (numberOfVersions + 1)
73+
}"
74+
)
2675
'';
2776

28-
meta = with lib; {
29-
description = "Filter PostgreSQL statements by execution plans";
30-
homepage = "https://github.com/pgexperts/${pname}";
31-
platforms = postgresql.meta.platforms;
32-
license = licenses.postgresql;
77+
passthru = {
78+
inherit versions numberOfVersions;
79+
pname = "${pname}-all";
80+
defaultSettings = {
81+
shared_preload_libraries = [ "plan_filter" ];
82+
};
83+
pgRegressTestName = "pg_plan_filter";
84+
version =
85+
"multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions);
3386
};
3487
}

nix/ext/tests/pg_plan_filter.nix

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
{ self, pkgs }:
2+
let
3+
pname = "plan_filter";
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 = pname;
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+
settings = (installedExtension "15").defaultSettings or { };
57+
};
58+
59+
systemd.services.postgresql-migrate = {
60+
serviceConfig = {
61+
Type = "oneshot";
62+
RemainAfterExit = true;
63+
User = "postgres";
64+
Group = "postgres";
65+
StateDirectory = "postgresql";
66+
WorkingDirectory = "${builtins.dirOf config.services.postgresql.dataDir}";
67+
};
68+
script =
69+
let
70+
oldPostgresql = psql_15;
71+
newPostgresql = psql_17;
72+
oldDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${oldPostgresql.psqlSchema}";
73+
newDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${newPostgresql.psqlSchema}";
74+
in
75+
''
76+
if [[ ! -d ${newDataDir} ]]; then
77+
install -d -m 0700 -o postgres -g postgres "${newDataDir}"
78+
${newPostgresql}/bin/initdb -D "${newDataDir}"
79+
${newPostgresql}/bin/pg_upgrade --old-datadir "${oldDataDir}" --new-datadir "${newDataDir}" \
80+
--old-bindir "${oldPostgresql}/bin" --new-bindir "${newPostgresql}/bin"
81+
else
82+
echo "${newDataDir} already exists"
83+
fi
84+
'';
85+
};
86+
87+
systemd.services.postgresql = {
88+
after = [ "postgresql-migrate.service" ];
89+
requires = [ "postgresql-migrate.service" ];
90+
};
91+
};
92+
};
93+
testScript =
94+
{ nodes, ... }:
95+
let
96+
pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17";
97+
in
98+
''
99+
from pathlib import Path
100+
versions = {
101+
"15": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "15"))}],
102+
"17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}],
103+
}
104+
extension_name = "${pname}"
105+
support_upgrade = False
106+
pg17_configuration = "${pg17-configuration}"
107+
ext_has_background_worker = ${
108+
if (installedExtension "15") ? hasBackgroundWorker then "True" else "False"
109+
}
110+
sql_test_directory = Path("${../../tests}")
111+
pg_regress_test_name = "${(installedExtension "15").pgRegressTestName or pname}"
112+
113+
${builtins.readFile ./lib.py}
114+
115+
start_all()
116+
117+
server.wait_for_unit("multi-user.target")
118+
server.wait_for_unit("postgresql.service")
119+
120+
test = PostgresExtensionTest(server, extension_name, versions, sql_test_directory, support_upgrade)
121+
122+
with subtest("Check pg_regress with postgresql 15 after extension upgrade"):
123+
test.check_pg_regress(Path("${psql_15}/lib/pgxs/src/test/regress/pg_regress"), "15", pg_regress_test_name)
124+
125+
with subtest("switch to postgresql 17"):
126+
server.succeed(
127+
f"{pg17_configuration}/bin/switch-to-configuration test >&2"
128+
)
129+
130+
with subtest("Check pg_regress with postgresql 17 after extension upgrade"):
131+
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
132+
'';
133+
}

nix/ext/versions.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,16 @@
699699
"hash": "sha256-Nmb7XLqQflYZfqj0yrewfb1Hl5YgEB5wfjBunPwIuOU="
700700
}
701701
},
702+
"pg_plan_filter": {
703+
"0.1": {
704+
"postgresql": [
705+
"15",
706+
"17"
707+
],
708+
"rev": "5081a7b5cb890876e67d8e7486b6a64c38c9a492",
709+
"hash": "sha256-YNeIfmccT/DtOrwDmpYFCuV2/P6k3Zj23VWBDkOh6sw="
710+
}
711+
},
702712
"pg_repack": {
703713
"1.4.8": {
704714
"postgresql": [

0 commit comments

Comments
 (0)