Skip to content

Commit ac51e25

Browse files
committed
test: pg 17 compatibility
1 parent 4fdfa6a commit ac51e25

14 files changed

+501
-1
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
pg-version: ['12', '13', '14', '15', '16']
12+
pg-version: ['12', '13', '14', '15', '16', '17']
1313

1414
steps:
1515
- uses: actions/checkout@v1

nix/postgresql/17.nix

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import ./generic.nix {
2+
version = "17.0";
3+
hash = "sha256-fidhMcD91rYliNutmzuyS4w0mNUAkyjbpZrxboGRCd4=";
4+
}

nix/postgresql/default.nix

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
self:
2+
let
3+
# Before removing an EOL major version, make sure to check the versioning policy in:
4+
# <nixpkgs>/nixos/modules/services/databases/postgresql.md
5+
#
6+
# Before removing, make sure to update it to the last minor version - and if only in
7+
# an immediately preceding commit. This allows people relying on that old major version
8+
# for a bit longer to still update up to this commit to at least get the latest minor
9+
# version. In other words: Do not remove the second-to-last minor version from nixpkgs,
10+
# yet. Update first.
11+
versions = {
12+
postgresql_17 = ./17.nix;
13+
};
14+
15+
mkAttributes = jitSupport:
16+
self.lib.mapAttrs' (version: path:
17+
let
18+
attrName = if jitSupport then "${version}_jit" else version;
19+
in
20+
self.lib.nameValuePair attrName (import path {
21+
inherit jitSupport self;
22+
})
23+
) versions;
24+
25+
in
26+
# variations without and with JIT
27+
(mkAttributes false) // (mkAttributes true)

nix/postgresql/generic.nix

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
let
2+
3+
generic =
4+
# dependencies
5+
{ stdenv, lib, fetchurl, makeWrapper
6+
, glibc, zlib, readline, openssl, icu, lz4, zstd, systemd, libossp_uuid
7+
, pkg-config, libxml2, tzdata, libkrb5, substituteAll, darwin
8+
, linux-pam
9+
, bison, flex, perl, docbook_xml_dtd_45, docbook-xsl-nons, libxslt
10+
11+
# This is important to obtain a version of `libpq` that does not depend on systemd.
12+
, systemdSupport ? lib.meta.availableOn stdenv.hostPlatform systemd && !stdenv.hostPlatform.isStatic
13+
, enableSystemd ? null
14+
, gssSupport ? with stdenv.hostPlatform; !isWindows && !isStatic
15+
16+
# for postgresql.pkgs
17+
, self, newScope, buildEnv
18+
19+
# source specification
20+
, version, hash, muslPatches ? {}
21+
22+
# for tests
23+
, testers, nixosTests
24+
25+
# JIT
26+
, jitSupport
27+
, nukeReferences, patchelf, llvmPackages
28+
29+
# PL/Python
30+
, pythonSupport ? false
31+
, python3
32+
33+
# detection of crypt fails when using llvm stdenv, so we add it manually
34+
# for <13 (where it got removed: https://github.com/postgres/postgres/commit/c45643d618e35ec2fe91438df15abd4f3c0d85ca)
35+
, libxcrypt
36+
} @args:
37+
let
38+
atLeast = lib.versionAtLeast version;
39+
olderThan = lib.versionOlder version;
40+
lz4Enabled = atLeast "14";
41+
zstdEnabled = atLeast "15";
42+
43+
systemdSupport' = if enableSystemd == null then systemdSupport else (lib.warn "postgresql: argument enableSystemd is deprecated, please use systemdSupport instead." enableSystemd);
44+
45+
pname = "postgresql";
46+
47+
stdenv' = if jitSupport then llvmPackages.stdenv else stdenv;
48+
in stdenv'.mkDerivation (finalAttrs: {
49+
inherit version;
50+
pname = pname + lib.optionalString jitSupport "-jit";
51+
52+
src = fetchurl {
53+
url = "mirror://postgresql/source/v${version}/${pname}-${version}.tar.bz2";
54+
inherit hash;
55+
};
56+
57+
hardeningEnable = lib.optionals (!stdenv'.cc.isClang) [ "pie" ];
58+
59+
outputs = [ "out" "lib" "doc" "man" ];
60+
setOutputFlags = false; # $out retains configureFlags :-/
61+
62+
buildInputs = [
63+
zlib
64+
readline
65+
openssl
66+
libxml2
67+
icu
68+
]
69+
++ lib.optionals (olderThan "13") [ libxcrypt ]
70+
++ lib.optionals jitSupport [ llvmPackages.llvm ]
71+
++ lib.optionals lz4Enabled [ lz4 ]
72+
++ lib.optionals zstdEnabled [ zstd ]
73+
++ lib.optionals systemdSupport' [ systemd ]
74+
++ lib.optionals pythonSupport [ python3 ]
75+
++ lib.optionals gssSupport [ libkrb5 ]
76+
++ lib.optionals stdenv'.isLinux [ linux-pam ]
77+
++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ];
78+
79+
nativeBuildInputs = [
80+
makeWrapper
81+
pkg-config
82+
]
83+
++ lib.optionals jitSupport [ llvmPackages.llvm.dev nukeReferences patchelf ]
84+
++ lib.optionals (atLeast "17") [ bison flex perl docbook_xml_dtd_45 docbook-xsl-nons libxslt ];
85+
86+
enableParallelBuilding = true;
87+
88+
separateDebugInfo = true;
89+
90+
buildFlags = [ "world" ];
91+
92+
# Makes cross-compiling work when xml2-config can't be executed on the host.
93+
# Fixed upstream in https://github.com/postgres/postgres/commit/0bc8cebdb889368abdf224aeac8bc197fe4c9ae6
94+
env.NIX_CFLAGS_COMPILE = lib.optionalString (olderThan "13") "-I${libxml2.dev}/include/libxml2";
95+
96+
configureFlags = [
97+
"--with-openssl"
98+
"--with-libxml"
99+
"--with-icu"
100+
"--sysconfdir=/etc"
101+
"--libdir=$(lib)/lib"
102+
"--with-system-tzdata=${tzdata}/share/zoneinfo"
103+
"--enable-debug"
104+
(lib.optionalString systemdSupport' "--with-systemd")
105+
(if stdenv'.isDarwin then "--with-uuid=e2fs" else "--with-ossp-uuid")
106+
] ++ lib.optionals lz4Enabled [ "--with-lz4" ]
107+
++ lib.optionals zstdEnabled [ "--with-zstd" ]
108+
++ lib.optionals gssSupport [ "--with-gssapi" ]
109+
++ lib.optionals pythonSupport [ "--with-python" ]
110+
++ lib.optionals jitSupport [ "--with-llvm" ]
111+
++ lib.optionals stdenv'.isLinux [ "--with-pam" ];
112+
113+
patches = [
114+
(if atLeast "16" then ./patches/relative-to-symlinks-16+.patch else ./patches/relative-to-symlinks.patch)
115+
./patches/less-is-more.patch
116+
./patches/paths-for-split-outputs.patch
117+
./patches/specify_pkglibdir_at_runtime.patch
118+
./patches/paths-with-postgresql-suffix.patch
119+
120+
(substituteAll {
121+
src = ./patches/locale-binary-path.patch;
122+
locale = "${if stdenv.isDarwin then darwin.adv_cmds else lib.getBin stdenv.cc.libc}/bin/locale";
123+
})
124+
125+
] ++ lib.optionals stdenv'.hostPlatform.isMusl (
126+
# Using fetchurl instead of fetchpatch on purpose: https://github.com/NixOS/nixpkgs/issues/240141
127+
map fetchurl (lib.attrValues muslPatches)
128+
) ++ lib.optionals stdenv'.isLinux [
129+
(if atLeast "13" then ./patches/socketdir-in-run-13+.patch else ./patches/socketdir-in-run.patch)
130+
];
131+
132+
installTargets = [ "install-world" ];
133+
134+
postPatch = ''
135+
# Hardcode the path to pgxs so pg_config returns the path in $out
136+
substituteInPlace "src/common/config_info.c" --subst-var out
137+
'' + lib.optionalString jitSupport ''
138+
# Force lookup of jit stuff in $out instead of $lib
139+
substituteInPlace src/backend/jit/jit.c --replace pkglib_path \"$out/lib\"
140+
substituteInPlace src/backend/jit/llvm/llvmjit.c --replace pkglib_path \"$out/lib\"
141+
substituteInPlace src/backend/jit/llvm/llvmjit_inline.cpp --replace pkglib_path \"$out/lib\"
142+
'';
143+
144+
postInstall =
145+
''
146+
moveToOutput "lib/pgxs" "$out" # looks strange, but not deleting it
147+
moveToOutput "lib/libpgcommon*.a" "$out"
148+
moveToOutput "lib/libpgport*.a" "$out"
149+
moveToOutput "lib/libecpg*" "$out"
150+
151+
# Prevent a retained dependency on gcc-wrapper.
152+
substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/ld ld
153+
154+
if [ -z "''${dontDisableStatic:-}" ]; then
155+
# Remove static libraries in case dynamic are available.
156+
for i in $out/lib/*.a $lib/lib/*.a; do
157+
name="$(basename "$i")"
158+
ext="${stdenv'.hostPlatform.extensions.sharedLibrary}"
159+
if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then
160+
rm "$i"
161+
fi
162+
done
163+
fi
164+
'' + lib.optionalString jitSupport ''
165+
# Move the bitcode and libllvmjit.so library out of $lib; otherwise, every client that
166+
# depends on libpq.so will also have libLLVM.so in its closure too, bloating it
167+
moveToOutput "lib/bitcode" "$out"
168+
moveToOutput "lib/llvmjit*" "$out"
169+
170+
# In the case of JIT support, prevent a retained dependency on clang-wrapper
171+
substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/clang clang
172+
nuke-refs $out/lib/llvmjit_types.bc $(find $out/lib/bitcode -type f)
173+
174+
# Stop out depending on the default output of llvm
175+
substituteInPlace $out/lib/pgxs/src/Makefile.global \
176+
--replace ${llvmPackages.llvm.out}/bin "" \
177+
--replace '$(LLVM_BINPATH)/' ""
178+
179+
# Stop out depending on the -dev output of llvm
180+
substituteInPlace $out/lib/pgxs/src/Makefile.global \
181+
--replace ${llvmPackages.llvm.dev}/bin/llvm-config llvm-config \
182+
--replace -I${llvmPackages.llvm.dev}/include ""
183+
184+
${lib.optionalString (!stdenv'.isDarwin) ''
185+
# Stop lib depending on the -dev output of llvm
186+
rpath=$(patchelf --print-rpath $out/lib/llvmjit.so)
187+
nuke-refs -e $out $out/lib/llvmjit.so
188+
# Restore the correct rpath
189+
patchelf $out/lib/llvmjit.so --set-rpath "$rpath"
190+
''}
191+
'';
192+
193+
postFixup = lib.optionalString (!stdenv'.isDarwin && stdenv'.hostPlatform.libc == "glibc")
194+
''
195+
# initdb needs access to "locale" command from glibc.
196+
wrapProgram $out/bin/initdb --prefix PATH ":" ${glibc.bin}/bin
197+
'';
198+
199+
doCheck = !stdenv'.isDarwin;
200+
# autodetection doesn't seem to able to find this, but it's there.
201+
checkTarget = "check";
202+
203+
disallowedReferences = [ stdenv'.cc ];
204+
205+
passthru = let
206+
this = self.callPackage generic args;
207+
jitToggle = this.override {
208+
jitSupport = !jitSupport;
209+
};
210+
in
211+
{
212+
psqlSchema = lib.versions.major version;
213+
214+
withJIT = if jitSupport then this else jitToggle;
215+
withoutJIT = if jitSupport then jitToggle else this;
216+
217+
dlSuffix = if olderThan "16" then ".so" else stdenv.hostPlatform.extensions.sharedLibrary;
218+
219+
pkgs = let
220+
scope = {
221+
inherit jitSupport;
222+
inherit (llvmPackages) llvm;
223+
postgresql = this;
224+
stdenv = stdenv';
225+
};
226+
newSelf = self // scope;
227+
newSuper = { callPackage = newScope (scope // this.pkgs); };
228+
in import ./ext newSelf newSuper;
229+
230+
withPackages = postgresqlWithPackages {
231+
inherit makeWrapper buildEnv;
232+
postgresql = this;
233+
}
234+
this.pkgs;
235+
236+
tests = {
237+
postgresql-wal-receiver = import ../../../../nixos/tests/postgresql-wal-receiver.nix {
238+
inherit (stdenv) system;
239+
pkgs = self;
240+
package = this;
241+
};
242+
pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
243+
} // lib.optionalAttrs jitSupport {
244+
postgresql-jit = import ../../../../nixos/tests/postgresql-jit.nix {
245+
inherit (stdenv) system;
246+
pkgs = self;
247+
package = this;
248+
};
249+
};
250+
};
251+
252+
meta = with lib; {
253+
homepage = "https://www.postgresql.org";
254+
description = "Powerful, open source object-relational database system";
255+
license = licenses.postgresql;
256+
changelog = "https://www.postgresql.org/docs/release/${finalAttrs.version}/";
257+
maintainers = with maintainers; [ thoughtpolice danbst globin ivan ma27 wolfgangwalther ];
258+
pkgConfigModules = [ "libecpg" "libecpg_compat" "libpgtypes" "libpq" ];
259+
platforms = platforms.unix;
260+
261+
# JIT support doesn't work with cross-compilation. It is attempted to build LLVM-bytecode
262+
# (`%.bc` is the corresponding `make(1)`-rule) for each sub-directory in `backend/` for
263+
# the JIT apparently, but with a $(CLANG) that can produce binaries for the build, not the
264+
# host-platform.
265+
#
266+
# I managed to get a cross-build with JIT support working with
267+
# `depsBuildBuild = [ llvmPackages.clang ] ++ buildInputs`, but considering that the
268+
# resulting LLVM IR isn't platform-independent this doesn't give you much.
269+
# In fact, I tried to test the result in a VM-test, but as soon as JIT was used to optimize
270+
# a query, postgres would coredump with `Illegal instruction`.
271+
broken = (jitSupport && stdenv.hostPlatform != stdenv.buildPlatform)
272+
# Allmost all tests fail FATAL errors for v12 and v13
273+
|| (jitSupport && stdenv.hostPlatform.isMusl && olderThan "14");
274+
};
275+
});
276+
277+
postgresqlWithPackages = { postgresql, makeWrapper, buildEnv }: pkgs: f: buildEnv {
278+
name = "postgresql-and-plugins-${postgresql.version}";
279+
paths = f pkgs ++ [
280+
postgresql
281+
postgresql.lib
282+
postgresql.man # in case user installs this into environment
283+
];
284+
nativeBuildInputs = [ makeWrapper ];
285+
286+
287+
# We include /bin to ensure the $out/bin directory is created, which is
288+
# needed because we'll be removing the files from that directory in postBuild
289+
# below. See #22653
290+
pathsToLink = ["/" "/bin"];
291+
292+
# Note: the duplication of executables is about 4MB size.
293+
# So a nicer solution was patching postgresql to allow setting the
294+
# libdir explicitly.
295+
postBuild = ''
296+
mkdir -p $out/bin
297+
rm $out/bin/{pg_config,postgres,pg_ctl}
298+
cp --target-directory=$out/bin ${postgresql}/bin/{postgres,pg_config,pg_ctl}
299+
wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib
300+
'';
301+
302+
passthru.version = postgresql.version;
303+
passthru.psqlSchema = postgresql.psqlSchema;
304+
};
305+
306+
in
307+
# passed by <major>.nix
308+
versionArgs:
309+
# passed by default.nix
310+
{ self, ... } @defaultArgs:
311+
self.callPackage generic (defaultArgs // versionArgs)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--- a/src/include/fe_utils/print.h
2+
+++ b/src/include/fe_utils/print.h
3+
@@ -18,7 +18,7 @@
4+
5+
/* This is not a particularly great place for this ... */
6+
#ifndef __CYGWIN__
7+
-#define DEFAULT_PAGER "more"
8+
+#define DEFAULT_PAGER "less"
9+
#else
10+
#define DEFAULT_PAGER "less"
11+
#endif
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--- a/src/backend/commands/collationcmds.c
2+
+++ b/src/backend/commands/collationcmds.c
3+
@@ -611,7 +611,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
4+
aliases = (CollAliasData *) palloc(maxaliases * sizeof(CollAliasData));
5+
naliases = 0;
6+
7+
- locale_a_handle = OpenPipeStream("locale -a", "r");
8+
+ locale_a_handle = OpenPipeStream("@locale@ -a", "r");
9+
if (locale_a_handle == NULL)
10+
ereport(ERROR,
11+
(errcode_for_file_access(),
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--- a/src/common/config_info.c
2+
+++ b/src/common/config_info.c
3+
@@ -118,7 +118,7 @@
4+
i++;
5+
6+
configdata[i].name = pstrdup("PGXS");
7+
+ strlcpy(path, "@out@/lib", sizeof(path));
8+
- get_pkglib_path(my_exec_path, path);
9+
strlcat(path, "/pgxs/src/makefiles/pgxs.mk", sizeof(path));
10+
cleanup_path(path);
11+
configdata[i].setting = pstrdup(path);

0 commit comments

Comments
 (0)