From 2d90f6e4295d48b8e4ca27e8db76c9a690cc654c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Sun, 8 Mar 2026 19:35:10 +0100 Subject: [PATCH 01/13] update precompilation targets --- .github/workflows/precompile.yml | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/workflows/precompile.yml b/.github/workflows/precompile.yml index 7016176..6c60af7 100644 --- a/.github/workflows/precompile.yml +++ b/.github/workflows/precompile.yml @@ -4,6 +4,7 @@ on: push: tags: - "v*.*.*" + - "precompile-test" permissions: contents: write @@ -18,11 +19,14 @@ jobs: matrix: include: - pair: - elixir: "1.16.3-otp-24" - otp: "24.3.4.17" + elixir: "1.18.4-otp-27" + otp: "27.3" - pair: - elixir: "1.18.2-otp-27" - otp: "27.2.2" + elixir: "1.19.5-otp-27" + otp: "27.3" + - pair: + elixir: "1.20.0-rc.2-otp-28" + otp: "28.4" steps: - uses: actions/checkout@v4 - name: Set up Elixir @@ -83,11 +87,14 @@ jobs: matrix: include: - pair: - elixir: "1.16.3-otp-24" - otp: "24.3.4.17" + elixir: "1.18.4-otp-27" + otp: "27.3" + - pair: + elixir: "1.19.5-otp-27" + otp: "27.3" - pair: - elixir: "1.18.2-otp-27" - otp: "27.2.2" + elixir: "1.20.0-rc.2-otp-28" + otp: "28.4" steps: - uses: actions/checkout@v4 - name: Install erlang and elixir From 9d60373d3179553678bbabebec2be7e812dbf521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Sun, 8 Mar 2026 19:35:57 +0100 Subject: [PATCH 02/13] update min elixir version to 1.18 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 155d7f5..e80f758 100644 --- a/mix.exs +++ b/mix.exs @@ -7,7 +7,7 @@ defmodule PgInspect.MixProject do [ app: :pg_inspect, version: @version, - elixir: "~> 1.17", + elixir: "~> 1.18", start_permanent: Mix.env() == :prod, elixirc_paths: elixirc_paths(Mix.env()), deps: deps(), From 9911879ef808692860992edcccba2ba3fb0bce19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Mon, 9 Mar 2026 20:40:27 +0100 Subject: [PATCH 03/13] upgrade action versions --- .github/workflows/elixir.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index a45bb32..05720bf 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -17,12 +17,12 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Elixir - uses: erlef/setup-beam@5304e04ea2b355f03681464e683d92e3b2f18451 # v1 + uses: erlef/setup-beam@3580539ceec3dc05b0ed51e9e10b08eb7a7c2bb4 with: elixir-version: "1.18" otp-version: "27" - name: Install Protoc - uses: arduino/setup-protoc@f4d5893b897028ff5739576ea0409746887fa536 # v3 + uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b - name: Restore dependencies cache uses: actions/cache@v3 with: @@ -34,11 +34,11 @@ jobs: - name: Run tests run: mix coveralls.json - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de with: token: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results to Codecov if: ${{ !cancelled() }} - uses: codecov/test-results-action@44ecb3a270cd942bdf0fa8f2ce14cb32493e810a # v1 + uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 with: token: ${{ secrets.CODECOV_TOKEN }} From de6ecdb8eb6c6c4af33239c46515bf5c6b97b3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Mon, 9 Mar 2026 22:43:30 +0100 Subject: [PATCH 04/13] add zig --- mise.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/mise.toml b/mise.toml index 7f4763e..553fcc3 100644 --- a/mise.toml +++ b/mise.toml @@ -9,3 +9,4 @@ jq = "latest" rg = "latest" sd = "latest" yq = "latest" +zig = "latest" From 080e2a02831586d7f1ef8c1eb5b1e057304b7d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 12:26:02 +0100 Subject: [PATCH 05/13] mise --- .github/workflows/precompile.yml | 4 ++-- mise.ci.toml | 5 +++++ mise.toml | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 mise.ci.toml diff --git a/.github/workflows/precompile.yml b/.github/workflows/precompile.yml index 6c60af7..1679a71 100644 --- a/.github/workflows/precompile.yml +++ b/.github/workflows/precompile.yml @@ -25,7 +25,7 @@ jobs: elixir: "1.19.5-otp-27" otp: "27.3" - pair: - elixir: "1.20.0-rc.2-otp-28" + elixir: "1.20.0-rc.3-otp-28" otp: "28.4" steps: - uses: actions/checkout@v4 @@ -93,7 +93,7 @@ jobs: elixir: "1.19.5-otp-27" otp: "27.3" - pair: - elixir: "1.20.0-rc.2-otp-28" + elixir: "1.20.0-rc.3-otp-28" otp: "28.4" steps: - uses: actions/checkout@v4 diff --git a/mise.ci.toml b/mise.ci.toml new file mode 100644 index 0000000..5c6130a --- /dev/null +++ b/mise.ci.toml @@ -0,0 +1,5 @@ +[tools] +erlang = "28.4" +elixir = "1.19.5-otp-28" +zig = "0.15.2" +protoc = "latest" diff --git a/mise.toml b/mise.toml index 553fcc3..5f9e95d 100644 --- a/mise.toml +++ b/mise.toml @@ -1,5 +1,6 @@ [tools] -elixir = "1.20.0-rc.2-otp-28" +erlang = "28.4" +elixir = "1.20.0-rc.3-otp-28" ast-grep = "latest" bat = "latest" eza = "latest" @@ -9,4 +10,5 @@ jq = "latest" rg = "latest" sd = "latest" yq = "latest" -zig = "latest" +zig = "0.15.2" +protoc = "latest" From c2947b2691328772379a2d38f50c5bf194b339ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 13:05:09 +0100 Subject: [PATCH 06/13] compile using zig --- .github/workflows/elixir.yml | 18 ++++-- .github/workflows/precompile.yml | 103 ++++++------------------------- Makefile | 15 ++++- mix.exs | 33 ++++++++++ 4 files changed, 78 insertions(+), 91 deletions(-) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 05720bf..2c1380c 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -16,13 +16,19 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Elixir - uses: erlef/setup-beam@3580539ceec3dc05b0ed51e9e10b08eb7a7c2bb4 + - name: Install toolchain + uses: jdx/mise-action@v2 with: - elixir-version: "1.18" - otp-version: "27" - - name: Install Protoc - uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b + mise_toml: | + [tools] + erlang = "27.3" + elixir = "1.18.4-otp-27" + zig = "0.15.2" + protoc = "latest" + - name: Install Hex and Rebar + run: | + mix local.hex --force + mix local.rebar --force - name: Restore dependencies cache uses: actions/cache@v3 with: diff --git a/.github/workflows/precompile.yml b/.github/workflows/precompile.yml index 1679a71..d67f4f3 100644 --- a/.github/workflows/precompile.yml +++ b/.github/workflows/precompile.yml @@ -10,105 +10,42 @@ permissions: contents: write jobs: - linux: - runs-on: ubuntu-latest + precompile: + name: ${{ matrix.runner }} / Elixir ${{ matrix.pair.elixir }} + runs-on: ${{ matrix.runner }} env: MIX_ENV: "prod" strategy: fail-fast: false matrix: - include: - - pair: - elixir: "1.18.4-otp-27" - otp: "27.3" - - pair: - elixir: "1.19.5-otp-27" - otp: "27.3" - - pair: - elixir: "1.20.0-rc.3-otp-28" - otp: "28.4" + runner: [ubuntu-latest, macos-latest] + pair: + - elixir: "1.18.4-otp-27" + otp: "27.3" + - elixir: "1.19.5-otp-27" + otp: "27.3" + - elixir: "1.20.0-rc.3-otp-28" + otp: "28.4" steps: - uses: actions/checkout@v4 - - name: Set up Elixir - uses: erlef/setup-beam@5304e04ea2b355f03681464e683d92e3b2f18451 # v1 - with: - otp-version: ${{matrix.pair.otp}} - elixir-version: ${{matrix.pair.elixir}} - - name: Install Protoc - uses: arduino/setup-protoc@f4d5893b897028ff5739576ea0409746887fa536 # v3 - - name: Restore dependencies cache - uses: actions/cache@v3 - with: - path: deps - key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} - restore-keys: ${{ runner.os }}-mix- - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y build-essential automake autoconf pkg-config bc m4 unzip zip \ - gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - - name: Get musl cross-compilers - run: | - for musl_arch in x86_64 aarch64 riscv64 - do - wget "https://musl.cc/${musl_arch}-linux-musl-cross.tgz" -O "${musl_arch}-linux-musl-cross.tgz" - tar -xf "${musl_arch}-linux-musl-cross.tgz" - done - - name: Run tests - run: | - # Optional, use this if you have musl targets to compile - for musl_arch in x86_64 aarch64 riscv64 - do - export PATH="$(pwd)/${musl_arch}-linux-musl-cross/bin:${PATH}" - done - - mix deps.get - MIX_ENV=test mix test - - name: Create precompiled library - run: | - export ELIXIR_MAKE_CACHE_DIR=$(pwd)/cache - mkdir -p "${ELIXIR_MAKE_CACHE_DIR}" - mix elixir_make.precompile - - uses: softprops/action-gh-release@v1 - if: startsWith(github.ref, 'refs/tags/') - with: - draft: true - files: | - cache/*.tar.gz - - macos: - runs-on: macos-latest - env: - MIX_ENV: "prod" - ELIXIR_VERSION: ${{ matrix.pair.elixir }} - OTP_VERSION: ${{ matrix.pair.otp }} - strategy: - fail-fast: false - matrix: - include: - - pair: - elixir: "1.18.4-otp-27" - otp: "27.3" - - pair: - elixir: "1.19.5-otp-27" - otp: "27.3" - - pair: - elixir: "1.20.0-rc.3-otp-28" - otp: "28.4" - steps: - - uses: actions/checkout@v4 - - name: Install erlang and elixir + - name: Install toolchain uses: jdx/mise-action@v2 with: mise_toml: | [tools] elixir = "${{ matrix.pair.elixir }}" erlang = "${{ matrix.pair.otp }}" - - name: Install utilities + zig = "0.15.2" + protoc = "latest" + - name: Install Hex and Rebar run: | - brew install protobuf mix local.hex --force mix local.rebar --force + - name: Install Linux utilities + if: matrix.runner == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y unzip zip - name: Restore dependencies cache uses: actions/cache@v3 with: diff --git a/Makefile b/Makefile index 304f667..880dc22 100644 --- a/Makefile +++ b/Makefile @@ -7,12 +7,19 @@ LIBPG_QUERY_PATH = libpg_query CFLAGS += -I$(LIBPG_QUERY_PATH) -fPIC +ifdef ZIG_TARGET +CC ?= zig cc -target $(ZIG_TARGET) +endif + +CC ?= cc +LIBPG_QUERY_AR = $(if $(filter zig,$(firstword $(CC))),zig ar rs,ar rs) + LDFLAGS = -lpthread -shared ifeq ($(shell uname -s),Darwin) LDFLAGS += -undefined dynamic_lookup endif -.PHONY: all pg_inspect clean libpg_query_build +.PHONY: all pg_inspect clean precompile_clean libpg_query_build all: priv/pg_inspect.so @@ -20,7 +27,7 @@ priv: mkdir -p priv libpg_query_build: - $(MAKE) -C $(LIBPG_QUERY_PATH) libpg_query.a + $(MAKE) -C $(LIBPG_QUERY_PATH) CC="$(CC)" AR="$(LIBPG_QUERY_AR)" libpg_query.a priv/pg_inspect.so: priv libpg_query_build src/pg_inspect.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ src/pg_inspect.c $(LIBPG_QUERY_PATH)/libpg_query.a @@ -29,3 +36,7 @@ clean: $(MIX) clean $(MAKE) -C $(LIBPG_QUERY_PATH) clean $(RM) priv/pg_inspect.so + +precompile_clean: + $(MAKE) -C $(LIBPG_QUERY_PATH) clean + $(RM) priv/pg_inspect.so diff --git a/mix.exs b/mix.exs index e80f758..18dc07a 100644 --- a/mix.exs +++ b/mix.exs @@ -2,6 +2,12 @@ defmodule PgInspect.MixProject do use Mix.Project @version "0.1.0" + @zig_linux_targets [ + "x86_64-linux-gnu", + "aarch64-linux-gnu", + "x86_64-linux-musl", + "aarch64-linux-musl" + ] def project do [ @@ -17,12 +23,14 @@ defmodule PgInspect.MixProject do compilers: [:elixir_make] ++ Mix.compilers(), make_executable: "make", make_makefile: "Makefile", + make_env: &make_env/0, make_precompiler: {:nif, CCPrecompiler}, make_precompiler_url: "https://github.com/hlindset/pg_inspect/releases/download/v#{@version}/@{artefact_filename}", make_precompiler_priv_paths: ["pg_inspect.*"], make_precompiler_nif_versions: [versions: ["2.16", "2.17"]], make_precompiler_unavailable_target: :compile, + cc_precompiler: cc_precompiler(), # Docs name: "PgInspect", source_url: "https://github.com/hlindset/pg_inspect", @@ -88,6 +96,31 @@ defmodule PgInspect.MixProject do ] end + defp cc_precompiler do + [ + cleanup: "precompile_clean", + compilers: %{ + {:unix, :linux} => + Enum.into(@zig_linux_targets, %{}, fn target -> + {target, + {"zig", "zig", "<%= cc %> cc -target #{target}", "<%= cxx %> c++ -target #{target}"}} + end) + } + ] + end + + defp make_env do + case {os_type(), System.get_env("CC")} do + {{:unix, :linux}, nil} -> + %{"CC" => "zig cc"} + + _ -> + %{} + end + end + + defp os_type, do: :os.type() + # Run "mix help deps" to learn about dependencies. defp deps do [ From 80b69a56b6f8abd8bc9545aa691cab7c07a0d655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 13:16:06 +0100 Subject: [PATCH 07/13] wrap libpg_query calls in mutex --- src/pg_inspect.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/pg_inspect.c b/src/pg_inspect.c index 020a643..0a00117 100644 --- a/src/pg_inspect.c +++ b/src/pg_inspect.c @@ -22,6 +22,28 @@ #define DEBUG_LOG(fmt, ...) #endif +static ErlNifMutex *pg_query_mutex = NULL; + +static int load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) { + (void)env; + (void)priv_data; + (void)load_info; + + pg_query_mutex = enif_mutex_create("pg_inspect_pg_query_mutex"); + + return pg_query_mutex == NULL ? 1 : 0; +} + +static void unload(ErlNifEnv *env, void *priv_data) { + (void)env; + (void)priv_data; + + if (pg_query_mutex != NULL) { + enif_mutex_destroy(pg_query_mutex); + pg_query_mutex = NULL; + } +} + /** * Creates an error tuple of the form {:error, message} * @@ -208,7 +230,9 @@ static ERL_NIF_TERM deparse_protobuf(ErlNifEnv *env, int argc, .data = (char *)input_binary.data}; DEBUG_LOG("Departing protobuf of size %zu", protobuf.len); + enif_mutex_lock(pg_query_mutex); PgQueryDeparseResult result = pg_query_deparse_protobuf(protobuf); + enif_mutex_unlock(pg_query_mutex); if (result.error != NULL) { DEBUG_LOG("Deparse error: %s", result.error->message); @@ -255,7 +279,9 @@ static ERL_NIF_TERM parse_protobuf(ErlNifEnv *env, int argc, // Parse the query DEBUG_LOG("Parsing query of size %zu", query_binary.size); + enif_mutex_lock(pg_query_mutex); PgQueryProtobufParseResult result = pg_query_parse_protobuf(query_str); + enif_mutex_unlock(pg_query_mutex); enif_free(query_str); if (result.error != NULL) { @@ -307,7 +333,9 @@ static ERL_NIF_TERM fingerprint(ErlNifEnv *env, int argc, // Calculate fingerprint DEBUG_LOG("Calculating fingerprint for query of size %zu", query_binary.size); + enif_mutex_lock(pg_query_mutex); PgQueryFingerprintResult result = pg_query_fingerprint(query_str); + enif_mutex_unlock(pg_query_mutex); enif_free(query_str); // Free the query string as we don't need it anymore if (result.error != NULL) { @@ -382,7 +410,9 @@ static ERL_NIF_TERM scan(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { // Scan the query DEBUG_LOG("Scanning query of size %zu", query_binary.size); + enif_mutex_lock(pg_query_mutex); PgQueryScanResult result = pg_query_scan(query_str); + enif_mutex_unlock(pg_query_mutex); enif_free(query_str); // Free the query string as we don't need it anymore if (result.error != NULL) { @@ -433,7 +463,9 @@ static ERL_NIF_TERM normalize(ErlNifEnv *env, int argc, // Normalize the query DEBUG_LOG("Normalizing query of size %zu", query_binary.size); + enif_mutex_lock(pg_query_mutex); PgQueryNormalizeResult result = pg_query_normalize(query_str); + enif_mutex_unlock(pg_query_mutex); enif_free(query_str); if (result.error != NULL) { @@ -477,4 +509,4 @@ static ErlNifFunc funcs[] = { {"fingerprint", 1, fingerprint, ERL_NIF_DIRTY_JOB_CPU_BOUND}, {"normalize", 1, normalize, ERL_NIF_DIRTY_JOB_CPU_BOUND}}; -ERL_NIF_INIT(Elixir.PgInspect.Native, funcs, NULL, NULL, NULL, NULL) +ERL_NIF_INIT(Elixir.PgInspect.Native, funcs, load, NULL, NULL, unload) From a3d4d475c41ac5891d8fbc8b119d87a98c682147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 13:27:16 +0100 Subject: [PATCH 08/13] remove mutex experiment and remove ERL_NIF_DIRTY_JOB_CPU_BOUND flag --- src/pg_inspect.c | 44 ++++++-------------------------------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/src/pg_inspect.c b/src/pg_inspect.c index 0a00117..0690e27 100644 --- a/src/pg_inspect.c +++ b/src/pg_inspect.c @@ -22,28 +22,6 @@ #define DEBUG_LOG(fmt, ...) #endif -static ErlNifMutex *pg_query_mutex = NULL; - -static int load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) { - (void)env; - (void)priv_data; - (void)load_info; - - pg_query_mutex = enif_mutex_create("pg_inspect_pg_query_mutex"); - - return pg_query_mutex == NULL ? 1 : 0; -} - -static void unload(ErlNifEnv *env, void *priv_data) { - (void)env; - (void)priv_data; - - if (pg_query_mutex != NULL) { - enif_mutex_destroy(pg_query_mutex); - pg_query_mutex = NULL; - } -} - /** * Creates an error tuple of the form {:error, message} * @@ -230,9 +208,7 @@ static ERL_NIF_TERM deparse_protobuf(ErlNifEnv *env, int argc, .data = (char *)input_binary.data}; DEBUG_LOG("Departing protobuf of size %zu", protobuf.len); - enif_mutex_lock(pg_query_mutex); PgQueryDeparseResult result = pg_query_deparse_protobuf(protobuf); - enif_mutex_unlock(pg_query_mutex); if (result.error != NULL) { DEBUG_LOG("Deparse error: %s", result.error->message); @@ -279,9 +255,7 @@ static ERL_NIF_TERM parse_protobuf(ErlNifEnv *env, int argc, // Parse the query DEBUG_LOG("Parsing query of size %zu", query_binary.size); - enif_mutex_lock(pg_query_mutex); PgQueryProtobufParseResult result = pg_query_parse_protobuf(query_str); - enif_mutex_unlock(pg_query_mutex); enif_free(query_str); if (result.error != NULL) { @@ -333,9 +307,7 @@ static ERL_NIF_TERM fingerprint(ErlNifEnv *env, int argc, // Calculate fingerprint DEBUG_LOG("Calculating fingerprint for query of size %zu", query_binary.size); - enif_mutex_lock(pg_query_mutex); PgQueryFingerprintResult result = pg_query_fingerprint(query_str); - enif_mutex_unlock(pg_query_mutex); enif_free(query_str); // Free the query string as we don't need it anymore if (result.error != NULL) { @@ -410,9 +382,7 @@ static ERL_NIF_TERM scan(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { // Scan the query DEBUG_LOG("Scanning query of size %zu", query_binary.size); - enif_mutex_lock(pg_query_mutex); PgQueryScanResult result = pg_query_scan(query_str); - enif_mutex_unlock(pg_query_mutex); enif_free(query_str); // Free the query string as we don't need it anymore if (result.error != NULL) { @@ -463,9 +433,7 @@ static ERL_NIF_TERM normalize(ErlNifEnv *env, int argc, // Normalize the query DEBUG_LOG("Normalizing query of size %zu", query_binary.size); - enif_mutex_lock(pg_query_mutex); PgQueryNormalizeResult result = pg_query_normalize(query_str); - enif_mutex_unlock(pg_query_mutex); enif_free(query_str); if (result.error != NULL) { @@ -503,10 +471,10 @@ static ERL_NIF_TERM normalize(ErlNifEnv *env, int argc, * {:ok, result} | {:error, reason} */ static ErlNifFunc funcs[] = { - {"parse_protobuf", 1, parse_protobuf, ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"deparse_protobuf", 1, deparse_protobuf, ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"scan", 1, scan, ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"fingerprint", 1, fingerprint, ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"normalize", 1, normalize, ERL_NIF_DIRTY_JOB_CPU_BOUND}}; + {"parse_protobuf", 1, parse_protobuf}, + {"deparse_protobuf", 1, deparse_protobuf}, + {"scan", 1, scan}, + {"fingerprint", 1, fingerprint}, + {"normalize", 1, normalize}}; -ERL_NIF_INIT(Elixir.PgInspect.Native, funcs, load, NULL, NULL, unload) +ERL_NIF_INIT(Elixir.PgInspect.Native, funcs, NULL, NULL, NULL, NULL) From d14b52955b712af00a1cfd85d0f9cc6a796fca25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 13:40:33 +0100 Subject: [PATCH 09/13] tighten release matrix --- .github/workflows/precompile.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/precompile.yml b/.github/workflows/precompile.yml index d67f4f3..4f2858a 100644 --- a/.github/workflows/precompile.yml +++ b/.github/workflows/precompile.yml @@ -20,11 +20,9 @@ jobs: matrix: runner: [ubuntu-latest, macos-latest] pair: - - elixir: "1.18.4-otp-27" - otp: "27.3" - elixir: "1.19.5-otp-27" otp: "27.3" - - elixir: "1.20.0-rc.3-otp-28" + - elixir: "1.19.5-otp-28" otp: "28.4" steps: - uses: actions/checkout@v4 From 19d9740a9dc94844d1488a7a800ea43bcf11af4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 14:04:23 +0100 Subject: [PATCH 10/13] Simplify precompile release matrix --- .github/workflows/precompile.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/precompile.yml b/.github/workflows/precompile.yml index 4f2858a..55d7742 100644 --- a/.github/workflows/precompile.yml +++ b/.github/workflows/precompile.yml @@ -11,18 +11,19 @@ permissions: jobs: precompile: - name: ${{ matrix.runner }} / Elixir ${{ matrix.pair.elixir }} + name: ${{ matrix.runner }} / Elixir ${{ matrix.elixir }} runs-on: ${{ matrix.runner }} env: MIX_ENV: "prod" strategy: fail-fast: false matrix: - runner: [ubuntu-latest, macos-latest] - pair: - - elixir: "1.19.5-otp-27" - otp: "27.3" - - elixir: "1.19.5-otp-28" + include: + - runner: ubuntu-latest + elixir: "1.19.5-otp-28" + otp: "28.4" + - runner: macos-latest + elixir: "1.19.5-otp-28" otp: "28.4" steps: - uses: actions/checkout@v4 @@ -31,8 +32,8 @@ jobs: with: mise_toml: | [tools] - elixir = "${{ matrix.pair.elixir }}" - erlang = "${{ matrix.pair.otp }}" + elixir = "${{ matrix.elixir }}" + erlang = "${{ matrix.otp }}" zig = "0.15.2" protoc = "latest" - name: Install Hex and Rebar From ef4604708424b13029692e01f5ae7a46b0929f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 14:07:59 +0100 Subject: [PATCH 11/13] Limit published NIF versions to 2.17 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 18dc07a..ee0e6ae 100644 --- a/mix.exs +++ b/mix.exs @@ -28,7 +28,7 @@ defmodule PgInspect.MixProject do make_precompiler_url: "https://github.com/hlindset/pg_inspect/releases/download/v#{@version}/@{artefact_filename}", make_precompiler_priv_paths: ["pg_inspect.*"], - make_precompiler_nif_versions: [versions: ["2.16", "2.17"]], + make_precompiler_nif_versions: [versions: ["2.17"]], make_precompiler_unavailable_target: :compile, cc_precompiler: cc_precompiler(), # Docs From 7ef3b9935069986f080a7808545947805b6055e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 14:20:37 +0100 Subject: [PATCH 12/13] Move Zig compiler default into Makefile --- Makefile | 4 ++-- mix.exs | 13 ------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 880dc22..b581a00 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,9 @@ CFLAGS += -I$(LIBPG_QUERY_PATH) -fPIC ifdef ZIG_TARGET CC ?= zig cc -target $(ZIG_TARGET) +else +CC ?= zig cc endif - -CC ?= cc LIBPG_QUERY_AR = $(if $(filter zig,$(firstword $(CC))),zig ar rs,ar rs) LDFLAGS = -lpthread -shared diff --git a/mix.exs b/mix.exs index ee0e6ae..d36c2db 100644 --- a/mix.exs +++ b/mix.exs @@ -23,7 +23,6 @@ defmodule PgInspect.MixProject do compilers: [:elixir_make] ++ Mix.compilers(), make_executable: "make", make_makefile: "Makefile", - make_env: &make_env/0, make_precompiler: {:nif, CCPrecompiler}, make_precompiler_url: "https://github.com/hlindset/pg_inspect/releases/download/v#{@version}/@{artefact_filename}", @@ -109,18 +108,6 @@ defmodule PgInspect.MixProject do ] end - defp make_env do - case {os_type(), System.get_env("CC")} do - {{:unix, :linux}, nil} -> - %{"CC" => "zig cc"} - - _ -> - %{} - end - end - - defp os_type, do: :os.type() - # Run "mix help deps" to learn about dependencies. defp deps do [ From c770a4db36fe77724dccea7c87e92ed324e6ef0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lindset?= Date: Tue, 10 Mar 2026 14:23:59 +0100 Subject: [PATCH 13/13] remove `precompile-test` from tag triggers --- .github/workflows/precompile.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/precompile.yml b/.github/workflows/precompile.yml index 55d7742..1b1917a 100644 --- a/.github/workflows/precompile.yml +++ b/.github/workflows/precompile.yml @@ -4,7 +4,6 @@ on: push: tags: - "v*.*.*" - - "precompile-test" permissions: contents: write