From 9f5e90b69d504a23545b1579825a10fdf2dcdbc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Roche?= Date: Fri, 27 Jun 2025 11:18:50 +0200 Subject: [PATCH 1/6] feat: support multiple versions of the pg_tap extension Build multiple versions of the pg_tap extension on different PostgreSQL versions. Add test for the extensions and their upgrade on PostgreSQL 15 and 17. --- nix/ext/gdal.nix | 17 +- nix/ext/pg_jsonschema/default.nix | 3 +- nix/ext/pg_net.nix | 3 +- nix/ext/pgaudit.nix | 26 +- nix/ext/pgroonga/default.nix | 3 +- nix/ext/pgrouting.nix | 15 +- nix/ext/pgtap.nix | 135 ++++++-- nix/ext/plv8/default.nix | 90 +++--- nix/ext/postgis.nix | 3 +- nix/ext/tests/lib.py | 24 +- nix/ext/tests/pgrouting.nix | 19 +- nix/ext/tests/pgtap.nix | 154 +++++++++ nix/ext/timescaledb.nix | 3 +- nix/ext/vault.nix | 43 ++- nix/ext/versions.json | 22 ++ nix/ext/wal2json.nix | 2 +- nix/ext/wrappers/default.nix | 21 +- nix/packages/groonga/default.nix | 29 +- nix/packages/lib.nix | 13 +- nix/postgresql/generic.nix | 301 +++++++++--------- nix/tests/expected/z_15_ext_interface.out | 9 +- nix/tests/expected/z_17_ext_interface.out | 9 +- .../expected/z_orioledb-17_ext_interface.out | 9 +- testinfra/test_ami_nix.py | 28 +- 24 files changed, 617 insertions(+), 364 deletions(-) create mode 100644 nix/ext/tests/pgtap.nix diff --git a/nix/ext/gdal.nix b/nix/ext/gdal.nix index 739f7e4324..c4dba3e695 100644 --- a/nix/ext/gdal.nix +++ b/nix/ext/gdal.nix @@ -47,15 +47,14 @@ stdenv.mkDerivation rec { zlib ]; - cmakeFlags = - [ - "-DGDAL_USE_INTERNAL_LIBS=OFF" - "-DGEOTIFF_INCLUDE_DIR=${lib.getDev libgeotiff}/include" - "-DGEOTIFF_LIBRARY_RELEASE=${lib.getLib libgeotiff}/lib/libgeotiff${stdenv.hostPlatform.extensions.sharedLibrary}" - "-DBUILD_PYTHON_BINDINGS=OFF" - ] - ++ lib.optionals (!stdenv.isDarwin) [ "-DCMAKE_SKIP_BUILD_RPATH=ON" ] - ++ lib.optionals stdenv.isDarwin [ "-DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON" ]; + cmakeFlags = [ + "-DGDAL_USE_INTERNAL_LIBS=OFF" + "-DGEOTIFF_INCLUDE_DIR=${lib.getDev libgeotiff}/include" + "-DGEOTIFF_LIBRARY_RELEASE=${lib.getLib libgeotiff}/lib/libgeotiff${stdenv.hostPlatform.extensions.sharedLibrary}" + "-DBUILD_PYTHON_BINDINGS=OFF" + ] + ++ lib.optionals (!stdenv.isDarwin) [ "-DCMAKE_SKIP_BUILD_RPATH=ON" ] + ++ lib.optionals stdenv.isDarwin [ "-DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON" ]; enableParallelBuilding = true; diff --git a/nix/ext/pg_jsonschema/default.nix b/nix/ext/pg_jsonschema/default.nix index 1a2e8ee58f..84624300b6 100644 --- a/nix/ext/pg_jsonschema/default.nix +++ b/nix/ext/pg_jsonschema/default.nix @@ -45,7 +45,8 @@ let nativeBuildInputs = [ cargo ]; buildInputs = [ postgresql - ] ++ lib.optionals stdenv.isDarwin [ darwin.apple_sdk.frameworks.SystemConfiguration ]; + ] + ++ lib.optionals stdenv.isDarwin [ darwin.apple_sdk.frameworks.SystemConfiguration ]; # update the following array when the pg_jsonschema version is updated # required to ensure that extensions update scripts from previous versions are generated diff --git a/nix/ext/pg_net.nix b/nix/ext/pg_net.nix index 229971a81c..d9f47aab84 100644 --- a/nix/ext/pg_net.nix +++ b/nix/ext/pg_net.nix @@ -20,7 +20,8 @@ let buildInputs = [ curl postgresql - ] ++ lib.optional (version == "0.6") libuv; + ] + ++ lib.optional (version == "0.6") libuv; src = fetchFromGitHub { owner = "supabase"; diff --git a/nix/ext/pgaudit.nix b/nix/ext/pgaudit.nix index 7660f2bd13..55dd237f7c 100644 --- a/nix/ext/pgaudit.nix +++ b/nix/ext/pgaudit.nix @@ -184,22 +184,20 @@ buildEnv { echo "Found control version: $controlVer from package ${pkg}" # Create migrations from control version to all supported versions on this PG major - ${ - lib.concatMapStringsSep "\n" (targetVer: '' - # Skip if control version equals target version - if [[ "$controlVer" != "${targetVer}" ]]; then - # Skip if migration already exists - if [[ ! -f "$out/share/postgresql/extension/${pname}--$controlVer--${targetVer}.sql" ]]; then - # Create symlink to migration if target SQL exists - if [[ -f "$out/share/postgresql/extension/${pname}--${targetVer}.sql" ]]; then - echo "Creating migration symlink from control version $controlVer to ${targetVer}" - ln -s "$out/share/postgresql/extension/${pname}--${targetVer}.sql" \ - "$out/share/postgresql/extension/${pname}--$controlVer--${targetVer}.sql" - fi + ${lib.concatMapStringsSep "\n" (targetVer: '' + # Skip if control version equals target version + if [[ "$controlVer" != "${targetVer}" ]]; then + # Skip if migration already exists + if [[ ! -f "$out/share/postgresql/extension/${pname}--$controlVer--${targetVer}.sql" ]]; then + # Create symlink to migration if target SQL exists + if [[ -f "$out/share/postgresql/extension/${pname}--${targetVer}.sql" ]]; then + echo "Creating migration symlink from control version $controlVer to ${targetVer}" + ln -s "$out/share/postgresql/extension/${pname}--${targetVer}.sql" \ + "$out/share/postgresql/extension/${pname}--$controlVer--${targetVer}.sql" fi fi - '') versions - } + fi + '') versions} fi '') packages} diff --git a/nix/ext/pgroonga/default.nix b/nix/ext/pgroonga/default.nix index 22a8c2dfc6..89aca72a23 100644 --- a/nix/ext/pgroonga/default.nix +++ b/nix/ext/pgroonga/default.nix @@ -57,7 +57,8 @@ let msgpack-c supabase-groonga mecab - ] ++ lib.optionals stdenv.isDarwin [ xxHash ]; + ] + ++ lib.optionals stdenv.isDarwin [ xxHash ]; propagatedBuildInputs = [ supabase-groonga diff --git a/nix/ext/pgrouting.nix b/nix/ext/pgrouting.nix index 48833791e7..5690a41406 100644 --- a/nix/ext/pgrouting.nix +++ b/nix/ext/pgrouting.nix @@ -54,13 +54,14 @@ let stdenv.isDarwin && lib.versionAtLeast postgresql.version "16" ) "-Wno-error=int-conversion -Wno-error=incompatible-pointer-types"; - cmakeFlags = - [ "-DPOSTGRESQL_VERSION=${postgresql.version}" ] - ++ lib.optionals (stdenv.isDarwin && lib.versionAtLeast postgresql.version "16") [ - "-DCMAKE_MACOSX_RPATH=ON" - "-DCMAKE_SHARED_MODULE_SUFFIX=.dylib" - "-DCMAKE_SHARED_LIBRARY_SUFFIX=.dylib" - ]; + cmakeFlags = [ + "-DPOSTGRESQL_VERSION=${postgresql.version}" + ] + ++ lib.optionals (stdenv.isDarwin && lib.versionAtLeast postgresql.version "16") [ + "-DCMAKE_MACOSX_RPATH=ON" + "-DCMAKE_SHARED_MODULE_SUFFIX=.dylib" + "-DCMAKE_SHARED_LIBRARY_SUFFIX=.dylib" + ]; preConfigure = lib.optionalString (stdenv.isDarwin && lib.versionAtLeast postgresql.version "16") '' export DLSUFFIX=.dylib diff --git a/nix/ext/pgtap.nix b/nix/ext/pgtap.nix index a060c552b7..86bc0c9506 100644 --- a/nix/ext/pgtap.nix +++ b/nix/ext/pgtap.nix @@ -6,41 +6,116 @@ perl, perlPackages, which, + buildEnv, + fetchpatch2, }: - -stdenv.mkDerivation rec { +let pname = "pgtap"; - name = pname; - version = "1.2.0"; - src = fetchFromGitHub { - owner = "theory"; - repo = "pgtap"; - rev = "v${version}"; - hash = "sha256-lb0PRffwo6J5a6Hqw1ggvn0cW7gPZ02OEcLPi9ineI8="; - }; + # Load version configuration from external file + allVersions = (builtins.fromJSON (builtins.readFile ./versions.json)).${pname}; + + # Filter versions compatible with current PostgreSQL version + supportedVersions = lib.filterAttrs ( + _: value: builtins.elem (lib.versions.major postgresql.version) value.postgresql + ) allVersions; + + # Derived version information + versions = lib.naturalSort (lib.attrNames supportedVersions); + latestVersion = lib.last versions; + numberOfVersions = builtins.length versions; + packages = builtins.attrValues ( + lib.mapAttrs (name: value: build name value.hash) supportedVersions + ); + repoOwner = "theory"; + + # Build function for individual versions + build = + version: hash: + stdenv.mkDerivation rec { + inherit pname version; + + src = fetchFromGitHub { + owner = repoOwner; + repo = pname; + rev = "v${version}"; + inherit hash; + }; + + nativeBuildInputs = [ + postgresql + perl + perlPackages.TAPParserSourceHandlerpgTAP + which + ]; + + patches = lib.optionals (version == "1.3.3") [ + # Fix error in upgrade script from 1.2.0 to 1.3.3 + (fetchpatch2 { + name = "pgtap-fix-upgrade-from-1.2.0-to-1.3.3.patch"; + url = "https://github.com/${repoOwner}/${pname}/pull/338.diff?full_index=1"; + hash = "sha256-AVRQyqCGoc0gcoMRWBJKMmUBjadGtWg7rvHmTq5rRpw="; + }) + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/{lib,share/postgresql/extension} + + # Create version-specific control file + sed -e "/^default_version =/d" \ + -e "s|^module_pathname = .*|module_pathname = '$ext'|" \ + ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control + + # Copy SQL file to install the specific version + cp sql/${pname}--${version}.sql $out/share/postgresql/extension + + if [[ -f src/pgtap.so ]]; then + # Install the shared library with version suffix + install -Dm755 src/pgtap.so $out/lib/${pname}-${version}${postgresql.dlSuffix} + fi + + # For the latest version, create default control file and symlink and copy SQL upgrade scripts + if [[ "${version}" == "${latestVersion}" ]]; then + { + echo "default_version = '${version}'" + cat $out/share/postgresql/extension/${pname}--${version}.control + } > $out/share/postgresql/extension/${pname}.control + cp sql/${pname}--*--*.sql $out/share/postgresql/extension + elif [[ "${version}" == "1.3.1" ]]; then + # 1.3.1 is the first and only version with a C extension + ln -sfn ${pname}-${version}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} + fi + ''; + + meta = with lib; { + description = "A unit testing framework for PostgreSQL"; + longDescription = '' + pgTAP is a unit testing framework for PostgreSQL written in PL/pgSQL and PL/SQL. + It includes a comprehensive collection of TAP-emitting assertion functions, + as well as the ability to integrate with other TAP-emitting test frameworks. + It can also be used in the xUnit testing style. + ''; + homepage = "https://pgtap.org"; + inherit (postgresql.meta) platforms; + license = licenses.mit; + }; + }; +in +buildEnv { + name = pname; + paths = packages; - nativeBuildInputs = [ - postgresql - perl - perlPackages.TAPParserSourceHandlerpgTAP - which + pathsToLink = [ + "/lib" + "/share/postgresql/extension" ]; - installPhase = '' - install -D {sql/pgtap--${version}.sql,pgtap.control} -t $out/share/postgresql/extension - ''; - - meta = with lib; { - description = "A unit testing framework for PostgreSQL"; - longDescription = '' - pgTAP is a unit testing framework for PostgreSQL written in PL/pgSQL and PL/SQL. - It includes a comprehensive collection of TAP-emitting assertion functions, - as well as the ability to integrate with other TAP-emitting test frameworks. - It can also be used in the xUnit testing style. - ''; - homepage = "https://pgtap.org"; - inherit (postgresql.meta) platforms; - license = licenses.mit; + passthru = { + inherit versions numberOfVersions; + pname = "${pname}-all"; + version = + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/plv8/default.nix b/nix/ext/plv8/default.nix index d858405ed4..5df87bb747 100644 --- a/nix/ext/plv8/default.nix +++ b/nix/ext/plv8/default.nix @@ -50,49 +50,47 @@ let inherit hash; }; - patches = - [ - # Allow building with system v8. - # https://github.com/plv8/plv8/pull/505 (rejected) - ./0001-build-Allow-using-V8-from-system-${version}.patch - ] - ++ lib.optionals (builtins.compareVersions "3.1.10" version >= 0) [ - # Apply https://github.com/plv8/plv8/pull/552/ patch to fix extension upgrade problems - ./0001-fix-upgrade-related-woes-with-GUC-redefinitions-${version}.patch - ]; + patches = [ + # Allow building with system v8. + # https://github.com/plv8/plv8/pull/505 (rejected) + ./0001-build-Allow-using-V8-from-system-${version}.patch + ] + ++ lib.optionals (builtins.compareVersions "3.1.10" version >= 0) [ + # Apply https://github.com/plv8/plv8/pull/552/ patch to fix extension upgrade problems + ./0001-fix-upgrade-related-woes-with-GUC-redefinitions-${version}.patch + ]; - nativeBuildInputs = - [ perl ] - ++ lib.optionals stdenv.isDarwin [ - clang - xcbuild - ]; + nativeBuildInputs = [ + perl + ] + ++ lib.optionals stdenv.isDarwin [ + clang + xcbuild + ]; - buildInputs = - [ - (if (builtins.compareVersions "3.1.10" version >= 0) then v8 else nodejs_20.libv8) - postgresql - ] - ++ lib.optionals stdenv.isDarwin [ - darwin.apple_sdk.frameworks.CoreFoundation - darwin.apple_sdk.frameworks.Kerberos - ]; + buildInputs = [ + (if (builtins.compareVersions "3.1.10" version >= 0) then v8 else nodejs_20.libv8) + postgresql + ] + ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.CoreFoundation + darwin.apple_sdk.frameworks.Kerberos + ]; buildFlags = [ "all" ]; - makeFlags = - [ - # Nixpkgs build a v8 monolith instead of separate v8_libplatform. - "USE_SYSTEM_V8=1" - "V8_OUTDIR=${v8}/lib" - "PG_CONFIG=${postgresql}/bin/pg_config" - ] - ++ lib.optionals stdenv.isDarwin [ - "CC=${clang}/bin/clang" - "CXX=${clang}/bin/clang++" - "SHLIB_LINK=-L${v8}/lib -lv8_monolith -Wl,-rpath,${v8}/lib" - ] - ++ lib.optionals (!stdenv.isDarwin) [ "SHLIB_LINK=-lv8" ]; + makeFlags = [ + # Nixpkgs build a v8 monolith instead of separate v8_libplatform. + "USE_SYSTEM_V8=1" + "V8_OUTDIR=${v8}/lib" + "PG_CONFIG=${postgresql}/bin/pg_config" + ] + ++ lib.optionals stdenv.isDarwin [ + "CC=${clang}/bin/clang" + "CXX=${clang}/bin/clang++" + "SHLIB_LINK=-L${v8}/lib -lv8_monolith -Wl,-rpath,${v8}/lib" + ] + ++ lib.optionals (!stdenv.isDarwin) [ "SHLIB_LINK=-lv8" ]; NIX_LDFLAGS = lib.optionals stdenv.isDarwin [ "-L${postgresql}/lib" @@ -144,11 +142,9 @@ let install_name_tool -change @rpath/libv8_monolith.dylib ${v8}/lib/libv8_monolith.dylib $out/lib/$LIB_NAME ''} - ${ - lib.optionalString (!stdenv.isDarwin) '' - ${patchelf}/bin/patchelf --set-rpath "${v8}/lib:${postgresql}/lib:${libcxx}/lib" $out/lib/$LIB_NAME - '' - } + ${lib.optionalString (!stdenv.isDarwin) '' + ${patchelf}/bin/patchelf --set-rpath "${v8}/lib:${postgresql}/lib:${libcxx}/lib" $out/lib/$LIB_NAME + ''} else ${lib.optionalString stdenv.isDarwin '' install_name_tool -add_rpath "${v8}/lib" $out/lib/$LIB_NAME @@ -157,11 +153,9 @@ let install_name_tool -change @rpath/libv8_monolith.dylib ${v8}/lib/libv8_monolith.dylib $out/lib/$LIB_NAME ''} - ${ - lib.optionalString (!stdenv.isDarwin) '' - ${patchelf}/bin/patchelf --set-rpath "${v8}/lib:${postgresql}/lib:${libcxx}/lib" $out/lib/$LIB_NAME - '' - } + ${lib.optionalString (!stdenv.isDarwin) '' + ${patchelf}/bin/patchelf --set-rpath "${v8}/lib:${postgresql}/lib:${libcxx}/lib" $out/lib/$LIB_NAME + ''} fi # plv8 3.2.x removed support for coffeejs and livescript diff --git a/nix/ext/postgis.nix b/nix/ext/postgis.nix index cdf48fb24d..a8dd831a14 100644 --- a/nix/ext/postgis.nix +++ b/nix/ext/postgis.nix @@ -79,7 +79,8 @@ let protobufc pcre2.dev sfcgal - ] ++ lib.optional stdenv.isDarwin libiconv; + ] + ++ lib.optional stdenv.isDarwin libiconv; nativeBuildInputs = [ perl pkg-config diff --git a/nix/ext/tests/lib.py b/nix/ext/tests/lib.py index d04f830fd4..66d96523df 100644 --- a/nix/ext/tests/lib.py +++ b/nix/ext/tests/lib.py @@ -93,9 +93,9 @@ def assert_version_matches(self, expected_version: str): AssertionError: If the installed version does not match the expected version """ installed_version = self.get_installed_version() - assert ( - installed_version == expected_version - ), f"Expected version {expected_version}, but found {installed_version}" + assert installed_version == expected_version, ( + f"Expected version {expected_version}, but found {installed_version}" + ) def check_upgrade_path(self, pg_version: str): """Test the complete upgrade path for a PostgreSQL version. @@ -163,9 +163,9 @@ def check_switch_extension_with_background_worker( f"No versions available for PostgreSQL version {pg_version}" ) last_version = available_versions[-1] - assert ext_version.endswith( - f"{last_version}.so" - ), f"Expected {self.extension_name} version {last_version}, but found {ext_version}" + assert ext_version.endswith(f"{last_version}.so"), ( + f"Expected {self.extension_name} version {last_version}, but found {ext_version}" + ) # Switch to the first version first_version = available_versions[0] @@ -173,17 +173,17 @@ def check_switch_extension_with_background_worker( # Check that we are using the first version now ext_version = self.vm.succeed(f"readlink -f {extension_lib_path}").strip() - assert ext_version.endswith( - f"{first_version}.so" - ), f"Expected {self.extension_name} version {first_version}, but found {ext_version}" + assert ext_version.endswith(f"{first_version}.so"), ( + f"Expected {self.extension_name} version {first_version}, but found {ext_version}" + ) # Switch to the last version self.vm.succeed(f"switch_{self.extension_name}_version {last_version}") # Check that we are using the last version now ext_version = self.vm.succeed(f"readlink -f {extension_lib_path}").strip() - assert ext_version.endswith( - f"{last_version}.so" - ), f"Expected {self.extension_name} version {last_version}, but found {ext_version}" + assert ext_version.endswith(f"{last_version}.so"), ( + f"Expected {self.extension_name} version {last_version}, but found {ext_version}" + ) def check_pg_regress(self, pg_regress: Path, pg_version: str, test_name: str): """Run pg_regress tests for the extension on a given PostgreSQL version. diff --git a/nix/ext/tests/pgrouting.nix b/nix/ext/tests/pgrouting.nix index f4550b576f..e3dfc6dc38 100644 --- a/nix/ext/tests/pgrouting.nix +++ b/nix/ext/tests/pgrouting.nix @@ -12,16 +12,15 @@ let majorVersion = lib.versions.major postgresql.version; pkg = pkgs.buildEnv { name = "postgresql-${majorVersion}-${pname}"; - paths = - [ - postgresql - postgresql.lib - (installedExtension majorVersion) - (self.legacyPackages.${pkgs.system}."psql_${majorVersion}".exts.postgis) - ] - ++ lib.optional (postgresql.isOrioleDB) ( - self.legacyPackages.${pkgs.system}."psql_orioledb-17".exts.orioledb - ); + paths = [ + postgresql + postgresql.lib + (installedExtension majorVersion) + (self.legacyPackages.${pkgs.system}."psql_${majorVersion}".exts.postgis) + ] + ++ lib.optional (postgresql.isOrioleDB) ( + self.legacyPackages.${pkgs.system}."psql_orioledb-17".exts.orioledb + ); passthru = { inherit (postgresql) version psqlSchema; lib = pkg; diff --git a/nix/ext/tests/pgtap.nix b/nix/ext/tests/pgtap.nix new file mode 100644 index 0000000000..714c8296e7 --- /dev/null +++ b/nix/ext/tests/pgtap.nix @@ -0,0 +1,154 @@ +{ self, pkgs }: +let + pname = "pgtap"; + inherit (pkgs) lib; + installedExtension = + postgresMajorVersion: self.packages.${pkgs.system}."psql_${postgresMajorVersion}/exts/${pname}-all"; + versions = postgresqlMajorVersion: (installedExtension postgresqlMajorVersion).versions; + postgresqlWithExtension = + postgresql: + let + majorVersion = lib.versions.major postgresql.version; + pkg = pkgs.buildEnv { + name = "postgresql-${majorVersion}-${pname}"; + paths = [ + postgresql + postgresql.lib + (installedExtension majorVersion) + ]; + passthru = { + inherit (postgresql) version psqlSchema; + lib = pkg; + withPackages = _: pkg; + }; + nativeBuildInputs = [ pkgs.makeWrapper ]; + pathsToLink = [ + "/" + "/bin" + "/lib" + ]; + postBuild = '' + wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib + wrapProgram $out/bin/pg_ctl --set NIX_PGLIBDIR $out/lib + wrapProgram $out/bin/pg_upgrade --set NIX_PGLIBDIR $out/lib + ''; + }; + in + pkg; +in +self.inputs.nixpkgs.lib.nixos.runTest { + name = pname; + hostPkgs = pkgs; + nodes.server = + { config, ... }: + { + virtualisation = { + forwardPorts = [ + { + from = "host"; + host.port = 13022; + guest.port = 22; + } + ]; + }; + services.openssh = { + enable = true; + }; + + services.postgresql = { + enable = true; + package = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15; + }; + + specialisation.postgresql17.configuration = { + services.postgresql = { + package = lib.mkForce (postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17); + }; + + systemd.services.postgresql-migrate = { + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + User = "postgres"; + Group = "postgres"; + StateDirectory = "postgresql"; + WorkingDirectory = "${builtins.dirOf config.services.postgresql.dataDir}"; + }; + script = + let + oldPostgresql = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15; + newPostgresql = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17; + oldDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${oldPostgresql.psqlSchema}"; + newDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${newPostgresql.psqlSchema}"; + in + '' + if [[ ! -d ${newDataDir} ]]; then + install -d -m 0700 -o postgres -g postgres "${newDataDir}" + ${newPostgresql}/bin/initdb -D "${newDataDir}" + ${newPostgresql}/bin/pg_upgrade --old-datadir "${oldDataDir}" --new-datadir "${newDataDir}" \ + --old-bindir "${oldPostgresql}/bin" --new-bindir "${newPostgresql}/bin" + else + echo "${newDataDir} already exists" + fi + ''; + }; + + systemd.services.postgresql = { + after = [ "postgresql-migrate.service" ]; + requires = [ "postgresql-migrate.service" ]; + }; + }; + }; + testScript = + { nodes, ... }: + let + pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17"; + in + '' + versions = { + "15": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "15"))}], + "17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}], + } + + def run_sql(query): + return server.succeed(f"""sudo -u postgres psql -t -A -F\",\" -c \"{query}\" """).strip() + + def check_upgrade_path(pg_version): + with subtest("Check ${pname} upgrade path"): + firstVersion = versions[pg_version][0] + server.succeed("sudo -u postgres psql -c 'DROP EXTENSION IF EXISTS ${pname};'") + run_sql(f"""CREATE EXTENSION ${pname} WITH VERSION '{firstVersion}' CASCADE;""") + installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = '${pname}';""") + assert installed_version == firstVersion, f"Expected ${pname} version {firstVersion}, but found {installed_version}" + for version in versions[pg_version][1:]: + run_sql(f"""ALTER EXTENSION ${pname} UPDATE TO '{version}';""") + installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = '${pname}';""") + assert installed_version == version, f"Expected ${pname} version {version}, but found {installed_version}" + + start_all() + + server.wait_for_unit("multi-user.target") + server.wait_for_unit("postgresql.service") + + check_upgrade_path("15") + + with subtest("Check ${pname} latest extension version"): + server.succeed("sudo -u postgres psql -c 'DROP EXTENSION ${pname};'") + server.succeed("sudo -u postgres psql -c 'CREATE EXTENSION ${pname} CASCADE;'") + installed_extensions=run_sql(r"""SELECT extname, extversion FROM pg_extension;""") + latestVersion = versions["15"][-1] + assert f"${pname},{latestVersion}" in installed_extensions + + with subtest("switch to postgresql 17"): + server.succeed( + "${pg17-configuration}/bin/switch-to-configuration test >&2" + ) + + with subtest("Check ${pname} latest extension version after upgrade"): + installed_extensions=run_sql(r"""SELECT extname, extversion FROM pg_extension;""") + latestVersion = versions["17"][-1] + assert f"${pname},{latestVersion}" in installed_extensions + + check_upgrade_path("17") + ''; +} diff --git a/nix/ext/timescaledb.nix b/nix/ext/timescaledb.nix index 91605a48c4..8c42aaaeff 100644 --- a/nix/ext/timescaledb.nix +++ b/nix/ext/timescaledb.nix @@ -39,7 +39,8 @@ let "-DREGRESS_CHECKS=OFF" "-DTAP_CHECKS=OFF" "-DAPACHE_ONLY=1" - ] ++ lib.optionals stdenv.isDarwin [ "-DLINTER=OFF" ]; + ] + ++ lib.optionals stdenv.isDarwin [ "-DLINTER=OFF" ]; postPatch = '' for x in CMakeLists.txt sql/CMakeLists.txt; do diff --git a/nix/ext/vault.nix b/nix/ext/vault.nix index cb90882a7b..537febc0b6 100644 --- a/nix/ext/vault.nix +++ b/nix/ext/vault.nix @@ -44,31 +44,30 @@ let inherit hash; }; - installPhase = - '' - mkdir -p $out/{lib,share/postgresql/extension} + installPhase = '' + mkdir -p $out/{lib,share/postgresql/extension} - # Create version-specific control file - sed -e "/^default_version =/d" \ - -e "s|^module_pathname = .*|module_pathname = '\$libdir/${pname}'|" \ - ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control + # Create version-specific control file + sed -e "/^default_version =/d" \ + -e "s|^module_pathname = .*|module_pathname = '\$libdir/${pname}'|" \ + ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control - '' - # for versions <= 0.2.8, we don't have a library to install - + lib.optionalString (builtins.compareVersions "0.2.8" version < 0) '' - # Install shared library with version suffix - mv ${pname}${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix} + '' + # for versions <= 0.2.8, we don't have a library to install + + lib.optionalString (builtins.compareVersions "0.2.8" version < 0) '' + # Install shared library with version suffix + mv ${pname}${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix} - # For the latest version, copy the sql files - if [[ "${version}" == "${latestVersion}" ]]; then - install -D -t $out/share/postgresql/extension sql/*.sql - { - echo "default_version = '${latestVersion}'" - cat $out/share/postgresql/extension/${pname}--${latestVersion}.control - } > $out/share/postgresql/extension/${pname}.control - fi - ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} - ''; + # For the latest version, copy the sql files + if [[ "${version}" == "${latestVersion}" ]]; then + install -D -t $out/share/postgresql/extension sql/*.sql + { + echo "default_version = '${latestVersion}'" + cat $out/share/postgresql/extension/${pname}--${latestVersion}.control + } > $out/share/postgresql/extension/${pname}.control + fi + ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} + ''; meta = with lib; { description = "Store encrypted secrets in PostgreSQL"; diff --git a/nix/ext/versions.json b/nix/ext/versions.json index b35c6c40b9..0fca984cd0 100644 --- a/nix/ext/versions.json +++ b/nix/ext/versions.json @@ -786,6 +786,28 @@ "hash": "sha256-STJVvvrLVLe1JevNu6u6EftzAWv+X+J8lu66su7Or2s=" } }, + "pgtap": { + "1.2.0": { + "postgresql": [ + "15" + ], + "hash": "sha256-lb0PRffwo6J5a6Hqw1ggvn0cW7gPZ02OEcLPi9ineI8=" + }, + "1.3.1": { + "postgresql": [ + "15", + "17" + ], + "hash": "sha256-HOgCb1CCfsfbMbMMWuzFJ4B8CfVm9b0sI2zBY3/kqyI=" + }, + "1.3.3": { + "postgresql": [ + "15", + "17" + ], + "hash": "sha256-YgvfLGF7pLVcCKD66NnWAydDxtoYHH1DpLiYTEKHJ0E=" + } + }, "pg_tle": { "1.0.1": { "postgresql": [ diff --git a/nix/ext/wal2json.nix b/nix/ext/wal2json.nix index bd1e8ddd8e..43ddab8dfd 100644 --- a/nix/ext/wal2json.nix +++ b/nix/ext/wal2json.nix @@ -10,7 +10,7 @@ let pname = "wal2json"; build = - version: rev: hash: + version: _rev: hash: stdenv.mkDerivation rec { inherit version pname; diff --git a/nix/ext/wrappers/default.nix b/nix/ext/wrappers/default.nix index c9f22dc4a1..a032eb9b69 100644 --- a/nix/ext/wrappers/default.nix +++ b/nix/ext/wrappers/default.nix @@ -37,17 +37,16 @@ let cargo git ]; - buildInputs = - [ - openssl - postgresql - ] - ++ lib.optionals stdenv.isDarwin [ - darwin.apple_sdk.frameworks.CoreFoundation - darwin.apple_sdk.frameworks.CoreServices - darwin.apple_sdk.frameworks.Security - darwin.apple_sdk.frameworks.SystemConfiguration - ]; + buildInputs = [ + openssl + postgresql + ] + ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.CoreFoundation + darwin.apple_sdk.frameworks.CoreServices + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.SystemConfiguration + ]; NIX_LDFLAGS = "-L${postgresql}/lib -lpq"; diff --git a/nix/packages/groonga/default.nix b/nix/packages/groonga/default.nix index bef4911095..c6d734db6c 100644 --- a/nix/packages/groonga/default.nix +++ b/nix/packages/groonga/default.nix @@ -36,21 +36,20 @@ stdenv.mkDerivation (finalAttrs: { pkg-config makeWrapper ]; - buildInputs = - [ - rapidjson - xxHash - zstd - mecab - kytea - msgpack-c - ] - ++ lib.optionals lz4Support [ lz4 ] - ++ lib.optional zlibSupport [ zlib ] - ++ lib.optionals suggestSupport [ - zeromq - libevent - ]; + buildInputs = [ + rapidjson + xxHash + zstd + mecab + kytea + msgpack-c + ] + ++ lib.optionals lz4Support [ lz4 ] + ++ lib.optional zlibSupport [ zlib ] + ++ lib.optionals suggestSupport [ + zeromq + libevent + ]; cmakeFlags = [ "-DWITH_MECAB=ON" "-DMECAB_DICDIR=${mecab-naist-jdic}/lib/mecab/dic/naist-jdic" diff --git a/nix/packages/lib.nix b/nix/packages/lib.nix index cf541913da..ef8f640697 100644 --- a/nix/packages/lib.nix +++ b/nix/packages/lib.nix @@ -100,7 +100,8 @@ PGBOUNCER_AUTH_SCHEMA_SQL = "${paths.pgbouncerAuthSchemaSql}"; STAT_EXTENSION_SQL = "${paths.statExtensionSql}"; CURRENT_SYSTEM = "${system}"; - } // extraSubstitutions; # Merge in any extra substitutions + } + // extraSubstitutions; # Merge in any extra substitutions in pkgs.runCommand name { @@ -129,13 +130,11 @@ chmod 644 $out/etc/postgresql/pg_hba.conf substitute ${../tools/run-server.sh.in} $out/bin/start-postgres-server \ - ${ - builtins.concatStringsSep " " ( - builtins.attrValues ( - builtins.mapAttrs (name: value: "--subst-var-by '${name}' '${value}'") substitutions - ) + ${builtins.concatStringsSep " " ( + builtins.attrValues ( + builtins.mapAttrs (name: value: "--subst-var-by '${name}' '${value}'") substitutions ) - } + )} chmod +x $out/bin/start-postgres-server ''; } diff --git a/nix/postgresql/generic.nix b/nix/postgresql/generic.nix index ea67cbc915..1be57113f3 100644 --- a/nix/postgresql/generic.nix +++ b/nix/postgresql/generic.nix @@ -113,43 +113,41 @@ let ]; setOutputFlags = false; # $out retains configureFlags :-/ - buildInputs = - [ - zlib - readline - openssl - (libxml2.override { python = python3; }) - icu - ] - ++ lib.optionals (olderThan "13") [ libxcrypt ] - ++ lib.optionals jitSupport [ llvmPackages.llvm ] - ++ lib.optionals lz4Enabled [ lz4 ] - ++ lib.optionals zstdEnabled [ zstd ] - ++ lib.optionals systemdSupport' [ systemd ] - ++ lib.optionals pythonSupport [ python3 ] - ++ lib.optionals gssSupport [ libkrb5 ] - ++ lib.optionals stdenv'.isLinux [ linux-pam ] - ++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ] - ++ lib.optionals (isOrioleDB || (lib.versionAtLeast version "17")) [ - perl - bison - flex - docbook_xsl - docbook_xml_dtd_45 - docbook_xsl_ns - libxslt - ]; + buildInputs = [ + zlib + readline + openssl + (libxml2.override { python = python3; }) + icu + ] + ++ lib.optionals (olderThan "13") [ libxcrypt ] + ++ lib.optionals jitSupport [ llvmPackages.llvm ] + ++ lib.optionals lz4Enabled [ lz4 ] + ++ lib.optionals zstdEnabled [ zstd ] + ++ lib.optionals systemdSupport' [ systemd ] + ++ lib.optionals pythonSupport [ python3 ] + ++ lib.optionals gssSupport [ libkrb5 ] + ++ lib.optionals stdenv'.isLinux [ linux-pam ] + ++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ] + ++ lib.optionals (isOrioleDB || (lib.versionAtLeast version "17")) [ + perl + bison + flex + docbook_xsl + docbook_xml_dtd_45 + docbook_xsl_ns + libxslt + ]; - nativeBuildInputs = - [ - makeWrapper - pkg-config - ] - ++ lib.optionals jitSupport [ - llvmPackages.llvm.dev - nukeReferences - patchelf - ]; + nativeBuildInputs = [ + makeWrapper + pkg-config + ] + ++ lib.optionals jitSupport [ + llvmPackages.llvm.dev + nukeReferences + patchelf + ]; enableParallelBuilding = true; @@ -161,113 +159,109 @@ let # Fixed upstream in https://github.com/postgres/postgres/commit/0bc8cebdb889368abdf224aeac8bc197fe4c9ae6 env.NIX_CFLAGS_COMPILE = lib.optionalString (olderThan "13") "-I${libxml2.dev}/include/libxml2"; - configureFlags = - [ - "--with-openssl" - "--with-libxml" - "--with-icu" - "--sysconfdir=/etc" - "--libdir=$(lib)/lib" - "--with-system-tzdata=${tzdata}/share/zoneinfo" - "--enable-debug" - (lib.optionalString systemdSupport' "--with-systemd") - (if stdenv'.isDarwin then "--with-uuid=e2fs" else "--with-ossp-uuid") - ] - ++ lib.optionals lz4Enabled [ "--with-lz4" ] - ++ lib.optionals zstdEnabled [ "--with-zstd" ] - ++ lib.optionals gssSupport [ "--with-gssapi" ] - ++ lib.optionals pythonSupport [ "--with-python" ] - ++ lib.optionals jitSupport [ "--with-llvm" ] - ++ lib.optionals stdenv'.isLinux [ "--with-pam" ]; - - patches = - [ - ( - if atLeast "16" then - ./patches/relative-to-symlinks-16+.patch - else - ./patches/relative-to-symlinks.patch - ) - ./patches/less-is-more.patch - ./patches/paths-for-split-outputs.patch - ./patches/specify_pkglibdir_at_runtime.patch - ./patches/paths-with-postgresql-suffix.patch - ./patches/locale-binary-path.patch - ] - ++ lib.optionals stdenv'.hostPlatform.isMusl ( - # Using fetchurl instead of fetchpatch on purpose: https://github.com/NixOS/nixpkgs/issues/240141 - map fetchurl (lib.attrValues muslPatches) + configureFlags = [ + "--with-openssl" + "--with-libxml" + "--with-icu" + "--sysconfdir=/etc" + "--libdir=$(lib)/lib" + "--with-system-tzdata=${tzdata}/share/zoneinfo" + "--enable-debug" + (lib.optionalString systemdSupport' "--with-systemd") + (if stdenv'.isDarwin then "--with-uuid=e2fs" else "--with-ossp-uuid") + ] + ++ lib.optionals lz4Enabled [ "--with-lz4" ] + ++ lib.optionals zstdEnabled [ "--with-zstd" ] + ++ lib.optionals gssSupport [ "--with-gssapi" ] + ++ lib.optionals pythonSupport [ "--with-python" ] + ++ lib.optionals jitSupport [ "--with-llvm" ] + ++ lib.optionals stdenv'.isLinux [ "--with-pam" ]; + + patches = [ + ( + if atLeast "16" then + ./patches/relative-to-symlinks-16+.patch + else + ./patches/relative-to-symlinks.patch ) - ++ lib.optionals stdenv'.isLinux [ - (if atLeast "13" then ./patches/socketdir-in-run-13+.patch else ./patches/socketdir-in-run.patch) - ]; + ./patches/less-is-more.patch + ./patches/paths-for-split-outputs.patch + ./patches/specify_pkglibdir_at_runtime.patch + ./patches/paths-with-postgresql-suffix.patch + ./patches/locale-binary-path.patch + ] + ++ lib.optionals stdenv'.hostPlatform.isMusl ( + # Using fetchurl instead of fetchpatch on purpose: https://github.com/NixOS/nixpkgs/issues/240141 + map fetchurl (lib.attrValues muslPatches) + ) + ++ lib.optionals stdenv'.isLinux [ + (if atLeast "13" then ./patches/socketdir-in-run-13+.patch else ./patches/socketdir-in-run.patch) + ]; installTargets = [ "install-world-bin" ]; - postPatch = - '' - # Hardcode the path to pgxs so pg_config returns the path in $out - substituteInPlace "src/common/config_info.c" --subst-var out - substituteInPlace "src/backend/commands/collationcmds.c" --replace-fail '@locale@' '${ - if stdenv.isDarwin then darwin.adv_cmds else lib.getBin stdenv.cc.libc - }/bin/locale' - '' - + lib.optionalString jitSupport '' - # Force lookup of jit stuff in $out instead of $lib - substituteInPlace src/backend/jit/jit.c --replace pkglib_path \"$out/lib\" - substituteInPlace src/backend/jit/llvm/llvmjit.c --replace pkglib_path \"$out/lib\" - substituteInPlace src/backend/jit/llvm/llvmjit_inline.cpp --replace pkglib_path \"$out/lib\" - ''; - - postInstall = - '' - moveToOutput "lib/pgxs" "$out" # looks strange, but not deleting it - moveToOutput "lib/libpgcommon*.a" "$out" - moveToOutput "lib/libpgport*.a" "$out" - moveToOutput "lib/libecpg*" "$out" - - # Prevent a retained dependency on gcc-wrapper. - substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/ld ld - - if [ -z "''${dontDisableStatic:-}" ]; then - # Remove static libraries in case dynamic are available. - for i in $out/lib/*.a $lib/lib/*.a; do - name="$(basename "$i")" - ext="${stdenv'.hostPlatform.extensions.sharedLibrary}" - if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then - rm "$i" - fi - done - fi - '' - + lib.optionalString jitSupport '' - # Move the bitcode and libllvmjit.so library out of $lib; otherwise, every client that - # depends on libpq.so will also have libLLVM.so in its closure too, bloating it - moveToOutput "lib/bitcode" "$out" - moveToOutput "lib/llvmjit*" "$out" - - # In the case of JIT support, prevent a retained dependency on clang-wrapper - substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/clang clang - nuke-refs $out/lib/llvmjit_types.bc $(find $out/lib/bitcode -type f) - - # Stop out depending on the default output of llvm - substituteInPlace $out/lib/pgxs/src/Makefile.global \ - --replace ${llvmPackages.llvm.out}/bin "" \ - --replace '$(LLVM_BINPATH)/' "" - - # Stop out depending on the -dev output of llvm - substituteInPlace $out/lib/pgxs/src/Makefile.global \ - --replace ${llvmPackages.llvm.dev}/bin/llvm-config llvm-config \ - --replace -I${llvmPackages.llvm.dev}/include "" - - ${lib.optionalString (!stdenv'.isDarwin) '' - # Stop lib depending on the -dev output of llvm - rpath=$(patchelf --print-rpath $out/lib/llvmjit.so) - nuke-refs -e $out $out/lib/llvmjit.so - # Restore the correct rpath - patchelf $out/lib/llvmjit.so --set-rpath "$rpath" - ''} - ''; + postPatch = '' + # Hardcode the path to pgxs so pg_config returns the path in $out + substituteInPlace "src/common/config_info.c" --subst-var out + substituteInPlace "src/backend/commands/collationcmds.c" --replace-fail '@locale@' '${ + if stdenv.isDarwin then darwin.adv_cmds else lib.getBin stdenv.cc.libc + }/bin/locale' + '' + + lib.optionalString jitSupport '' + # Force lookup of jit stuff in $out instead of $lib + substituteInPlace src/backend/jit/jit.c --replace pkglib_path \"$out/lib\" + substituteInPlace src/backend/jit/llvm/llvmjit.c --replace pkglib_path \"$out/lib\" + substituteInPlace src/backend/jit/llvm/llvmjit_inline.cpp --replace pkglib_path \"$out/lib\" + ''; + + postInstall = '' + moveToOutput "lib/pgxs" "$out" # looks strange, but not deleting it + moveToOutput "lib/libpgcommon*.a" "$out" + moveToOutput "lib/libpgport*.a" "$out" + moveToOutput "lib/libecpg*" "$out" + + # Prevent a retained dependency on gcc-wrapper. + substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/ld ld + + if [ -z "''${dontDisableStatic:-}" ]; then + # Remove static libraries in case dynamic are available. + for i in $out/lib/*.a $lib/lib/*.a; do + name="$(basename "$i")" + ext="${stdenv'.hostPlatform.extensions.sharedLibrary}" + if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then + rm "$i" + fi + done + fi + '' + + lib.optionalString jitSupport '' + # Move the bitcode and libllvmjit.so library out of $lib; otherwise, every client that + # depends on libpq.so will also have libLLVM.so in its closure too, bloating it + moveToOutput "lib/bitcode" "$out" + moveToOutput "lib/llvmjit*" "$out" + + # In the case of JIT support, prevent a retained dependency on clang-wrapper + substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/clang clang + nuke-refs $out/lib/llvmjit_types.bc $(find $out/lib/bitcode -type f) + + # Stop out depending on the default output of llvm + substituteInPlace $out/lib/pgxs/src/Makefile.global \ + --replace ${llvmPackages.llvm.out}/bin "" \ + --replace '$(LLVM_BINPATH)/' "" + + # Stop out depending on the -dev output of llvm + substituteInPlace $out/lib/pgxs/src/Makefile.global \ + --replace ${llvmPackages.llvm.dev}/bin/llvm-config llvm-config \ + --replace -I${llvmPackages.llvm.dev}/include "" + + ${lib.optionalString (!stdenv'.isDarwin) '' + # Stop lib depending on the -dev output of llvm + rpath=$(patchelf --print-rpath $out/lib/llvmjit.so) + nuke-refs -e $out $out/lib/llvmjit.so + # Restore the correct rpath + patchelf $out/lib/llvmjit.so --set-rpath "$rpath" + ''} + ''; postFixup = lib.optionalString (!stdenv'.isDarwin && stdenv'.hostPlatform.libc == "glibc") '' # initdb needs access to "locale" command from glibc. @@ -321,22 +315,21 @@ let postgresql = this; } this.pkgs; - tests = - { - postgresql-wal-receiver = import ../../../../nixos/tests/postgresql-wal-receiver.nix { - inherit (stdenv) system; - pkgs = self; - package = this; - }; - pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; - } - // lib.optionalAttrs jitSupport { - postgresql-jit = import ../../../../nixos/tests/postgresql-jit.nix { - inherit (stdenv) system; - pkgs = self; - package = this; - }; + tests = { + postgresql-wal-receiver = import ../../../../nixos/tests/postgresql-wal-receiver.nix { + inherit (stdenv) system; + pkgs = self; + package = this; }; + pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; + } + // lib.optionalAttrs jitSupport { + postgresql-jit = import ../../../../nixos/tests/postgresql-jit.nix { + inherit (stdenv) system; + pkgs = self; + package = this; + }; + }; }; meta = with lib; { diff --git a/nix/tests/expected/z_15_ext_interface.out b/nix/tests/expected/z_15_ext_interface.out index c68d842109..b456af76cc 100644 --- a/nix/tests/expected/z_15_ext_interface.out +++ b/nix/tests/expected/z_15_ext_interface.out @@ -2231,7 +2231,6 @@ order by pgtap | public | _pg_sv_type_array | oid[] | name[] pgtap | public | _prokind | p_oid oid | "char" pgtap | public | _query | text | text - pgtap | public | _quote_ident_like | text, text | text pgtap | public | _refine_vol | text | text pgtap | public | _relcomp | text, text, text, text, text | text pgtap | public | _relcomp | text, text, text, text | text @@ -2244,6 +2243,7 @@ order by pgtap | public | _returns | name, name[] | text pgtap | public | _returns | name | text pgtap | public | _returns | name, name | text + pgtap | public | _retval | text | text pgtap | public | _rexists | character[], name, name | boolean pgtap | public | _rexists | character, name | boolean pgtap | public | _rexists | character[], name | boolean @@ -2272,6 +2272,7 @@ order by pgtap | public | _type_func | "char", name, name, name[] | boolean pgtap | public | _type_func | "char", name, name[] | boolean pgtap | public | _type_func | "char", name, name | boolean + pgtap | public | _typename | name | text pgtap | public | _types_are | name, name[], text, character[] | text pgtap | public | _types_are | name[], text, character[] | text pgtap | public | _unalike | boolean, anyelement, text, text | text @@ -2341,10 +2342,12 @@ order by pgtap | public | col_is_null | schema_name name, table_name name, column_name name, description text | text pgtap | public | col_is_pk | name, name, name, text | text pgtap | public | col_is_pk | name, name[], text | text + pgtap | public | col_is_pk | name, name, name[] | text pgtap | public | col_is_pk | name, name[] | text pgtap | public | col_is_pk | name, name, text | text pgtap | public | col_is_pk | name, name, name[], text | text pgtap | public | col_is_pk | name, name | text + pgtap | public | col_is_pk | name, name, name | text pgtap | public | col_is_unique | name, name, name, text | text pgtap | public | col_is_unique | name, name[], text | text pgtap | public | col_is_unique | name, name, name[] | text @@ -2458,6 +2461,7 @@ order by pgtap | public | foreign_tables_are | name[], text | text pgtap | public | foreign_tables_are | name, name[], text | text pgtap | public | foreign_tables_are | name, name[] | text + pgtap | public | format_type_string | text | text pgtap | public | function_lang_is | name, name, name, text | text pgtap | public | function_lang_is | name, name, text | text pgtap | public | function_lang_is | name, name[], name, text | text @@ -2570,6 +2574,7 @@ order by pgtap | public | has_pk | name, name, text | text pgtap | public | has_pk | name, text | text pgtap | public | has_pk | name | text + pgtap | public | has_pk | name, name | text pgtap | public | has_relation | name, name, text | text pgtap | public | has_relation | name, text | text pgtap | public | has_relation | name | text @@ -5293,7 +5298,7 @@ order by xml2 | public | xpath_table | text, text, text, text, text | SETOF record xml2 | public | xslt_process | text, text | text xml2 | public | xslt_process | text, text, text | text -(5121 rows) +(5126 rows) /* diff --git a/nix/tests/expected/z_17_ext_interface.out b/nix/tests/expected/z_17_ext_interface.out index 1b09ed17e5..40eb5a7298 100644 --- a/nix/tests/expected/z_17_ext_interface.out +++ b/nix/tests/expected/z_17_ext_interface.out @@ -2216,7 +2216,6 @@ order by pgtap | public | _pg_sv_type_array | oid[] | name[] pgtap | public | _prokind | p_oid oid | "char" pgtap | public | _query | text | text - pgtap | public | _quote_ident_like | text, text | text pgtap | public | _refine_vol | text | text pgtap | public | _relcomp | text, text, text, text, text | text pgtap | public | _relcomp | text, text, text, text | text @@ -2229,6 +2228,7 @@ order by pgtap | public | _returns | name, name[] | text pgtap | public | _returns | name | text pgtap | public | _returns | name, name | text + pgtap | public | _retval | text | text pgtap | public | _rexists | character[], name, name | boolean pgtap | public | _rexists | character, name | boolean pgtap | public | _rexists | character[], name | boolean @@ -2257,6 +2257,7 @@ order by pgtap | public | _type_func | "char", name, name, name[] | boolean pgtap | public | _type_func | "char", name, name[] | boolean pgtap | public | _type_func | "char", name, name | boolean + pgtap | public | _typename | name | text pgtap | public | _types_are | name, name[], text, character[] | text pgtap | public | _types_are | name[], text, character[] | text pgtap | public | _unalike | boolean, anyelement, text, text | text @@ -2326,10 +2327,12 @@ order by pgtap | public | col_is_null | schema_name name, table_name name, column_name name, description text | text pgtap | public | col_is_pk | name, name, name, text | text pgtap | public | col_is_pk | name, name[], text | text + pgtap | public | col_is_pk | name, name, name[] | text pgtap | public | col_is_pk | name, name[] | text pgtap | public | col_is_pk | name, name, text | text pgtap | public | col_is_pk | name, name, name[], text | text pgtap | public | col_is_pk | name, name | text + pgtap | public | col_is_pk | name, name, name | text pgtap | public | col_is_unique | name, name, name, text | text pgtap | public | col_is_unique | name, name[], text | text pgtap | public | col_is_unique | name, name, name[] | text @@ -2443,6 +2446,7 @@ order by pgtap | public | foreign_tables_are | name[], text | text pgtap | public | foreign_tables_are | name, name[], text | text pgtap | public | foreign_tables_are | name, name[] | text + pgtap | public | format_type_string | text | text pgtap | public | function_lang_is | name, name, name, text | text pgtap | public | function_lang_is | name, name, text | text pgtap | public | function_lang_is | name, name[], name, text | text @@ -2555,6 +2559,7 @@ order by pgtap | public | has_pk | name, name, text | text pgtap | public | has_pk | name, text | text pgtap | public | has_pk | name | text + pgtap | public | has_pk | name, name | text pgtap | public | has_relation | name, name, text | text pgtap | public | has_relation | name, text | text pgtap | public | has_relation | name | text @@ -4937,7 +4942,7 @@ order by xml2 | public | xpath_table | text, text, text, text, text | SETOF record xml2 | public | xslt_process | text, text | text xml2 | public | xslt_process | text, text, text | text -(4778 rows) +(4783 rows) /* diff --git a/nix/tests/expected/z_orioledb-17_ext_interface.out b/nix/tests/expected/z_orioledb-17_ext_interface.out index 1b09ed17e5..40eb5a7298 100644 --- a/nix/tests/expected/z_orioledb-17_ext_interface.out +++ b/nix/tests/expected/z_orioledb-17_ext_interface.out @@ -2216,7 +2216,6 @@ order by pgtap | public | _pg_sv_type_array | oid[] | name[] pgtap | public | _prokind | p_oid oid | "char" pgtap | public | _query | text | text - pgtap | public | _quote_ident_like | text, text | text pgtap | public | _refine_vol | text | text pgtap | public | _relcomp | text, text, text, text, text | text pgtap | public | _relcomp | text, text, text, text | text @@ -2229,6 +2228,7 @@ order by pgtap | public | _returns | name, name[] | text pgtap | public | _returns | name | text pgtap | public | _returns | name, name | text + pgtap | public | _retval | text | text pgtap | public | _rexists | character[], name, name | boolean pgtap | public | _rexists | character, name | boolean pgtap | public | _rexists | character[], name | boolean @@ -2257,6 +2257,7 @@ order by pgtap | public | _type_func | "char", name, name, name[] | boolean pgtap | public | _type_func | "char", name, name[] | boolean pgtap | public | _type_func | "char", name, name | boolean + pgtap | public | _typename | name | text pgtap | public | _types_are | name, name[], text, character[] | text pgtap | public | _types_are | name[], text, character[] | text pgtap | public | _unalike | boolean, anyelement, text, text | text @@ -2326,10 +2327,12 @@ order by pgtap | public | col_is_null | schema_name name, table_name name, column_name name, description text | text pgtap | public | col_is_pk | name, name, name, text | text pgtap | public | col_is_pk | name, name[], text | text + pgtap | public | col_is_pk | name, name, name[] | text pgtap | public | col_is_pk | name, name[] | text pgtap | public | col_is_pk | name, name, text | text pgtap | public | col_is_pk | name, name, name[], text | text pgtap | public | col_is_pk | name, name | text + pgtap | public | col_is_pk | name, name, name | text pgtap | public | col_is_unique | name, name, name, text | text pgtap | public | col_is_unique | name, name[], text | text pgtap | public | col_is_unique | name, name, name[] | text @@ -2443,6 +2446,7 @@ order by pgtap | public | foreign_tables_are | name[], text | text pgtap | public | foreign_tables_are | name, name[], text | text pgtap | public | foreign_tables_are | name, name[] | text + pgtap | public | format_type_string | text | text pgtap | public | function_lang_is | name, name, name, text | text pgtap | public | function_lang_is | name, name, text | text pgtap | public | function_lang_is | name, name[], name, text | text @@ -2555,6 +2559,7 @@ order by pgtap | public | has_pk | name, name, text | text pgtap | public | has_pk | name, text | text pgtap | public | has_pk | name | text + pgtap | public | has_pk | name, name | text pgtap | public | has_relation | name, name, text | text pgtap | public | has_relation | name, text | text pgtap | public | has_relation | name | text @@ -4937,7 +4942,7 @@ order by xml2 | public | xpath_table | text, text, text, text, text | SETOF record xml2 | public | xslt_process | text, text | text xml2 | public | xslt_process | text, text, text | text -(4778 rows) +(4783 rows) /* diff --git a/testinfra/test_ami_nix.py b/testinfra/test_ami_nix.py index 1b00f2c84a..a5cadcad9c 100644 --- a/testinfra/test_ami_nix.py +++ b/testinfra/test_ami_nix.py @@ -421,9 +421,9 @@ def is_healthy(ssh) -> bool: def test_postgrest_is_running(host): """Check if postgrest service is running using our SSH connection.""" result = run_ssh_command(host["ssh"], "systemctl is-active postgrest") - assert ( - result["succeeded"] and result["stdout"].strip() == "active" - ), "PostgREST service is not running" + assert result["succeeded"] and result["stdout"].strip() == "active", ( + "PostgREST service is not running" + ) def test_postgrest_responds_to_requests(host): @@ -546,9 +546,9 @@ def test_postgresql_version(host): if version_match: major_version = int(version_match.group(1)) print(f"PostgreSQL major version: {major_version}") - assert ( - major_version >= 14 - ), f"PostgreSQL version {major_version} is less than 14" + assert major_version >= 14, ( + f"PostgreSQL version {major_version} is less than 14" + ) else: assert False, "Could not parse PostgreSQL version number" else: @@ -578,9 +578,9 @@ def test_libpq5_version(host): if version_match: major_version = int(version_match.group(1)) print(f"libpq5 major version: {major_version}") - assert ( - major_version >= 14 - ), f"libpq5 version {major_version} is less than 14" + assert major_version >= 14, ( + f"libpq5 version {major_version} is less than 14" + ) else: print("Could not parse libpq5 version from dpkg output") else: @@ -613,9 +613,9 @@ def test_libpq5_version(host): if version_match: major_version = int(version_match.group(1)) print(f"psql/libpq major version: {major_version}") - assert ( - major_version >= 14 - ), f"psql/libpq version {major_version} is less than 14" + assert major_version >= 14, ( + f"psql/libpq version {major_version} is less than 14" + ) else: print("Could not parse psql version") @@ -776,7 +776,9 @@ def test_postgrest_read_only_session_attrs(host): print( f"\nFound 'session is not read-only' errors in PostgREST logs:\n{result['stdout']}" ) - assert False, "PostgREST logs contain 'session is not read-only' errors even though PostgreSQL is configured for read-only mode" + assert False, ( + "PostgREST logs contain 'session is not read-only' errors even though PostgreSQL is configured for read-only mode" + ) else: print("\nNo 'session is not read-only' errors found in PostgREST logs") From f746eec70684f799bb626edc1cf494cea7404e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Roche?= Date: Mon, 27 Oct 2025 10:30:33 +0100 Subject: [PATCH 2/6] feat: use default nixos extension test And run pg_regress tests for pgtap as part of the unified extension tests --- nix/ext/tests/default.nix | 3 +- nix/ext/tests/pgtap.nix | 154 -------------------------------------- 2 files changed, 2 insertions(+), 155 deletions(-) delete mode 100644 nix/ext/tests/pgtap.nix diff --git a/nix/ext/tests/default.nix b/nix/ext/tests/default.nix index 57644ee7fc..7433c38d4f 100644 --- a/nix/ext/tests/default.nix +++ b/nix/ext/tests/default.nix @@ -227,10 +227,11 @@ builtins.listToAttrs ( "pg_hashids" "pg_jsonschema" "pg_net" + "pg_partman" "pg_stat_monitor" "pg_tle" "pgaudit" - "pg_partman" + "pgtap" "vector" "wal2json" "wrappers" diff --git a/nix/ext/tests/pgtap.nix b/nix/ext/tests/pgtap.nix deleted file mode 100644 index 714c8296e7..0000000000 --- a/nix/ext/tests/pgtap.nix +++ /dev/null @@ -1,154 +0,0 @@ -{ self, pkgs }: -let - pname = "pgtap"; - inherit (pkgs) lib; - installedExtension = - postgresMajorVersion: self.packages.${pkgs.system}."psql_${postgresMajorVersion}/exts/${pname}-all"; - versions = postgresqlMajorVersion: (installedExtension postgresqlMajorVersion).versions; - postgresqlWithExtension = - postgresql: - let - majorVersion = lib.versions.major postgresql.version; - pkg = pkgs.buildEnv { - name = "postgresql-${majorVersion}-${pname}"; - paths = [ - postgresql - postgresql.lib - (installedExtension majorVersion) - ]; - passthru = { - inherit (postgresql) version psqlSchema; - lib = pkg; - withPackages = _: pkg; - }; - nativeBuildInputs = [ pkgs.makeWrapper ]; - pathsToLink = [ - "/" - "/bin" - "/lib" - ]; - postBuild = '' - wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib - wrapProgram $out/bin/pg_ctl --set NIX_PGLIBDIR $out/lib - wrapProgram $out/bin/pg_upgrade --set NIX_PGLIBDIR $out/lib - ''; - }; - in - pkg; -in -self.inputs.nixpkgs.lib.nixos.runTest { - name = pname; - hostPkgs = pkgs; - nodes.server = - { config, ... }: - { - virtualisation = { - forwardPorts = [ - { - from = "host"; - host.port = 13022; - guest.port = 22; - } - ]; - }; - services.openssh = { - enable = true; - }; - - services.postgresql = { - enable = true; - package = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15; - }; - - specialisation.postgresql17.configuration = { - services.postgresql = { - package = lib.mkForce (postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17); - }; - - systemd.services.postgresql-migrate = { - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - User = "postgres"; - Group = "postgres"; - StateDirectory = "postgresql"; - WorkingDirectory = "${builtins.dirOf config.services.postgresql.dataDir}"; - }; - script = - let - oldPostgresql = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15; - newPostgresql = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17; - oldDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${oldPostgresql.psqlSchema}"; - newDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${newPostgresql.psqlSchema}"; - in - '' - if [[ ! -d ${newDataDir} ]]; then - install -d -m 0700 -o postgres -g postgres "${newDataDir}" - ${newPostgresql}/bin/initdb -D "${newDataDir}" - ${newPostgresql}/bin/pg_upgrade --old-datadir "${oldDataDir}" --new-datadir "${newDataDir}" \ - --old-bindir "${oldPostgresql}/bin" --new-bindir "${newPostgresql}/bin" - else - echo "${newDataDir} already exists" - fi - ''; - }; - - systemd.services.postgresql = { - after = [ "postgresql-migrate.service" ]; - requires = [ "postgresql-migrate.service" ]; - }; - }; - }; - testScript = - { nodes, ... }: - let - pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17"; - in - '' - versions = { - "15": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "15"))}], - "17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}], - } - - def run_sql(query): - return server.succeed(f"""sudo -u postgres psql -t -A -F\",\" -c \"{query}\" """).strip() - - def check_upgrade_path(pg_version): - with subtest("Check ${pname} upgrade path"): - firstVersion = versions[pg_version][0] - server.succeed("sudo -u postgres psql -c 'DROP EXTENSION IF EXISTS ${pname};'") - run_sql(f"""CREATE EXTENSION ${pname} WITH VERSION '{firstVersion}' CASCADE;""") - installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = '${pname}';""") - assert installed_version == firstVersion, f"Expected ${pname} version {firstVersion}, but found {installed_version}" - for version in versions[pg_version][1:]: - run_sql(f"""ALTER EXTENSION ${pname} UPDATE TO '{version}';""") - installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = '${pname}';""") - assert installed_version == version, f"Expected ${pname} version {version}, but found {installed_version}" - - start_all() - - server.wait_for_unit("multi-user.target") - server.wait_for_unit("postgresql.service") - - check_upgrade_path("15") - - with subtest("Check ${pname} latest extension version"): - server.succeed("sudo -u postgres psql -c 'DROP EXTENSION ${pname};'") - server.succeed("sudo -u postgres psql -c 'CREATE EXTENSION ${pname} CASCADE;'") - installed_extensions=run_sql(r"""SELECT extname, extversion FROM pg_extension;""") - latestVersion = versions["15"][-1] - assert f"${pname},{latestVersion}" in installed_extensions - - with subtest("switch to postgresql 17"): - server.succeed( - "${pg17-configuration}/bin/switch-to-configuration test >&2" - ) - - with subtest("Check ${pname} latest extension version after upgrade"): - installed_extensions=run_sql(r"""SELECT extname, extversion FROM pg_extension;""") - latestVersion = versions["17"][-1] - assert f"${pname},{latestVersion}" in installed_extensions - - check_upgrade_path("17") - ''; -} From 9595cc046bf51df511b414e4068ab54d7f98cbd2 Mon Sep 17 00:00:00 2001 From: Yvan Sraka Date: Thu, 11 Dec 2025 18:30:46 +0100 Subject: [PATCH 3/6] chore: nix fmt --- nix/ext/gdal.nix | 17 +- nix/ext/pg_jsonschema/default.nix | 3 +- nix/ext/pg_net.nix | 3 +- nix/ext/pgaudit.nix | 26 +-- nix/ext/pgroonga/default.nix | 3 +- nix/ext/pgrouting.nix | 15 +- nix/ext/plv8/default.nix | 90 ++++----- nix/ext/postgis.nix | 3 +- nix/ext/tests/lib.py | 24 +-- nix/ext/tests/pgrouting.nix | 19 +- nix/ext/timescaledb.nix | 3 +- nix/ext/vault.nix | 43 ++--- nix/ext/wrappers/default.nix | 21 ++- nix/packages/groonga/default.nix | 29 +-- nix/packages/lib.nix | 13 +- nix/postgresql/generic.nix | 301 +++++++++++++++--------------- testinfra/test_ami_nix.py | 28 ++- 17 files changed, 327 insertions(+), 314 deletions(-) diff --git a/nix/ext/gdal.nix b/nix/ext/gdal.nix index c4dba3e695..739f7e4324 100644 --- a/nix/ext/gdal.nix +++ b/nix/ext/gdal.nix @@ -47,14 +47,15 @@ stdenv.mkDerivation rec { zlib ]; - cmakeFlags = [ - "-DGDAL_USE_INTERNAL_LIBS=OFF" - "-DGEOTIFF_INCLUDE_DIR=${lib.getDev libgeotiff}/include" - "-DGEOTIFF_LIBRARY_RELEASE=${lib.getLib libgeotiff}/lib/libgeotiff${stdenv.hostPlatform.extensions.sharedLibrary}" - "-DBUILD_PYTHON_BINDINGS=OFF" - ] - ++ lib.optionals (!stdenv.isDarwin) [ "-DCMAKE_SKIP_BUILD_RPATH=ON" ] - ++ lib.optionals stdenv.isDarwin [ "-DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON" ]; + cmakeFlags = + [ + "-DGDAL_USE_INTERNAL_LIBS=OFF" + "-DGEOTIFF_INCLUDE_DIR=${lib.getDev libgeotiff}/include" + "-DGEOTIFF_LIBRARY_RELEASE=${lib.getLib libgeotiff}/lib/libgeotiff${stdenv.hostPlatform.extensions.sharedLibrary}" + "-DBUILD_PYTHON_BINDINGS=OFF" + ] + ++ lib.optionals (!stdenv.isDarwin) [ "-DCMAKE_SKIP_BUILD_RPATH=ON" ] + ++ lib.optionals stdenv.isDarwin [ "-DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON" ]; enableParallelBuilding = true; diff --git a/nix/ext/pg_jsonschema/default.nix b/nix/ext/pg_jsonschema/default.nix index 84624300b6..1a2e8ee58f 100644 --- a/nix/ext/pg_jsonschema/default.nix +++ b/nix/ext/pg_jsonschema/default.nix @@ -45,8 +45,7 @@ let nativeBuildInputs = [ cargo ]; buildInputs = [ postgresql - ] - ++ lib.optionals stdenv.isDarwin [ darwin.apple_sdk.frameworks.SystemConfiguration ]; + ] ++ lib.optionals stdenv.isDarwin [ darwin.apple_sdk.frameworks.SystemConfiguration ]; # update the following array when the pg_jsonschema version is updated # required to ensure that extensions update scripts from previous versions are generated diff --git a/nix/ext/pg_net.nix b/nix/ext/pg_net.nix index d9f47aab84..229971a81c 100644 --- a/nix/ext/pg_net.nix +++ b/nix/ext/pg_net.nix @@ -20,8 +20,7 @@ let buildInputs = [ curl postgresql - ] - ++ lib.optional (version == "0.6") libuv; + ] ++ lib.optional (version == "0.6") libuv; src = fetchFromGitHub { owner = "supabase"; diff --git a/nix/ext/pgaudit.nix b/nix/ext/pgaudit.nix index 55dd237f7c..7660f2bd13 100644 --- a/nix/ext/pgaudit.nix +++ b/nix/ext/pgaudit.nix @@ -184,20 +184,22 @@ buildEnv { echo "Found control version: $controlVer from package ${pkg}" # Create migrations from control version to all supported versions on this PG major - ${lib.concatMapStringsSep "\n" (targetVer: '' - # Skip if control version equals target version - if [[ "$controlVer" != "${targetVer}" ]]; then - # Skip if migration already exists - if [[ ! -f "$out/share/postgresql/extension/${pname}--$controlVer--${targetVer}.sql" ]]; then - # Create symlink to migration if target SQL exists - if [[ -f "$out/share/postgresql/extension/${pname}--${targetVer}.sql" ]]; then - echo "Creating migration symlink from control version $controlVer to ${targetVer}" - ln -s "$out/share/postgresql/extension/${pname}--${targetVer}.sql" \ - "$out/share/postgresql/extension/${pname}--$controlVer--${targetVer}.sql" + ${ + lib.concatMapStringsSep "\n" (targetVer: '' + # Skip if control version equals target version + if [[ "$controlVer" != "${targetVer}" ]]; then + # Skip if migration already exists + if [[ ! -f "$out/share/postgresql/extension/${pname}--$controlVer--${targetVer}.sql" ]]; then + # Create symlink to migration if target SQL exists + if [[ -f "$out/share/postgresql/extension/${pname}--${targetVer}.sql" ]]; then + echo "Creating migration symlink from control version $controlVer to ${targetVer}" + ln -s "$out/share/postgresql/extension/${pname}--${targetVer}.sql" \ + "$out/share/postgresql/extension/${pname}--$controlVer--${targetVer}.sql" + fi fi fi - fi - '') versions} + '') versions + } fi '') packages} diff --git a/nix/ext/pgroonga/default.nix b/nix/ext/pgroonga/default.nix index 89aca72a23..22a8c2dfc6 100644 --- a/nix/ext/pgroonga/default.nix +++ b/nix/ext/pgroonga/default.nix @@ -57,8 +57,7 @@ let msgpack-c supabase-groonga mecab - ] - ++ lib.optionals stdenv.isDarwin [ xxHash ]; + ] ++ lib.optionals stdenv.isDarwin [ xxHash ]; propagatedBuildInputs = [ supabase-groonga diff --git a/nix/ext/pgrouting.nix b/nix/ext/pgrouting.nix index 5690a41406..48833791e7 100644 --- a/nix/ext/pgrouting.nix +++ b/nix/ext/pgrouting.nix @@ -54,14 +54,13 @@ let stdenv.isDarwin && lib.versionAtLeast postgresql.version "16" ) "-Wno-error=int-conversion -Wno-error=incompatible-pointer-types"; - cmakeFlags = [ - "-DPOSTGRESQL_VERSION=${postgresql.version}" - ] - ++ lib.optionals (stdenv.isDarwin && lib.versionAtLeast postgresql.version "16") [ - "-DCMAKE_MACOSX_RPATH=ON" - "-DCMAKE_SHARED_MODULE_SUFFIX=.dylib" - "-DCMAKE_SHARED_LIBRARY_SUFFIX=.dylib" - ]; + cmakeFlags = + [ "-DPOSTGRESQL_VERSION=${postgresql.version}" ] + ++ lib.optionals (stdenv.isDarwin && lib.versionAtLeast postgresql.version "16") [ + "-DCMAKE_MACOSX_RPATH=ON" + "-DCMAKE_SHARED_MODULE_SUFFIX=.dylib" + "-DCMAKE_SHARED_LIBRARY_SUFFIX=.dylib" + ]; preConfigure = lib.optionalString (stdenv.isDarwin && lib.versionAtLeast postgresql.version "16") '' export DLSUFFIX=.dylib diff --git a/nix/ext/plv8/default.nix b/nix/ext/plv8/default.nix index 5df87bb747..d858405ed4 100644 --- a/nix/ext/plv8/default.nix +++ b/nix/ext/plv8/default.nix @@ -50,47 +50,49 @@ let inherit hash; }; - patches = [ - # Allow building with system v8. - # https://github.com/plv8/plv8/pull/505 (rejected) - ./0001-build-Allow-using-V8-from-system-${version}.patch - ] - ++ lib.optionals (builtins.compareVersions "3.1.10" version >= 0) [ - # Apply https://github.com/plv8/plv8/pull/552/ patch to fix extension upgrade problems - ./0001-fix-upgrade-related-woes-with-GUC-redefinitions-${version}.patch - ]; + patches = + [ + # Allow building with system v8. + # https://github.com/plv8/plv8/pull/505 (rejected) + ./0001-build-Allow-using-V8-from-system-${version}.patch + ] + ++ lib.optionals (builtins.compareVersions "3.1.10" version >= 0) [ + # Apply https://github.com/plv8/plv8/pull/552/ patch to fix extension upgrade problems + ./0001-fix-upgrade-related-woes-with-GUC-redefinitions-${version}.patch + ]; - nativeBuildInputs = [ - perl - ] - ++ lib.optionals stdenv.isDarwin [ - clang - xcbuild - ]; + nativeBuildInputs = + [ perl ] + ++ lib.optionals stdenv.isDarwin [ + clang + xcbuild + ]; - buildInputs = [ - (if (builtins.compareVersions "3.1.10" version >= 0) then v8 else nodejs_20.libv8) - postgresql - ] - ++ lib.optionals stdenv.isDarwin [ - darwin.apple_sdk.frameworks.CoreFoundation - darwin.apple_sdk.frameworks.Kerberos - ]; + buildInputs = + [ + (if (builtins.compareVersions "3.1.10" version >= 0) then v8 else nodejs_20.libv8) + postgresql + ] + ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.CoreFoundation + darwin.apple_sdk.frameworks.Kerberos + ]; buildFlags = [ "all" ]; - makeFlags = [ - # Nixpkgs build a v8 monolith instead of separate v8_libplatform. - "USE_SYSTEM_V8=1" - "V8_OUTDIR=${v8}/lib" - "PG_CONFIG=${postgresql}/bin/pg_config" - ] - ++ lib.optionals stdenv.isDarwin [ - "CC=${clang}/bin/clang" - "CXX=${clang}/bin/clang++" - "SHLIB_LINK=-L${v8}/lib -lv8_monolith -Wl,-rpath,${v8}/lib" - ] - ++ lib.optionals (!stdenv.isDarwin) [ "SHLIB_LINK=-lv8" ]; + makeFlags = + [ + # Nixpkgs build a v8 monolith instead of separate v8_libplatform. + "USE_SYSTEM_V8=1" + "V8_OUTDIR=${v8}/lib" + "PG_CONFIG=${postgresql}/bin/pg_config" + ] + ++ lib.optionals stdenv.isDarwin [ + "CC=${clang}/bin/clang" + "CXX=${clang}/bin/clang++" + "SHLIB_LINK=-L${v8}/lib -lv8_monolith -Wl,-rpath,${v8}/lib" + ] + ++ lib.optionals (!stdenv.isDarwin) [ "SHLIB_LINK=-lv8" ]; NIX_LDFLAGS = lib.optionals stdenv.isDarwin [ "-L${postgresql}/lib" @@ -142,9 +144,11 @@ let install_name_tool -change @rpath/libv8_monolith.dylib ${v8}/lib/libv8_monolith.dylib $out/lib/$LIB_NAME ''} - ${lib.optionalString (!stdenv.isDarwin) '' - ${patchelf}/bin/patchelf --set-rpath "${v8}/lib:${postgresql}/lib:${libcxx}/lib" $out/lib/$LIB_NAME - ''} + ${ + lib.optionalString (!stdenv.isDarwin) '' + ${patchelf}/bin/patchelf --set-rpath "${v8}/lib:${postgresql}/lib:${libcxx}/lib" $out/lib/$LIB_NAME + '' + } else ${lib.optionalString stdenv.isDarwin '' install_name_tool -add_rpath "${v8}/lib" $out/lib/$LIB_NAME @@ -153,9 +157,11 @@ let install_name_tool -change @rpath/libv8_monolith.dylib ${v8}/lib/libv8_monolith.dylib $out/lib/$LIB_NAME ''} - ${lib.optionalString (!stdenv.isDarwin) '' - ${patchelf}/bin/patchelf --set-rpath "${v8}/lib:${postgresql}/lib:${libcxx}/lib" $out/lib/$LIB_NAME - ''} + ${ + lib.optionalString (!stdenv.isDarwin) '' + ${patchelf}/bin/patchelf --set-rpath "${v8}/lib:${postgresql}/lib:${libcxx}/lib" $out/lib/$LIB_NAME + '' + } fi # plv8 3.2.x removed support for coffeejs and livescript diff --git a/nix/ext/postgis.nix b/nix/ext/postgis.nix index a8dd831a14..cdf48fb24d 100644 --- a/nix/ext/postgis.nix +++ b/nix/ext/postgis.nix @@ -79,8 +79,7 @@ let protobufc pcre2.dev sfcgal - ] - ++ lib.optional stdenv.isDarwin libiconv; + ] ++ lib.optional stdenv.isDarwin libiconv; nativeBuildInputs = [ perl pkg-config diff --git a/nix/ext/tests/lib.py b/nix/ext/tests/lib.py index 66d96523df..d04f830fd4 100644 --- a/nix/ext/tests/lib.py +++ b/nix/ext/tests/lib.py @@ -93,9 +93,9 @@ def assert_version_matches(self, expected_version: str): AssertionError: If the installed version does not match the expected version """ installed_version = self.get_installed_version() - assert installed_version == expected_version, ( - f"Expected version {expected_version}, but found {installed_version}" - ) + assert ( + installed_version == expected_version + ), f"Expected version {expected_version}, but found {installed_version}" def check_upgrade_path(self, pg_version: str): """Test the complete upgrade path for a PostgreSQL version. @@ -163,9 +163,9 @@ def check_switch_extension_with_background_worker( f"No versions available for PostgreSQL version {pg_version}" ) last_version = available_versions[-1] - assert ext_version.endswith(f"{last_version}.so"), ( - f"Expected {self.extension_name} version {last_version}, but found {ext_version}" - ) + assert ext_version.endswith( + f"{last_version}.so" + ), f"Expected {self.extension_name} version {last_version}, but found {ext_version}" # Switch to the first version first_version = available_versions[0] @@ -173,17 +173,17 @@ def check_switch_extension_with_background_worker( # Check that we are using the first version now ext_version = self.vm.succeed(f"readlink -f {extension_lib_path}").strip() - assert ext_version.endswith(f"{first_version}.so"), ( - f"Expected {self.extension_name} version {first_version}, but found {ext_version}" - ) + assert ext_version.endswith( + f"{first_version}.so" + ), f"Expected {self.extension_name} version {first_version}, but found {ext_version}" # Switch to the last version self.vm.succeed(f"switch_{self.extension_name}_version {last_version}") # Check that we are using the last version now ext_version = self.vm.succeed(f"readlink -f {extension_lib_path}").strip() - assert ext_version.endswith(f"{last_version}.so"), ( - f"Expected {self.extension_name} version {last_version}, but found {ext_version}" - ) + assert ext_version.endswith( + f"{last_version}.so" + ), f"Expected {self.extension_name} version {last_version}, but found {ext_version}" def check_pg_regress(self, pg_regress: Path, pg_version: str, test_name: str): """Run pg_regress tests for the extension on a given PostgreSQL version. diff --git a/nix/ext/tests/pgrouting.nix b/nix/ext/tests/pgrouting.nix index e3dfc6dc38..f4550b576f 100644 --- a/nix/ext/tests/pgrouting.nix +++ b/nix/ext/tests/pgrouting.nix @@ -12,15 +12,16 @@ let majorVersion = lib.versions.major postgresql.version; pkg = pkgs.buildEnv { name = "postgresql-${majorVersion}-${pname}"; - paths = [ - postgresql - postgresql.lib - (installedExtension majorVersion) - (self.legacyPackages.${pkgs.system}."psql_${majorVersion}".exts.postgis) - ] - ++ lib.optional (postgresql.isOrioleDB) ( - self.legacyPackages.${pkgs.system}."psql_orioledb-17".exts.orioledb - ); + paths = + [ + postgresql + postgresql.lib + (installedExtension majorVersion) + (self.legacyPackages.${pkgs.system}."psql_${majorVersion}".exts.postgis) + ] + ++ lib.optional (postgresql.isOrioleDB) ( + self.legacyPackages.${pkgs.system}."psql_orioledb-17".exts.orioledb + ); passthru = { inherit (postgresql) version psqlSchema; lib = pkg; diff --git a/nix/ext/timescaledb.nix b/nix/ext/timescaledb.nix index 8c42aaaeff..91605a48c4 100644 --- a/nix/ext/timescaledb.nix +++ b/nix/ext/timescaledb.nix @@ -39,8 +39,7 @@ let "-DREGRESS_CHECKS=OFF" "-DTAP_CHECKS=OFF" "-DAPACHE_ONLY=1" - ] - ++ lib.optionals stdenv.isDarwin [ "-DLINTER=OFF" ]; + ] ++ lib.optionals stdenv.isDarwin [ "-DLINTER=OFF" ]; postPatch = '' for x in CMakeLists.txt sql/CMakeLists.txt; do diff --git a/nix/ext/vault.nix b/nix/ext/vault.nix index 537febc0b6..cb90882a7b 100644 --- a/nix/ext/vault.nix +++ b/nix/ext/vault.nix @@ -44,30 +44,31 @@ let inherit hash; }; - installPhase = '' - mkdir -p $out/{lib,share/postgresql/extension} + installPhase = + '' + mkdir -p $out/{lib,share/postgresql/extension} - # Create version-specific control file - sed -e "/^default_version =/d" \ - -e "s|^module_pathname = .*|module_pathname = '\$libdir/${pname}'|" \ - ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control + # Create version-specific control file + sed -e "/^default_version =/d" \ + -e "s|^module_pathname = .*|module_pathname = '\$libdir/${pname}'|" \ + ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control - '' - # for versions <= 0.2.8, we don't have a library to install - + lib.optionalString (builtins.compareVersions "0.2.8" version < 0) '' - # Install shared library with version suffix - mv ${pname}${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix} + '' + # for versions <= 0.2.8, we don't have a library to install + + lib.optionalString (builtins.compareVersions "0.2.8" version < 0) '' + # Install shared library with version suffix + mv ${pname}${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix} - # For the latest version, copy the sql files - if [[ "${version}" == "${latestVersion}" ]]; then - install -D -t $out/share/postgresql/extension sql/*.sql - { - echo "default_version = '${latestVersion}'" - cat $out/share/postgresql/extension/${pname}--${latestVersion}.control - } > $out/share/postgresql/extension/${pname}.control - fi - ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} - ''; + # For the latest version, copy the sql files + if [[ "${version}" == "${latestVersion}" ]]; then + install -D -t $out/share/postgresql/extension sql/*.sql + { + echo "default_version = '${latestVersion}'" + cat $out/share/postgresql/extension/${pname}--${latestVersion}.control + } > $out/share/postgresql/extension/${pname}.control + fi + ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} + ''; meta = with lib; { description = "Store encrypted secrets in PostgreSQL"; diff --git a/nix/ext/wrappers/default.nix b/nix/ext/wrappers/default.nix index a032eb9b69..c9f22dc4a1 100644 --- a/nix/ext/wrappers/default.nix +++ b/nix/ext/wrappers/default.nix @@ -37,16 +37,17 @@ let cargo git ]; - buildInputs = [ - openssl - postgresql - ] - ++ lib.optionals stdenv.isDarwin [ - darwin.apple_sdk.frameworks.CoreFoundation - darwin.apple_sdk.frameworks.CoreServices - darwin.apple_sdk.frameworks.Security - darwin.apple_sdk.frameworks.SystemConfiguration - ]; + buildInputs = + [ + openssl + postgresql + ] + ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.CoreFoundation + darwin.apple_sdk.frameworks.CoreServices + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.SystemConfiguration + ]; NIX_LDFLAGS = "-L${postgresql}/lib -lpq"; diff --git a/nix/packages/groonga/default.nix b/nix/packages/groonga/default.nix index c6d734db6c..bef4911095 100644 --- a/nix/packages/groonga/default.nix +++ b/nix/packages/groonga/default.nix @@ -36,20 +36,21 @@ stdenv.mkDerivation (finalAttrs: { pkg-config makeWrapper ]; - buildInputs = [ - rapidjson - xxHash - zstd - mecab - kytea - msgpack-c - ] - ++ lib.optionals lz4Support [ lz4 ] - ++ lib.optional zlibSupport [ zlib ] - ++ lib.optionals suggestSupport [ - zeromq - libevent - ]; + buildInputs = + [ + rapidjson + xxHash + zstd + mecab + kytea + msgpack-c + ] + ++ lib.optionals lz4Support [ lz4 ] + ++ lib.optional zlibSupport [ zlib ] + ++ lib.optionals suggestSupport [ + zeromq + libevent + ]; cmakeFlags = [ "-DWITH_MECAB=ON" "-DMECAB_DICDIR=${mecab-naist-jdic}/lib/mecab/dic/naist-jdic" diff --git a/nix/packages/lib.nix b/nix/packages/lib.nix index ef8f640697..cf541913da 100644 --- a/nix/packages/lib.nix +++ b/nix/packages/lib.nix @@ -100,8 +100,7 @@ PGBOUNCER_AUTH_SCHEMA_SQL = "${paths.pgbouncerAuthSchemaSql}"; STAT_EXTENSION_SQL = "${paths.statExtensionSql}"; CURRENT_SYSTEM = "${system}"; - } - // extraSubstitutions; # Merge in any extra substitutions + } // extraSubstitutions; # Merge in any extra substitutions in pkgs.runCommand name { @@ -130,11 +129,13 @@ chmod 644 $out/etc/postgresql/pg_hba.conf substitute ${../tools/run-server.sh.in} $out/bin/start-postgres-server \ - ${builtins.concatStringsSep " " ( - builtins.attrValues ( - builtins.mapAttrs (name: value: "--subst-var-by '${name}' '${value}'") substitutions + ${ + builtins.concatStringsSep " " ( + builtins.attrValues ( + builtins.mapAttrs (name: value: "--subst-var-by '${name}' '${value}'") substitutions + ) ) - )} + } chmod +x $out/bin/start-postgres-server ''; } diff --git a/nix/postgresql/generic.nix b/nix/postgresql/generic.nix index 1be57113f3..ea67cbc915 100644 --- a/nix/postgresql/generic.nix +++ b/nix/postgresql/generic.nix @@ -113,41 +113,43 @@ let ]; setOutputFlags = false; # $out retains configureFlags :-/ - buildInputs = [ - zlib - readline - openssl - (libxml2.override { python = python3; }) - icu - ] - ++ lib.optionals (olderThan "13") [ libxcrypt ] - ++ lib.optionals jitSupport [ llvmPackages.llvm ] - ++ lib.optionals lz4Enabled [ lz4 ] - ++ lib.optionals zstdEnabled [ zstd ] - ++ lib.optionals systemdSupport' [ systemd ] - ++ lib.optionals pythonSupport [ python3 ] - ++ lib.optionals gssSupport [ libkrb5 ] - ++ lib.optionals stdenv'.isLinux [ linux-pam ] - ++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ] - ++ lib.optionals (isOrioleDB || (lib.versionAtLeast version "17")) [ - perl - bison - flex - docbook_xsl - docbook_xml_dtd_45 - docbook_xsl_ns - libxslt - ]; + buildInputs = + [ + zlib + readline + openssl + (libxml2.override { python = python3; }) + icu + ] + ++ lib.optionals (olderThan "13") [ libxcrypt ] + ++ lib.optionals jitSupport [ llvmPackages.llvm ] + ++ lib.optionals lz4Enabled [ lz4 ] + ++ lib.optionals zstdEnabled [ zstd ] + ++ lib.optionals systemdSupport' [ systemd ] + ++ lib.optionals pythonSupport [ python3 ] + ++ lib.optionals gssSupport [ libkrb5 ] + ++ lib.optionals stdenv'.isLinux [ linux-pam ] + ++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ] + ++ lib.optionals (isOrioleDB || (lib.versionAtLeast version "17")) [ + perl + bison + flex + docbook_xsl + docbook_xml_dtd_45 + docbook_xsl_ns + libxslt + ]; - nativeBuildInputs = [ - makeWrapper - pkg-config - ] - ++ lib.optionals jitSupport [ - llvmPackages.llvm.dev - nukeReferences - patchelf - ]; + nativeBuildInputs = + [ + makeWrapper + pkg-config + ] + ++ lib.optionals jitSupport [ + llvmPackages.llvm.dev + nukeReferences + patchelf + ]; enableParallelBuilding = true; @@ -159,109 +161,113 @@ let # Fixed upstream in https://github.com/postgres/postgres/commit/0bc8cebdb889368abdf224aeac8bc197fe4c9ae6 env.NIX_CFLAGS_COMPILE = lib.optionalString (olderThan "13") "-I${libxml2.dev}/include/libxml2"; - configureFlags = [ - "--with-openssl" - "--with-libxml" - "--with-icu" - "--sysconfdir=/etc" - "--libdir=$(lib)/lib" - "--with-system-tzdata=${tzdata}/share/zoneinfo" - "--enable-debug" - (lib.optionalString systemdSupport' "--with-systemd") - (if stdenv'.isDarwin then "--with-uuid=e2fs" else "--with-ossp-uuid") - ] - ++ lib.optionals lz4Enabled [ "--with-lz4" ] - ++ lib.optionals zstdEnabled [ "--with-zstd" ] - ++ lib.optionals gssSupport [ "--with-gssapi" ] - ++ lib.optionals pythonSupport [ "--with-python" ] - ++ lib.optionals jitSupport [ "--with-llvm" ] - ++ lib.optionals stdenv'.isLinux [ "--with-pam" ]; - - patches = [ - ( - if atLeast "16" then - ./patches/relative-to-symlinks-16+.patch - else - ./patches/relative-to-symlinks.patch + configureFlags = + [ + "--with-openssl" + "--with-libxml" + "--with-icu" + "--sysconfdir=/etc" + "--libdir=$(lib)/lib" + "--with-system-tzdata=${tzdata}/share/zoneinfo" + "--enable-debug" + (lib.optionalString systemdSupport' "--with-systemd") + (if stdenv'.isDarwin then "--with-uuid=e2fs" else "--with-ossp-uuid") + ] + ++ lib.optionals lz4Enabled [ "--with-lz4" ] + ++ lib.optionals zstdEnabled [ "--with-zstd" ] + ++ lib.optionals gssSupport [ "--with-gssapi" ] + ++ lib.optionals pythonSupport [ "--with-python" ] + ++ lib.optionals jitSupport [ "--with-llvm" ] + ++ lib.optionals stdenv'.isLinux [ "--with-pam" ]; + + patches = + [ + ( + if atLeast "16" then + ./patches/relative-to-symlinks-16+.patch + else + ./patches/relative-to-symlinks.patch + ) + ./patches/less-is-more.patch + ./patches/paths-for-split-outputs.patch + ./patches/specify_pkglibdir_at_runtime.patch + ./patches/paths-with-postgresql-suffix.patch + ./patches/locale-binary-path.patch + ] + ++ lib.optionals stdenv'.hostPlatform.isMusl ( + # Using fetchurl instead of fetchpatch on purpose: https://github.com/NixOS/nixpkgs/issues/240141 + map fetchurl (lib.attrValues muslPatches) ) - ./patches/less-is-more.patch - ./patches/paths-for-split-outputs.patch - ./patches/specify_pkglibdir_at_runtime.patch - ./patches/paths-with-postgresql-suffix.patch - ./patches/locale-binary-path.patch - ] - ++ lib.optionals stdenv'.hostPlatform.isMusl ( - # Using fetchurl instead of fetchpatch on purpose: https://github.com/NixOS/nixpkgs/issues/240141 - map fetchurl (lib.attrValues muslPatches) - ) - ++ lib.optionals stdenv'.isLinux [ - (if atLeast "13" then ./patches/socketdir-in-run-13+.patch else ./patches/socketdir-in-run.patch) - ]; + ++ lib.optionals stdenv'.isLinux [ + (if atLeast "13" then ./patches/socketdir-in-run-13+.patch else ./patches/socketdir-in-run.patch) + ]; installTargets = [ "install-world-bin" ]; - postPatch = '' - # Hardcode the path to pgxs so pg_config returns the path in $out - substituteInPlace "src/common/config_info.c" --subst-var out - substituteInPlace "src/backend/commands/collationcmds.c" --replace-fail '@locale@' '${ - if stdenv.isDarwin then darwin.adv_cmds else lib.getBin stdenv.cc.libc - }/bin/locale' - '' - + lib.optionalString jitSupport '' - # Force lookup of jit stuff in $out instead of $lib - substituteInPlace src/backend/jit/jit.c --replace pkglib_path \"$out/lib\" - substituteInPlace src/backend/jit/llvm/llvmjit.c --replace pkglib_path \"$out/lib\" - substituteInPlace src/backend/jit/llvm/llvmjit_inline.cpp --replace pkglib_path \"$out/lib\" - ''; - - postInstall = '' - moveToOutput "lib/pgxs" "$out" # looks strange, but not deleting it - moveToOutput "lib/libpgcommon*.a" "$out" - moveToOutput "lib/libpgport*.a" "$out" - moveToOutput "lib/libecpg*" "$out" - - # Prevent a retained dependency on gcc-wrapper. - substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/ld ld - - if [ -z "''${dontDisableStatic:-}" ]; then - # Remove static libraries in case dynamic are available. - for i in $out/lib/*.a $lib/lib/*.a; do - name="$(basename "$i")" - ext="${stdenv'.hostPlatform.extensions.sharedLibrary}" - if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then - rm "$i" - fi - done - fi - '' - + lib.optionalString jitSupport '' - # Move the bitcode and libllvmjit.so library out of $lib; otherwise, every client that - # depends on libpq.so will also have libLLVM.so in its closure too, bloating it - moveToOutput "lib/bitcode" "$out" - moveToOutput "lib/llvmjit*" "$out" - - # In the case of JIT support, prevent a retained dependency on clang-wrapper - substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/clang clang - nuke-refs $out/lib/llvmjit_types.bc $(find $out/lib/bitcode -type f) - - # Stop out depending on the default output of llvm - substituteInPlace $out/lib/pgxs/src/Makefile.global \ - --replace ${llvmPackages.llvm.out}/bin "" \ - --replace '$(LLVM_BINPATH)/' "" - - # Stop out depending on the -dev output of llvm - substituteInPlace $out/lib/pgxs/src/Makefile.global \ - --replace ${llvmPackages.llvm.dev}/bin/llvm-config llvm-config \ - --replace -I${llvmPackages.llvm.dev}/include "" - - ${lib.optionalString (!stdenv'.isDarwin) '' - # Stop lib depending on the -dev output of llvm - rpath=$(patchelf --print-rpath $out/lib/llvmjit.so) - nuke-refs -e $out $out/lib/llvmjit.so - # Restore the correct rpath - patchelf $out/lib/llvmjit.so --set-rpath "$rpath" - ''} - ''; + postPatch = + '' + # Hardcode the path to pgxs so pg_config returns the path in $out + substituteInPlace "src/common/config_info.c" --subst-var out + substituteInPlace "src/backend/commands/collationcmds.c" --replace-fail '@locale@' '${ + if stdenv.isDarwin then darwin.adv_cmds else lib.getBin stdenv.cc.libc + }/bin/locale' + '' + + lib.optionalString jitSupport '' + # Force lookup of jit stuff in $out instead of $lib + substituteInPlace src/backend/jit/jit.c --replace pkglib_path \"$out/lib\" + substituteInPlace src/backend/jit/llvm/llvmjit.c --replace pkglib_path \"$out/lib\" + substituteInPlace src/backend/jit/llvm/llvmjit_inline.cpp --replace pkglib_path \"$out/lib\" + ''; + + postInstall = + '' + moveToOutput "lib/pgxs" "$out" # looks strange, but not deleting it + moveToOutput "lib/libpgcommon*.a" "$out" + moveToOutput "lib/libpgport*.a" "$out" + moveToOutput "lib/libecpg*" "$out" + + # Prevent a retained dependency on gcc-wrapper. + substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/ld ld + + if [ -z "''${dontDisableStatic:-}" ]; then + # Remove static libraries in case dynamic are available. + for i in $out/lib/*.a $lib/lib/*.a; do + name="$(basename "$i")" + ext="${stdenv'.hostPlatform.extensions.sharedLibrary}" + if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then + rm "$i" + fi + done + fi + '' + + lib.optionalString jitSupport '' + # Move the bitcode and libllvmjit.so library out of $lib; otherwise, every client that + # depends on libpq.so will also have libLLVM.so in its closure too, bloating it + moveToOutput "lib/bitcode" "$out" + moveToOutput "lib/llvmjit*" "$out" + + # In the case of JIT support, prevent a retained dependency on clang-wrapper + substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/clang clang + nuke-refs $out/lib/llvmjit_types.bc $(find $out/lib/bitcode -type f) + + # Stop out depending on the default output of llvm + substituteInPlace $out/lib/pgxs/src/Makefile.global \ + --replace ${llvmPackages.llvm.out}/bin "" \ + --replace '$(LLVM_BINPATH)/' "" + + # Stop out depending on the -dev output of llvm + substituteInPlace $out/lib/pgxs/src/Makefile.global \ + --replace ${llvmPackages.llvm.dev}/bin/llvm-config llvm-config \ + --replace -I${llvmPackages.llvm.dev}/include "" + + ${lib.optionalString (!stdenv'.isDarwin) '' + # Stop lib depending on the -dev output of llvm + rpath=$(patchelf --print-rpath $out/lib/llvmjit.so) + nuke-refs -e $out $out/lib/llvmjit.so + # Restore the correct rpath + patchelf $out/lib/llvmjit.so --set-rpath "$rpath" + ''} + ''; postFixup = lib.optionalString (!stdenv'.isDarwin && stdenv'.hostPlatform.libc == "glibc") '' # initdb needs access to "locale" command from glibc. @@ -315,21 +321,22 @@ let postgresql = this; } this.pkgs; - tests = { - postgresql-wal-receiver = import ../../../../nixos/tests/postgresql-wal-receiver.nix { - inherit (stdenv) system; - pkgs = self; - package = this; - }; - pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; - } - // lib.optionalAttrs jitSupport { - postgresql-jit = import ../../../../nixos/tests/postgresql-jit.nix { - inherit (stdenv) system; - pkgs = self; - package = this; + tests = + { + postgresql-wal-receiver = import ../../../../nixos/tests/postgresql-wal-receiver.nix { + inherit (stdenv) system; + pkgs = self; + package = this; + }; + pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; + } + // lib.optionalAttrs jitSupport { + postgresql-jit = import ../../../../nixos/tests/postgresql-jit.nix { + inherit (stdenv) system; + pkgs = self; + package = this; + }; }; - }; }; meta = with lib; { diff --git a/testinfra/test_ami_nix.py b/testinfra/test_ami_nix.py index a5cadcad9c..1b00f2c84a 100644 --- a/testinfra/test_ami_nix.py +++ b/testinfra/test_ami_nix.py @@ -421,9 +421,9 @@ def is_healthy(ssh) -> bool: def test_postgrest_is_running(host): """Check if postgrest service is running using our SSH connection.""" result = run_ssh_command(host["ssh"], "systemctl is-active postgrest") - assert result["succeeded"] and result["stdout"].strip() == "active", ( - "PostgREST service is not running" - ) + assert ( + result["succeeded"] and result["stdout"].strip() == "active" + ), "PostgREST service is not running" def test_postgrest_responds_to_requests(host): @@ -546,9 +546,9 @@ def test_postgresql_version(host): if version_match: major_version = int(version_match.group(1)) print(f"PostgreSQL major version: {major_version}") - assert major_version >= 14, ( - f"PostgreSQL version {major_version} is less than 14" - ) + assert ( + major_version >= 14 + ), f"PostgreSQL version {major_version} is less than 14" else: assert False, "Could not parse PostgreSQL version number" else: @@ -578,9 +578,9 @@ def test_libpq5_version(host): if version_match: major_version = int(version_match.group(1)) print(f"libpq5 major version: {major_version}") - assert major_version >= 14, ( - f"libpq5 version {major_version} is less than 14" - ) + assert ( + major_version >= 14 + ), f"libpq5 version {major_version} is less than 14" else: print("Could not parse libpq5 version from dpkg output") else: @@ -613,9 +613,9 @@ def test_libpq5_version(host): if version_match: major_version = int(version_match.group(1)) print(f"psql/libpq major version: {major_version}") - assert major_version >= 14, ( - f"psql/libpq version {major_version} is less than 14" - ) + assert ( + major_version >= 14 + ), f"psql/libpq version {major_version} is less than 14" else: print("Could not parse psql version") @@ -776,9 +776,7 @@ def test_postgrest_read_only_session_attrs(host): print( f"\nFound 'session is not read-only' errors in PostgREST logs:\n{result['stdout']}" ) - assert False, ( - "PostgREST logs contain 'session is not read-only' errors even though PostgreSQL is configured for read-only mode" - ) + assert False, "PostgREST logs contain 'session is not read-only' errors even though PostgreSQL is configured for read-only mode" else: print("\nNo 'session is not read-only' errors found in PostgREST logs") From 008f32fb4a2a9c0f06c51766e697265006155208 Mon Sep 17 00:00:00 2001 From: Yvan Sraka Date: Mon, 19 Jan 2026 15:40:07 +0100 Subject: [PATCH 4/6] fix(pgtap): define ext variable before sed command Define the ext variable to point to the correct shared library path before using it in the sed command that sets module_pathname in the PostgreSQL extension control file. --- nix/ext/pgtap.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix/ext/pgtap.nix b/nix/ext/pgtap.nix index 86bc0c9506..e50bdef6e0 100644 --- a/nix/ext/pgtap.nix +++ b/nix/ext/pgtap.nix @@ -64,6 +64,7 @@ let mkdir -p $out/{lib,share/postgresql/extension} # Create version-specific control file + ext="$out/lib/${pname}-${version}${postgresql.dlSuffix}" sed -e "/^default_version =/d" \ -e "s|^module_pathname = .*|module_pathname = '$ext'|" \ ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control From 1bade9f69ac3835615afeeeb3c99c94c66c4803a Mon Sep 17 00:00:00 2001 From: Yvan Sraka Date: Mon, 19 Jan 2026 16:05:57 +0100 Subject: [PATCH 5/6] fix(pgtap): use platform-specific extension suffix for shared library detection Check for src/pgtap${postgresql.dlSuffix} instead of hardcoded src/pgtap.so to properly detect the shared library on all platforms (e.g., .dylib on macOS). --- nix/ext/pgtap.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nix/ext/pgtap.nix b/nix/ext/pgtap.nix index e50bdef6e0..54be7c2f18 100644 --- a/nix/ext/pgtap.nix +++ b/nix/ext/pgtap.nix @@ -72,9 +72,9 @@ let # Copy SQL file to install the specific version cp sql/${pname}--${version}.sql $out/share/postgresql/extension - if [[ -f src/pgtap.so ]]; then + if [[ -f src/pgtap${postgresql.dlSuffix} ]]; then # Install the shared library with version suffix - install -Dm755 src/pgtap.so $out/lib/${pname}-${version}${postgresql.dlSuffix} + install -Dm755 src/pgtap${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix} fi # For the latest version, create default control file and symlink and copy SQL upgrade scripts From 6d28bfbf4a89e84a83285eee4695068cdc8123a3 Mon Sep 17 00:00:00 2001 From: Yvan Sraka Date: Mon, 19 Jan 2026 16:48:48 +0100 Subject: [PATCH 6/6] fix(pgtap): add guards for empty versions and conditional module_pathname - Add assertion guard to fail clearly when no supported versions exist for the current PostgreSQL version, preventing lib.last on empty list - Gate module_pathname rewrite on shared library existence: only set module_pathname when the shared library exists, remove the line entirely for SQL-only versions to prevent CREATE EXTENSION failures --- nix/ext/pgtap.nix | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/nix/ext/pgtap.nix b/nix/ext/pgtap.nix index 54be7c2f18..2953f62bc0 100644 --- a/nix/ext/pgtap.nix +++ b/nix/ext/pgtap.nix @@ -22,7 +22,11 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); - latestVersion = lib.last versions; + latestVersion = + assert lib.assertMsg ( + versions != [ ] + ) "pgtap: no supported versions for PostgreSQL ${lib.versions.major postgresql.version}"; + lib.last versions; numberOfVersions = builtins.length versions; packages = builtins.attrValues ( lib.mapAttrs (name: value: build name value.hash) supportedVersions @@ -64,10 +68,18 @@ let mkdir -p $out/{lib,share/postgresql/extension} # Create version-specific control file - ext="$out/lib/${pname}-${version}${postgresql.dlSuffix}" - sed -e "/^default_version =/d" \ - -e "s|^module_pathname = .*|module_pathname = '$ext'|" \ - ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control + if [[ -f src/pgtap${postgresql.dlSuffix} ]]; then + # For versions with shared library, set module_pathname + ext="$out/lib/${pname}-${version}${postgresql.dlSuffix}" + sed -e "/^default_version =/d" \ + -e "s|^module_pathname = .*|module_pathname = '$ext'|" \ + ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control + else + # For SQL-only versions, remove module_pathname line entirely + sed -e "/^default_version =/d" \ + -e "/^module_pathname =/d" \ + ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control + fi # Copy SQL file to install the specific version cp sql/${pname}--${version}.sql $out/share/postgresql/extension