Skip to content

Commit fae5be1

Browse files
samrosejfroche
andauthored
Multi version ext/pg cron (#1737)w
* feat: pg_cron multi-version with new pattern * feat: pg_cron using the new multi-version pattern not yet complete * fix: bring in some function from previous version to test * chore: move pg_cron extension package to its own directory * feat: add nixos test for pg_cron extension * feat: refactor pg_cron to use buildEnv Fix upgrade nixos tests that was broken. Move overlays and switch-ext-version script to package. * feat: refactor pg_net according to previous refactoring * Refactor postgres extensions tests Keep the postgres extension tests DRY by extracting shared logic into a shared library. * chore: format python files using ruff * chore: rebase on develop and bump version for retsting * ore: bump version for deploy --------- Co-authored-by: Jean-François Roche <[email protected]>
1 parent 6102e10 commit fae5be1

20 files changed

+881
-759
lines changed

ansible/vars.yml

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

1010
# Full version strings for each major version
1111
postgres_release:
12-
postgresorioledb-17: "17.5.1.023-orioledb"
13-
postgres17: "17.6.1.002"
14-
postgres15: "15.14.1.002"
12+
postgresorioledb-17: "17.5.1.024-orioledb"
13+
postgres17: "17.6.1.003"
14+
postgres15: "15.14.1.003"
1515

1616
# Non Postgres Extensions
1717
pgbouncer_release: "1.19.0"

nix/checks.nix

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -308,16 +308,14 @@
308308
postgresql_17_src
309309
;
310310
}
311-
// pkgs.lib.optionalAttrs (system == "x86_64-linux") {
312-
pg_net = import ./ext/tests/pg_net.nix {
311+
// pkgs.lib.optionalAttrs (system == "x86_64-linux") (
312+
{
313+
devShell = self'.devShells.default;
314+
}
315+
// (import ./ext/tests {
313316
inherit self;
314317
inherit pkgs;
315-
};
316-
wrappers = import ./ext/tests/wrappers.nix {
317-
inherit self;
318-
inherit pkgs;
319-
};
320-
devShell = self'.devShells.default;
321-
};
318+
})
319+
);
322320
};
323321
}

nix/ext/index_advisor.nix

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
stdenv,
55
fetchFromGitHub,
66
postgresql,
7+
callPackage,
78
}:
89

910
let
@@ -69,7 +70,8 @@ let
6970
in
7071
pkgs.buildEnv {
7172
name = pname;
72-
paths = packages;
73+
# Add dependency on hypopg for the extension to work
74+
paths = packages ++ [ (callPackage ./hypopg.nix { inherit postgresql; }) ];
7375
pathsToLink = [
7476
"/lib"
7577
"/share/postgresql/extension"

nix/ext/pg_cron.nix

Lines changed: 0 additions & 36 deletions
This file was deleted.

nix/ext/pg_cron/default.nix

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
{
2+
lib,
3+
stdenv,
4+
fetchFromGitHub,
5+
postgresql,
6+
buildEnv,
7+
makeWrapper,
8+
switch-ext-version,
9+
}:
10+
let
11+
pname = "pg_cron";
12+
allVersions = (builtins.fromJSON (builtins.readFile ../versions.json)).${pname};
13+
supportedVersions = lib.filterAttrs (
14+
_: value: builtins.elem (lib.versions.major postgresql.version) value.postgresql
15+
) allVersions;
16+
versions = lib.naturalSort (lib.attrNames supportedVersions);
17+
latestVersion = lib.last versions;
18+
numberOfVersions = builtins.length versions;
19+
build =
20+
version: versionData:
21+
stdenv.mkDerivation rec {
22+
inherit pname version;
23+
24+
buildInputs = [ postgresql ];
25+
26+
src = fetchFromGitHub {
27+
owner = "citusdata";
28+
repo = pname;
29+
rev = versionData.rev or "v${version}";
30+
hash = versionData.hash;
31+
};
32+
33+
patches = map (p: ./. + "/${p}") (versionData.patches or [ ]);
34+
35+
buildPhase = ''
36+
make PG_CONFIG=${postgresql}/bin/pg_config
37+
'';
38+
39+
installPhase = ''
40+
mkdir -p $out/{lib,share/postgresql/extension}
41+
42+
# Install versioned library
43+
install -Dm755 ${pname}${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix}
44+
45+
46+
if [[ "${version}" == "${latestVersion}" ]]; then
47+
cp ${pname}.sql $out/share/postgresql/extension/${pname}--1.0.0.sql
48+
# Install upgrade scripts
49+
find . -name 'pg_cron--*--*.sql' -exec install -Dm644 {} $out/share/postgresql/extension/ \;
50+
mv $out/share/postgresql/extension/pg_cron--1.0--1.1.sql $out/share/postgresql/extension/pg_cron--1.0.0--1.1.0.sql
51+
mv $out/share/postgresql/extension/pg_cron--1.1--1.2.sql $out/share/postgresql/extension/pg_cron--1.1.0--1.2.0.sql
52+
mv $out/share/postgresql/extension/pg_cron--1.2--1.3.sql $out/share/postgresql/extension/pg_cron--1.2.0--1.3.1.sql
53+
mv $out/share/postgresql/extension/pg_cron--1.3--1.4.sql $out/share/postgresql/extension/pg_cron--1.3.1--1.4.2.sql
54+
mv $out/share/postgresql/extension/pg_cron--1.4--1.4-1.sql $out/share/postgresql/extension/pg_cron--1.4.0--1.4.1.sql
55+
mv $out/share/postgresql/extension/pg_cron--1.4-1--1.5.sql $out/share/postgresql/extension/pg_cron--1.4.2--1.5.2.sql
56+
mv $out/share/postgresql/extension/pg_cron--1.5--1.6.sql $out/share/postgresql/extension/pg_cron--1.5.2--1.6.4.sql
57+
fi
58+
59+
# Create versioned control file with modified module path
60+
sed -e "/^default_version =/d" \
61+
-e "/^schema =/d" \
62+
-e "s|^module_pathname = .*|module_pathname = '\$libdir/${pname}'|" \
63+
${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control
64+
'';
65+
66+
meta = with lib; {
67+
description = "Run Cron jobs through PostgreSQL";
68+
homepage = "https://github.com/citusdata/pg_cron";
69+
changelog = "https://github.com/citusdata/pg_cron/raw/v${version}/CHANGELOG.md";
70+
platforms = postgresql.meta.platforms;
71+
license = licenses.postgresql;
72+
};
73+
};
74+
packages = builtins.attrValues (lib.mapAttrs (name: value: build name value) supportedVersions);
75+
in
76+
buildEnv {
77+
name = pname;
78+
paths = packages;
79+
nativeBuildInputs = [ makeWrapper ];
80+
81+
pathsToLink = [
82+
"/lib"
83+
"/share/postgresql/extension"
84+
];
85+
86+
postBuild = ''
87+
{
88+
echo "default_version = '${latestVersion}'"
89+
cat $out/share/postgresql/extension/${pname}--${latestVersion}.control
90+
} > $out/share/postgresql/extension/${pname}.control
91+
ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix}
92+
93+
# checks
94+
(set -x
95+
test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${
96+
toString (numberOfVersions + 1)
97+
}"
98+
)
99+
100+
makeWrapper ${lib.getExe switch-ext-version} $out/bin/switch_pg_cron_version \
101+
--prefix EXT_WRAPPER : "$out" --prefix EXT_NAME : "${pname}"
102+
'';
103+
104+
meta = with lib; {
105+
description = "Run Cron jobs through PostgreSQL (multi-version compatible)";
106+
homepage = "https://github.com/citusdata/pg_cron";
107+
platforms = postgresql.meta.platforms;
108+
license = licenses.postgresql;
109+
};
110+
111+
passthru = {
112+
inherit versions numberOfVersions switch-ext-version;
113+
pname = "${pname}-all";
114+
hasBackgroundWorker = true;
115+
defaultSettings = {
116+
shared_preload_libraries = [ "pg_cron" ];
117+
"cron.database_name" = "postgres";
118+
};
119+
version =
120+
"multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions);
121+
};
122+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
diff --git a/src/pg_cron.c b/src/pg_cron.c
2+
index e0ca973..4d51b2c 100644
3+
--- a/src/pg_cron.c
4+
+++ b/src/pg_cron.c
5+
@@ -14,6 +14,8 @@
6+
#include <sys/resource.h>
7+
8+
#include "postgres.h"
9+
+#include "commands/async.h"
10+
+#include "miscadmin.h"
11+
#include "fmgr.h"
12+
13+
/* these are always necessary for a bgworker */
14+
@@ -1908,7 +1910,7 @@ CronBackgroundWorker(Datum main_arg)
15+
/* Post-execution cleanup. */
16+
disable_timeout(STATEMENT_TIMEOUT, false);
17+
CommitTransactionCommand();
18+
- ProcessCompletedNotifies();
19+
+ /* ProcessCompletedNotifies removed */
20+
pgstat_report_activity(STATE_IDLE, command);
21+
pgstat_report_stat(true);
22+
23+
@@ -2025,7 +2027,7 @@ ExecuteSqlString(const char *sql)
24+
*/
25+
oldcontext = MemoryContextSwitchTo(parsecontext);
26+
#if PG_VERSION_NUM >= 100000
27+
- querytree_list = pg_analyze_and_rewrite(parsetree, sql, NULL, 0,NULL);
28+
+ querytree_list = pg_analyze_and_rewrite_fixedparams(parsetree, sql, NULL, 0, NULL);
29+
#else
30+
querytree_list = pg_analyze_and_rewrite(parsetree, sql, NULL, 0);
31+
#endif

nix/ext/pg_net.nix

Lines changed: 8 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -6,111 +6,11 @@
66
curl,
77
postgresql,
88
libuv,
9-
writeShellApplication,
109
makeWrapper,
10+
switch-ext-version,
1111
}:
1212

1313
let
14-
enableOverlayOnPackage = writeShellApplication {
15-
name = "enable_overlay_on_package";
16-
runtimeInputs = [ pkgs.coreutils ];
17-
text = ''
18-
# This script enable overlayfs on a specific nix store path
19-
set -euo pipefail
20-
21-
if [ $# -ne 1 ]; then
22-
echo "Usage: $0 <path>"
23-
exit 1
24-
fi
25-
26-
PACKAGE_PATH="$1"
27-
PACKAGE_NAME=$(basename "$1"|cut -c 34-)
28-
29-
# Nixos compatibility: use systemd mount unit
30-
#shellcheck disable=SC1091
31-
source /etc/os-release || true
32-
if [[ "$ID" == "nixos" ]]; then
33-
# This script is used in NixOS test only for the moment
34-
SYSTEMD_DIR="/run/systemd/system"
35-
else
36-
SYSTEMD_DIR="/etc/systemd/system"
37-
fi
38-
39-
# Create required directories for overlay
40-
echo "$PACKAGE_NAME"
41-
mkdir -p "/var/lib/overlay/$PACKAGE_NAME/"{upper,work}
42-
43-
PACKAGE_MOUNT_PATH=$(systemd-escape -p --suffix=mount "$PACKAGE_PATH")
44-
45-
cat > "$SYSTEMD_DIR/$PACKAGE_MOUNT_PATH" <<EOF
46-
[Unit]
47-
Description=Overlay mount for PostgreSQL extension $PACKAGE_NAME
48-
49-
[Mount]
50-
What=overlay
51-
Type=overlay
52-
Options=lowerdir=$PACKAGE_PATH,upperdir=/var/lib/overlay/$PACKAGE_NAME/upper,workdir=/var/lib/overlay/$PACKAGE_NAME/work
53-
54-
[Install]
55-
WantedBy=multi-user.target
56-
EOF
57-
58-
systemctl daemon-reload
59-
systemctl start "$PACKAGE_MOUNT_PATH"
60-
'';
61-
};
62-
switchPgNetVersion = writeShellApplication {
63-
name = "switch_pg_net_version";
64-
runtimeInputs = [ pkgs.coreutils ];
65-
text = ''
66-
# Create version switcher script
67-
set -euo pipefail
68-
69-
# Check if the required environment variables are set
70-
if [ -z "''${EXT_WRAPPER:-}" ]; then
71-
echo "Error: EXT_WRAPPER environment variable is not set."
72-
exit 1
73-
fi
74-
75-
if [ $# -ne 1 ]; then
76-
echo "Usage: $0 <version>"
77-
echo "Example: $0 0.10.0"
78-
echo ""
79-
echo "Optional environment variables:"
80-
echo " NIX_PROFILE - Path to nix profile (default: /var/lib/postgresql/.nix-profile)"
81-
echo " LIB_DIR - Override library directory"
82-
echo " EXTENSION_DIR - Override extension directory"
83-
exit 1
84-
fi
85-
86-
VERSION="$1"
87-
echo "$VERSION"
88-
89-
# Enable overlay on the wrapper package to be able to switch version
90-
${lib.getExe enableOverlayOnPackage} "$EXT_WRAPPER"
91-
92-
# Check if version exists
93-
EXT_WRAPPER_LIB="$EXT_WRAPPER/lib"
94-
PG_NET_LIB_TO_USE="$EXT_WRAPPER_LIB/pg_net-$VERSION${postgresql.dlSuffix}"
95-
if [ ! -f "$PG_NET_LIB_TO_USE" ]; then
96-
echo "Error: Version $VERSION not found in $EXT_WRAPPER_LIB"
97-
echo "Available versions:"
98-
#shellcheck disable=SC2012
99-
ls "$EXT_WRAPPER_LIB"/pg_net-*${postgresql.dlSuffix} 2>/dev/null | sed 's/.*pg_net-/ /' | sed 's/${postgresql.dlSuffix}$//' || echo " No versions found"
100-
exit 1
101-
fi
102-
103-
# Update library symlink
104-
ln -sfnv "$PG_NET_LIB_TO_USE" "$EXT_WRAPPER_LIB/pg_net${postgresql.dlSuffix}"
105-
106-
# Update control file
107-
EXT_WRAPPER_SHARE="$EXT_WRAPPER/share/postgresql/extension"
108-
echo "default_version = '$VERSION'" > "$EXT_WRAPPER_SHARE/pg_net.control"
109-
cat "$EXT_WRAPPER_SHARE/pg_net--$VERSION.control" >> "$EXT_WRAPPER_SHARE/pg_net.control"
110-
111-
echo "Successfully switched pg_net to version $VERSION"
112-
'';
113-
};
11414
pname = "pg_net";
11515
build =
11616
version: hash:
@@ -211,13 +111,17 @@ pkgs.buildEnv {
211111
}"
212112
)
213113
214-
makeWrapper ${lib.getExe switchPgNetVersion} $out/bin/switch_pg_net_version \
215-
--prefix EXT_WRAPPER : "$out"
114+
makeWrapper ${lib.getExe switch-ext-version} $out/bin/switch_pg_net_version \
115+
--prefix EXT_WRAPPER : "$out" --prefix EXT_NAME : "${pname}"
216116
'';
217117

218118
passthru = {
219-
inherit versions numberOfVersions switchPgNetVersion;
119+
inherit versions numberOfVersions;
220120
pname = "${pname}-all";
121+
hasBackgroundWorker = true;
122+
defaultSettings = {
123+
shared_preload_libraries = [ "pg_net" ];
124+
};
221125
version =
222126
"multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions);
223127
};

0 commit comments

Comments
 (0)