From 04f1bea671eb6c285a3eb2f6c45ab2d545866d7f Mon Sep 17 00:00:00 2001 From: riderx Date: Tue, 7 Jul 2026 13:56:03 +0200 Subject: [PATCH] Export pgoutput.so imports from the main wasm module pgoutput.so is loaded at runtime as an emscripten side module, but unlike pgxs-built extensions its undefined symbols were never collected into the exported-functions list. With -sMAIN_MODULE=2, symbols used only by pgoutput (defGetStreamingMode, logicalrep_write_*, publication lookup functions, etc. - 46 in total) were dead-code-eliminated from the main module, so any logical decoding session using pgoutput crashed at the output plugin startup callback with a call to an undefined table entry. Generate a pgoutput.imports file at install time, mirroring the pgxs.mk recipe, so the pglite-exported-functions target keeps those symbols alive. This makes logical replication slots usable in PGlite: SELECT pg_create_logical_replication_slot('slot', 'pgoutput'); SELECT * FROM pg_logical_slot_get_binary_changes('slot', NULL, NULL, 'proto_version', '1', 'publication_names', 'pub'); Fixes electric-sql/pglite#880 Co-Authored-By: Claude Fable 5 --- src/backend/replication/pgoutput/Makefile | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/backend/replication/pgoutput/Makefile b/src/backend/replication/pgoutput/Makefile index d89d317fe7a27..c632e4d6232e1 100644 --- a/src/backend/replication/pgoutput/Makefile +++ b/src/backend/replication/pgoutput/Makefile @@ -24,9 +24,27 @@ include $(top_srcdir)/src/Makefile.shlib install: all installdirs install-lib +ifeq ($(PORTNAME), emscripten) +# pgoutput.so is loaded at runtime as an emscripten side module, but unlike +# pgxs-built extensions it is linked from src/backend, so its imports from the +# core module are not collected automatically. Without this, symbols used only +# by pgoutput (e.g. logicalrep_write_*) are dead-code-eliminated from the main +# module (-sMAIN_MODULE=2) and logical decoding fails at runtime with a call +# to an undefined table entry. Generate the .imports file here so the +# pglite-exported-functions target keeps these symbols alive. +install: install-imports + +.PHONY: install-imports +install-imports: all + $(MKDIR_P) '$(DESTDIR)$(emscripten_extension_imports_dir)' + find . -name "*.o" -exec $(LLVM_NM) --undefined-only {} \; | awk '{print $$2}' | sed '/^$$/d' | sort -u > '$(NAME).undef.txt' + find . -type f \( -name "*.o" -o -name "*.so" \) -exec $(LLVM_NM) --defined-only {} \; | awk '$$2 ~ /^[TDB]$$/ {print $$3}' | sed '/^$$/d' | sort -u > '$(NAME).defs.txt' + comm -23 '$(NAME).undef.txt' '$(NAME).defs.txt' > '$(DESTDIR)$(emscripten_extension_imports_dir)/$(NAME).imports' +endif + installdirs: installdirs-lib uninstall: uninstall-lib clean distclean: clean-lib - rm -f $(OBJS) + rm -f $(OBJS) $(NAME).undef.txt $(NAME).defs.txt