Skip to content

Commit 72570fe

Browse files
committed
feat: multiple versions for the timescaledb-apache extension
1 parent f5ba2a5 commit 72570fe

File tree

6 files changed

+199
-96
lines changed

6 files changed

+199
-96
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ result*
2525

2626
db/schema.sql
2727
common-nix.vars.pkr.hcl
28+
29+
.envrc

flake.nix

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
/*"postgis"*/
113113
];
114114

115-
#FIXME for now, timescaledb is not included in the orioledb version of supabase extensions, as there is an issue
115+
# FIXME for now, timescaledb is not included in the orioledb version of supabase extensions, as there is an issue
116116
# with building timescaledb with the orioledb patched version of postgresql
117117
orioledbPsqlExtensions = [
118118
/* pljava */
@@ -131,7 +131,6 @@
131131
ourExtensions = [
132132
./nix/ext/rum.nix
133133
./nix/ext/timescaledb.nix
134-
./nix/ext/timescaledb-2.9.1.nix
135134
./nix/ext/pgroonga.nix
136135
./nix/ext/index_advisor.nix
137136
./nix/ext/wal2json.nix
@@ -162,16 +161,13 @@
162161
./nix/ext/plv8.nix
163162
];
164163

165-
#Where we import and build the orioledb extension, we add on our custom extensions
166-
# plus the orioledb option
167-
#we're not using timescaledb or plv8 in the orioledb-17 version or pg 17 of supabase extensions
164+
# Where we import and build the orioledb extension, we add on our
165+
# custom extensions plus the orioledb option. We're not using
166+
# timescaledb or plv8 in the orioledb-17 version or pg 17 of supabase
167+
# extensions
168168
orioleFilteredExtensions = builtins.filter
169-
(
170-
x:
171-
x != ./nix/ext/timescaledb.nix &&
172-
x != ./nix/ext/timescaledb-2.9.1.nix &&
173-
x != ./nix/ext/plv8.nix
174-
) ourExtensions;
169+
(x: x != ./nix/ext/timescaledb.nix && x != ./nix/ext/plv8.nix)
170+
ourExtensions;
175171

176172
orioledbExtensions = orioleFilteredExtensions ++ [ ./nix/ext/orioledb.nix ];
177173
dbExtensions17 = orioleFilteredExtensions;
@@ -1377,6 +1373,7 @@
13771373
# The list of exported 'checks' that are run with every run of 'nix
13781374
# flake check'. This is run in the CI system, as well.
13791375
checks = {
1376+
timescaledb = import ./nix/tests/timescaledb.nix { inherit self; inherit pkgs; };
13801377
psql_15 = makeCheckHarness basePackages.psql_15.bin;
13811378
psql_17 = makeCheckHarness basePackages.psql_17.bin;
13821379
psql_orioledb-17 = makeCheckHarness basePackages.psql_orioledb-17.bin;

nix/ext/timescaledb-2.9.1.nix

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

nix/ext/timescaledb.nix

Lines changed: 90 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,97 @@
1-
{ lib, stdenv, fetchFromGitHub, cmake, postgresql, openssl, libkrb5 }:
1+
{ pkgs, lib, stdenv, fetchFromGitHub, cmake, postgresql, openssl, libkrb5 }:
22

3-
stdenv.mkDerivation rec {
4-
pname = "timescaledb-apache";
5-
version = "2.16.1";
3+
let
4+
pname = "timescaledb";
5+
build = version: hash: revision:
6+
stdenv.mkDerivation rec {
7+
inherit pname version;
68

7-
nativeBuildInputs = [ cmake ];
8-
buildInputs = [ postgresql openssl libkrb5 ];
9+
nativeBuildInputs = [ cmake ];
10+
buildInputs = [ postgresql openssl libkrb5 ];
911

10-
src = fetchFromGitHub {
11-
owner = "timescale";
12-
repo = "timescaledb";
13-
rev = version;
14-
hash = "sha256-sLxWdBmih9mgiO51zLLxn9uwJVYc5JVHJjSWoADoJ+w=";
15-
};
12+
src = fetchFromGitHub {
13+
owner = "timescale";
14+
repo = "timescaledb";
15+
rev = version;
16+
inherit hash;
17+
};
1618

17-
cmakeFlags = [ "-DSEND_TELEMETRY_DEFAULT=OFF" "-DREGRESS_CHECKS=OFF" "-DTAP_CHECKS=OFF" "-DAPACHE_ONLY=1" ]
18-
++ lib.optionals stdenv.isDarwin [ "-DLINTER=OFF" ];
19-
20-
# Fix the install phase which tries to install into the pgsql extension dir,
21-
# and cannot be manually overridden. This is rather fragile but works OK.
22-
postPatch = ''
23-
for x in CMakeLists.txt sql/CMakeLists.txt; do
24-
substituteInPlace "$x" \
25-
--replace 'DESTINATION "''${PG_SHAREDIR}/extension"' "DESTINATION \"$out/share/postgresql/extension\""
26-
done
27-
28-
for x in src/CMakeLists.txt src/loader/CMakeLists.txt tsl/src/CMakeLists.txt; do
29-
substituteInPlace "$x" \
30-
--replace 'DESTINATION ''${PG_PKGLIBDIR}' "DESTINATION \"$out/lib\""
31-
done
32-
'';
19+
cmakeFlags = [
20+
"-DSEND_TELEMETRY_DEFAULT=OFF"
21+
"-DREGRESS_CHECKS=OFF"
22+
"-DTAP_CHECKS=OFF"
23+
"-DAPACHE_ONLY=1"
24+
] ++ lib.optionals stdenv.isDarwin [ "-DLINTER=OFF" ];
25+
26+
postPatch = ''
27+
for x in CMakeLists.txt sql/CMakeLists.txt; do
28+
if [ -f "$x" ]; then
29+
substituteInPlace "$x" \
30+
--replace 'DESTINATION "''${PG_SHAREDIR}/extension"' "DESTINATION \"$out/share/postgresql/extension\""
31+
fi
32+
done
33+
34+
for x in src/CMakeLists.txt src/loader/CMakeLists.txt tsl/src/CMakeLists.txt; do
35+
if [ -f "$x" ]; then
36+
substituteInPlace "$x" \
37+
--replace 'DESTINATION ''${PG_PKGLIBDIR}' "DESTINATION \"$out/lib\""
38+
fi
39+
done
40+
'';
3341

34-
meta = with lib; {
35-
description = "Scales PostgreSQL for time-series data via automatic partitioning across time and space";
36-
homepage = "https://www.timescale.com/";
37-
changelog = "https://github.com/timescale/timescaledb/blob/${version}/CHANGELOG.md";
38-
platforms = postgresql.meta.platforms;
39-
license = licenses.asl20;
40-
broken = versionOlder postgresql.version "13";
42+
postInstall = ''
43+
if [ -f $out/lib/timescaledb.so ]; then
44+
mv $out/lib/timescaledb.so $out/lib/timescaledb-${version}.so
45+
fi
46+
if [ -f $out/share/postgresql/extension/timescaledb.control ]; then
47+
mv $out/share/postgresql/extension/timescaledb.control $out/share/postgresql/extension/timescaledb--${version}.control
48+
fi
49+
'';
50+
51+
meta = with lib; {
52+
description =
53+
"Scales PostgreSQL for time-series data via automatic partitioning across time and space";
54+
homepage = "https://www.timescale.com/";
55+
changelog =
56+
"https://github.com/timescale/timescaledb/blob/${version}/CHANGELOG.md";
57+
license = licenses.postgresql;
58+
inherit (postgresql.meta) platforms;
59+
};
60+
};
61+
62+
allVersions =
63+
(builtins.fromJSON (builtins.readFile ./versions.json)).timescaledb;
64+
supportedVersions = lib.filterAttrs (_: value:
65+
builtins.elem (lib.versions.major postgresql.version) value.postgresql)
66+
allVersions;
67+
versions = lib.naturalSort (lib.attrNames supportedVersions);
68+
latestVersion = lib.last versions;
69+
numberOfVersions = builtins.length versions;
70+
packages = builtins.attrValues
71+
(lib.mapAttrs (name: value: build name value.hash (value.revision or name))
72+
supportedVersions);
73+
in pkgs.buildEnv {
74+
name = pname;
75+
paths = packages;
76+
postBuild = ''
77+
{
78+
echo "default_version = '${latestVersion}'"
79+
cat $out/share/postgresql/extension/${pname}--${latestVersion}.control
80+
} > $out/share/postgresql/extension/${pname}.control
81+
ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix}
82+
83+
# checks
84+
(set -x
85+
test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${
86+
toString (numberOfVersions + 1)
87+
}"
88+
)
89+
'';
90+
pathsToLink = [ "/lib" "/share/postgresql/extension" ];
91+
passthru = {
92+
inherit versions numberOfVersions;
93+
pname = "${pname}-all";
94+
version = "multi-" + lib.concatStringsSep "-"
95+
(map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions);
4196
};
4297
}

nix/ext/versions.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"timescaledb": {
3+
"2.9.1": {
4+
"postgresql": [
5+
"15"
6+
],
7+
"hash": "sha256-fvVSxDiGZAewyuQ2vZDb0I6tmlDXl6trjZp8+qDBtb8="
8+
},
9+
"2.16.1": {
10+
"postgresql": [
11+
"15"
12+
],
13+
"hash": "sha256-sLxWdBmih9mgiO51zLLxn9uwJVYc5JVHJjSWoADoJ+w="
14+
}
15+
}
16+
}

nix/tests/timescaledb.nix

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{ self, pkgs }:
2+
let
3+
inherit (pkgs) lib;
4+
installedExtension = postgresMajorVersion:
5+
self.packages.${pkgs.system}."psql_${postgresMajorVersion}/exts/timescaledb-all";
6+
versions = (installedExtension "15").versions;
7+
firstVersion = lib.head versions;
8+
latestVersion = lib.last versions;
9+
postgresqlWithExtension = postgresql:
10+
let
11+
majorVersion = lib.versions.major postgresql.version;
12+
pkg = pkgs.buildEnv {
13+
name = "postgresql-${majorVersion}-timescaledb";
14+
paths = [ postgresql postgresql.lib (installedExtension majorVersion) ];
15+
passthru = {
16+
inherit (postgresql) version psqlSchema;
17+
lib = pkg;
18+
withPackages = _: pkg;
19+
};
20+
nativeBuildInputs = [ pkgs.makeWrapper ];
21+
pathsToLink = [ "/" "/bin" "/lib" ];
22+
postBuild = ''
23+
wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib
24+
wrapProgram $out/bin/pg_ctl --set NIX_PGLIBDIR $out/lib
25+
wrapProgram $out/bin/pg_upgrade --set NIX_PGLIBDIR $out/lib
26+
'';
27+
};
28+
in pkg;
29+
in self.inputs.nixpkgs.lib.nixos.runTest {
30+
name = "timescaledb";
31+
hostPkgs = pkgs;
32+
nodes.server = { config, ... }: {
33+
virtualisation = {
34+
forwardPorts = [{
35+
from = "host";
36+
host.port = 13022;
37+
guest.port = 22;
38+
}];
39+
};
40+
services.openssh = { enable = true; };
41+
users.users.root.openssh.authorizedKeys.keys = [
42+
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIArkmq6Th79Z4klW6Urgi4phN8yq769/l/10jlE00tU9"
43+
];
44+
45+
services.postgresql = {
46+
enable = true;
47+
package =
48+
postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15;
49+
settings = { shared_preload_libraries = "timescaledb"; };
50+
};
51+
52+
specialisation.postgresql15.configuration = {
53+
services.postgresql = {
54+
package = lib.mkForce
55+
(postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15);
56+
};
57+
};
58+
};
59+
testScript = { nodes, ... }: ''
60+
def run_sql(query):
61+
return server.succeed(f"""sudo -u postgres psql -t -A -F\",\" -c \"{query}\" """).strip()
62+
63+
def check_upgrade_path():
64+
with subtest("Check timescaledb upgrade path"):
65+
server.succeed("sudo -u postgres psql -c 'DROP EXTENSION IF EXISTS timescaledb;'")
66+
run_sql(r"""CREATE EXTENSION timescaledb WITH VERSION \"${firstVersion}\";""")
67+
installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = 'timescaledb';""")
68+
assert installed_version == "${firstVersion}", f"Expected timescaledb version ${firstVersion}, but found {installed_version}"
69+
for version in [${
70+
lib.concatStringsSep ", " (map (s: ''"${s}"'') versions)
71+
}][1:]:
72+
run_sql(f"""ALTER EXTENSION timescaledb UPDATE TO '{version}';""")
73+
installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = 'timescaledb';""")
74+
assert installed_version == version, f"Expected timescaledb version {version}, but found {installed_version}"
75+
76+
start_all()
77+
78+
server.wait_for_unit("multi-user.target")
79+
server.wait_for_unit("postgresql.service")
80+
81+
check_upgrade_path()
82+
'';
83+
}

0 commit comments

Comments
 (0)