From fb2d0c89fcdf7121b40cdc8e31b8a7bdca73c24a Mon Sep 17 00:00:00 2001 From: tudor Date: Wed, 15 Oct 2025 17:10:11 +0300 Subject: [PATCH 01/21] simplifications --- pglite-wasm/interactive_one.c | 21 --------------------- src/backend/libpq/pqcomm.c | 23 +++++++++++++++++++---- src/backend/tcop/postgres.c | 6 ------ 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/pglite-wasm/interactive_one.c b/pglite-wasm/interactive_one.c index 2c2fa478c43ad..007f54f1f2913 100644 --- a/pglite-wasm/interactive_one.c +++ b/pglite-wasm/interactive_one.c @@ -9,27 +9,6 @@ volatile sigjmp_buf local_sigjmp_buf; // track back how many ex raised in steps of the loop until sucessfull clear_error volatile int canary_ex = 0; -// read FROM JS -// (i guess return number of bytes written) -// ssize_t pglite_read(/* ignored */ int socket, void *buffer, size_t length,/* ignored */ int flags,/* ignored */ void *address,/* ignored */ socklen_t *address_len); -//typedef ssize_t (*pglite_read_t)(/* ignored */ int socket, void *buffer, size_t length,/* ignored */ int flags,/* ignored */ void *address,/* ignored */ unsigned int *address_len); -typedef ssize_t (*pglite_read_t)(void *buffer, size_t max_length); -extern pglite_read_t pglite_read; - -// write TO JS -// (i guess return number of bytes read) -// ssize_t pglite_write(/* ignored */ int sockfd, const void *buf, size_t len, /* ignored */ int flags); -// typedef ssize_t (*pglite_write_t)(/* ignored */ int sockfd, const void *buf, size_t len, /* ignored */ int flags); -typedef ssize_t (*pglite_write_t)(void *buffer, size_t length); -extern pglite_write_t pglite_write; - -__attribute__((export_name("set_read_write_cbs"))) -void -set_read_write_cbs(pglite_read_t read_cb, pglite_write_t write_cb) { - pglite_read = read_cb; - pglite_write = write_cb; -} - extern void AbortTransaction(void); extern void CleanupTransaction(void); extern void ClientAuthentication(Port *port); diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 856e9d2a3623c..56a01904dddfa 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -133,11 +133,26 @@ static int PqRecvLength; /* End of data available in PqRecvBuffer */ volatile int querylen = 0; volatile FILE* queryfp = NULL; +// read FROM JS +// (i guess return number of bytes written) +// ssize_t pglite_read(/* ignored */ int socket, void *buffer, size_t length,/* ignored */ int flags,/* ignored */ void *address,/* ignored */ socklen_t *address_len); +//typedef ssize_t (*pglite_read_t)(/* ignored */ int socket, void *buffer, size_t length,/* ignored */ int flags,/* ignored */ void *address,/* ignored */ unsigned int *address_len); typedef ssize_t (*pglite_read_t)(void *buffer, size_t max_length); -extern pglite_read_t pglite_read; - -typedef ssize_t(*pglite_write_t)(void *buffer, size_t length); -extern pglite_write_t pglite_write; +pglite_read_t pglite_read; + +// write TO JS +// (i guess return number of bytes read) +// ssize_t pglite_write(/* ignored */ int sockfd, const void *buf, size_t len, /* ignored */ int flags); +// typedef ssize_t (*pglite_write_t)(/* ignored */ int sockfd, const void *buf, size_t len, /* ignored */ int flags); +typedef ssize_t (*pglite_write_t)(void *buffer, size_t length); +pglite_write_t pglite_write; + +__attribute__((export_name("set_read_write_cbs"))) +void +set_read_write_cbs(pglite_read_t read_cb, pglite_write_t write_cb) { + pglite_read = read_cb; + pglite_write = write_cb; +} int EMSCRIPTEN_KEEPALIVE fcntl(int __fd, int __cmd, ...) { // dummy diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index bbcf4112aead6..7f6d8f47c5cc2 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -109,12 +109,6 @@ int restrict_nonsystem_relation_kind; #if (defined(__EMSCRIPTEN__) || defined(__wasi__)) bool quote_all_identifiers = false; - -typedef ssize_t (*pglite_read_t)(void *buffer, size_t max_length); -pglite_read_t pglite_read = NULL; - -typedef ssize_t(*pglite_write_t)(void *buffer, size_t length); -pglite_write_t pglite_write = NULL; #endif // WASM From 7444f8516855ad6472c459e19b560265aefd9a0e Mon Sep 17 00:00:00 2001 From: tudor Date: Mon, 20 Oct 2025 17:14:06 +0300 Subject: [PATCH 02/21] progress connecting pg_dump --- .gitignore | 1 + build-pglite.sh | 28 ++++++++---- pglite/includes/pglite-comm.h | 76 ++++++++++++++++++++++++++++++++ src/backend/libpq/be-secure.c | 4 ++ src/backend/libpq/pqcomm.c | 66 --------------------------- src/bin/pg_dump/pg_dump.c | 10 ++++- src/interfaces/libpq/fe-secure.c | 4 ++ 7 files changed, 112 insertions(+), 77 deletions(-) create mode 100644 pglite/includes/pglite-comm.h diff --git a/.gitignore b/.gitignore index 2e67d7c8e6671..f4f898ed7b1a5 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ lib*.pc /dist # emscripten build excludes +*.js *.cjs *.wasm pglite.data diff --git a/build-pglite.sh b/build-pglite.sh index 8fd4b25572087..df9915b0aa640 100755 --- a/build-pglite.sh +++ b/build-pglite.sh @@ -37,9 +37,21 @@ else echo "$CONFIG_STATUS exists and is newer than $REF_FILE. ./configure will NOT be run." fi +# we define here "all" emscripten flags in order to allow native builds (like libpglite) +EXPORTED_RUNTIME_METHODS="addFunction,removeFunction" +PGLITE_EMSCRIPTEN_FLAGS="-sWASM_BIGINT \ +-sSUPPORT_LONGJMP=emscripten \ +-sFORCE_FILESYSTEM=1 \ +-sNO_EXIT_RUNTIME=0 -sENVIRONMENT=node,web,worker \ +-sMAIN_MODULE=2 -sMODULARIZE=1 -sEXPORT_ES6=1 \ +-sEXPORT_NAME=Module -sALLOW_TABLE_GROWTH -sALLOW_MEMORY_GROWTH \ +-sERROR_ON_UNDEFINED_SYMBOLS=0 \ +-sEXPORTED_RUNTIME_METHODS=$EXPORTED_RUNTIME_METHODS \ +-sTOTAL_MEMORY=32MB" + # Step 1: configure the project if [ "$RUN_CONFIGURE" = true ]; then - LDFLAGS="-sWASM_BIGINT -sUSE_PTHREADS=0" CFLAGS="${PGLITE_CFLAGS} -sWASM_BIGINT -fpic -sENVIRONMENT=node,web,worker -sSUPPORT_LONGJMP=emscripten -Wno-declaration-after-statement -Wno-macro-redefined -Wno-unused-function -Wno-missing-prototypes -Wno-incompatible-pointer-types" emconfigure ./configure ac_cv_exeext=.cjs --disable-spinlocks --disable-largefile --without-llvm --without-pam --disable-largefile --with-openssl=no --without-readline --without-icu --with-includes=$INSTALL_PREFIX/include:$INSTALL_PREFIX/include/libxml2 --with-libraries=$INSTALL_PREFIX/lib --with-uuid=ossp --with-zlib --with-libxml --with-libxslt --with-template=emscripten --prefix=$INSTALL_FOLDER || { echo 'error: emconfigure failed' ; exit 11; } + LDFLAGS_EX=$PGLITE_EMSCRIPTEN_FLAGS LDFLAGS="-sWASM_BIGINT -sUSE_PTHREADS=0" CFLAGS="${PGLITE_CFLAGS} -sWASM_BIGINT -fpic -sENVIRONMENT=node,web,worker -sSUPPORT_LONGJMP=emscripten -Wno-declaration-after-statement -Wno-macro-redefined -Wno-unused-function -Wno-missing-prototypes -Wno-incompatible-pointer-types" emconfigure ./configure ac_cv_exeext=.js --host aarch64-unknown-linux-gnu --disable-spinlocks --disable-largefile --without-llvm --without-pam --disable-largefile --with-openssl=no --without-readline --without-icu --with-includes=$INSTALL_PREFIX/include:$INSTALL_PREFIX/include/libxml2:$(pwd)/pglite/includes --with-libraries=$INSTALL_PREFIX/lib --with-uuid=ossp --with-zlib --with-libxml --with-libxslt --with-template=emscripten --prefix=$INSTALL_FOLDER || { echo 'error: emconfigure failed' ; exit 11; } else echo "Warning: configure has not been run because RUN_CONFIGURE=${RUN_CONFIGURE}" fi @@ -55,14 +67,13 @@ emmake make PORTNAME=emscripten -C contrib/ dist || { echo 'error: emmake make P # the above will also create a file with the imports that each extension needs - we pass these as input in the next step for emscripten to keep alive # Step 4: make and dist other extensions -SAVE_PATH=$PATH -PATH=$PATH:$INSTALL_FOLDER/bin -emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite || { echo 'error: emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite' ; exit 41; } -emmake make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist || { echo 'error: make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist ' ; exit 42; } -PATH=$SAVE_PATH +# SAVE_PATH=$PATH +# PATH=$PATH:$INSTALL_FOLDER/bin +# emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite || { echo 'error: emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite' ; exit 41; } +# emmake make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist || { echo 'error: make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist ' ; exit 42; } +# PATH=$SAVE_PATH # Step 5: make and install pglite -# we define here "all" emscripten flags in order to allow native builds (like libpglite) EXPORTED_RUNTIME_METHODS="MEMFS,IDBFS,FS,setValue,getValue,UTF8ToString,stringToNewUTF8,stringToUTF8OnStack,addFunction,removeFunction" PGLITE_EMSCRIPTEN_FLAGS="-sWASM_BIGINT \ -sSUPPORT_LONGJMP=emscripten \ @@ -70,8 +81,7 @@ PGLITE_EMSCRIPTEN_FLAGS="-sWASM_BIGINT \ -sNO_EXIT_RUNTIME=1 -sENVIRONMENT=node,web,worker \ -sMAIN_MODULE=2 -sMODULARIZE=1 -sEXPORT_ES6=1 \ -sEXPORT_NAME=Module -sALLOW_TABLE_GROWTH -sALLOW_MEMORY_GROWTH \ --sERROR_ON_UNDEFINED_SYMBOLS=1 \ +-sERROR_ON_UNDEFINED_SYMBOLS=0 \ -sEXPORTED_RUNTIME_METHODS=$EXPORTED_RUNTIME_METHODS" - # Building pglite itself needs to be the last step because of the PRELOAD_FILES parameter (a list of files and folders) need to be available. PGLITE_CFLAGS="$PGLITE_CFLAGS $PGLITE_EMSCRIPTEN_FLAGS" emmake make PORTNAME=emscripten -j -C src/backend/ install-pglite || { echo 'emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite' ; exit 51; } diff --git a/pglite/includes/pglite-comm.h b/pglite/includes/pglite-comm.h new file mode 100644 index 0000000000000..43ea84173844e --- /dev/null +++ b/pglite/includes/pglite-comm.h @@ -0,0 +1,76 @@ +#if defined(__EMSCRIPTEN__) + +#ifndef PGLITE_COMM_H +#define PGLITE_COMM_H + +#include + +volatile int querylen = 0; +volatile FILE* queryfp = NULL; + +// read FROM JS +// (i guess return number of bytes written) +// ssize_t pglite_read(/* ignored */ int socket, void *buffer, size_t length,/* ignored */ int flags,/* ignored */ void *address,/* ignored */ socklen_t *address_len); +//typedef ssize_t (*pglite_read_t)(/* ignored */ int socket, void *buffer, size_t length,/* ignored */ int flags,/* ignored */ void *address,/* ignored */ unsigned int *address_len); +typedef ssize_t (*pglite_read_t)(void *buffer, size_t max_length); +pglite_read_t pglite_read; + +// write TO JS +// (i guess return number of bytes read) +// ssize_t pglite_write(/* ignored */ int sockfd, const void *buf, size_t len, /* ignored */ int flags); +// typedef ssize_t (*pglite_write_t)(/* ignored */ int sockfd, const void *buf, size_t len, /* ignored */ int flags); +typedef ssize_t (*pglite_write_t)(void *buffer, size_t length); +pglite_write_t pglite_write; + +__attribute__((export_name("set_read_write_cbs"))) +void +set_read_write_cbs(pglite_read_t read_cb, pglite_write_t write_cb) { + pglite_read = read_cb; + pglite_write = write_cb; +} + +int EMSCRIPTEN_KEEPALIVE fcntl(int __fd, int __cmd, ...) { + // dummy + return 0; +} + +int EMSCRIPTEN_KEEPALIVE setsockopt(int __fd, int __level, int __optname, + const void *__optval, socklen_t __optlen) { + // dummy + return 0; +} + +int EMSCRIPTEN_KEEPALIVE getsockopt(int __fd, int __level, int __optname, + void *__restrict __optval, + socklen_t *__restrict __optlen) { + // dummy + return 0; +} + +int EMSCRIPTEN_KEEPALIVE getsockname(int __fd, struct sockaddr * __addr, + socklen_t *__restrict __len) { + // dummy + return 0; + } + +ssize_t EMSCRIPTEN_KEEPALIVE + recv(int __fd, void *__buf, size_t __n, int __flags) { + ssize_t got = pglite_read(__buf, __n); + return got; + } + +ssize_t EMSCRIPTEN_KEEPALIVE + send(int __fd, const void *__buf, size_t __n, int __flags) { + ssize_t wrote = pglite_write(__buf, __n); + return wrote; + } + +int EMSCRIPTEN_KEEPALIVE + connect(int socket, const struct sockaddr *address, socklen_t address_len) { + // dummy + return 0; + } + +#endif + +#endif // ifndef PGLITE_COMM_H \ No newline at end of file diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index 1663f36b6b80d..b2e9260e8b1a6 100644 --- a/src/backend/libpq/be-secure.c +++ b/src/backend/libpq/be-secure.c @@ -32,6 +32,10 @@ #include "tcop/tcopprot.h" #include "utils/wait_event.h" +#if defined(__EMSCRIPTEN__) +#include "pglite-comm.h" +#endif + char *ssl_library; char *ssl_cert_file; char *ssl_key_file; diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 56a01904dddfa..e022fa25082c3 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -80,10 +80,6 @@ #include "utils/guc_hooks.h" #include "utils/memutils.h" -#if defined(__EMSCRIPTEN__) -#include -#endif - /* * Cope with the various platform-specific ways to spell TCP keepalive socket * options. This doesn't cover Windows, which as usual does its own thing. @@ -129,68 +125,6 @@ static size_t PqSendStart; /* Next index to send a byte in PqSendBuffer */ static char PqRecvBuffer[PQ_RECV_BUFFER_SIZE]; static int PqRecvPointer; /* Next index to read a byte from PqRecvBuffer */ static int PqRecvLength; /* End of data available in PqRecvBuffer */ -#if defined(__EMSCRIPTEN__) || defined(__wasi__) -volatile int querylen = 0; -volatile FILE* queryfp = NULL; - -// read FROM JS -// (i guess return number of bytes written) -// ssize_t pglite_read(/* ignored */ int socket, void *buffer, size_t length,/* ignored */ int flags,/* ignored */ void *address,/* ignored */ socklen_t *address_len); -//typedef ssize_t (*pglite_read_t)(/* ignored */ int socket, void *buffer, size_t length,/* ignored */ int flags,/* ignored */ void *address,/* ignored */ unsigned int *address_len); -typedef ssize_t (*pglite_read_t)(void *buffer, size_t max_length); -pglite_read_t pglite_read; - -// write TO JS -// (i guess return number of bytes read) -// ssize_t pglite_write(/* ignored */ int sockfd, const void *buf, size_t len, /* ignored */ int flags); -// typedef ssize_t (*pglite_write_t)(/* ignored */ int sockfd, const void *buf, size_t len, /* ignored */ int flags); -typedef ssize_t (*pglite_write_t)(void *buffer, size_t length); -pglite_write_t pglite_write; - -__attribute__((export_name("set_read_write_cbs"))) -void -set_read_write_cbs(pglite_read_t read_cb, pglite_write_t write_cb) { - pglite_read = read_cb; - pglite_write = write_cb; -} - -int EMSCRIPTEN_KEEPALIVE fcntl(int __fd, int __cmd, ...) { - // dummy - return 0; -} - -int EMSCRIPTEN_KEEPALIVE setsockopt(int __fd, int __level, int __optname, - const void *__optval, socklen_t __optlen) { - // dummy - return 0; -} - -int EMSCRIPTEN_KEEPALIVE getsockopt(int __fd, int __level, int __optname, - void *__restrict __optval, - socklen_t *__restrict __optlen) { - // dummy - return 0; -} - -int EMSCRIPTEN_KEEPALIVE getsockname(int __fd, struct sockaddr * __addr, - socklen_t *__restrict __len) { - // dummy - return 0; - } - -ssize_t EMSCRIPTEN_KEEPALIVE - recv(int __fd, void *__buf, size_t __n, int __flags) { - ssize_t got = pglite_read(__buf, __n); - return got; - } - -ssize_t EMSCRIPTEN_KEEPALIVE - send(int __fd, const void *__buf, size_t __n, int __flags) { - ssize_t wrote = pglite_write(__buf, __n); - return wrote; - } - -#endif /* * Message status diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index acfa76da4e89b..17ca4363a3794 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -93,6 +93,10 @@ int sdk_fd_seek(int fd, int offset,int whence, unsigned long long *retptr) { #endif #endif +#if defined(__EMSCRIPTEN__) +#include +#endif + typedef struct { Oid roleoid; /* role's OID */ @@ -366,8 +370,10 @@ static TableInfo *getRootTableInfo(const TableInfo *tbinfo); static bool forcePartitionRootLoad(const TableInfo *tbinfo); static void read_dump_filters(const char *filename, DumpOptions *dopt); - -int +int +#if defined(__EMSCRIPTEN__) +EMSCRIPTEN_KEEPALIVE +#endif main(int argc, char **argv) { int c; diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index f628082337ebc..7f170f55730db 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -45,6 +45,10 @@ #include "libpq-fe.h" #include "libpq-int.h" +#if defined(__EMSCRIPTEN__) +#include "pglite-comm.h" +#endif + /* * Macros to handle disabling and then restoring the state of SIGPIPE handling. * On Windows, these are all no-ops since there's no SIGPIPEs. From 6e1820b567f53f9df6117af8b968d500c2990fe5 Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 21 Oct 2025 16:27:58 +0300 Subject: [PATCH 03/21] added handling of *.data files (created by emscripten) --- src/bin/pg_dump/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile index cdd9cfcc5de96..a101bf429680c 100644 --- a/src/bin/pg_dump/Makefile +++ b/src/bin/pg_dump/Makefile @@ -59,8 +59,11 @@ install: all installdirs $(INSTALL_PROGRAM) pg_dumpall$(X) '$(DESTDIR)$(bindir)'/pg_dumpall$(X) ifeq ($(PORTNAME), emscripten) $(INSTALL_PROGRAM) pg_dump.wasm '$(DESTDIR)$(bindir)/pg_dump.wasm' + $(INSTALL_PROGRAM) pg_dump.data '$(DESTDIR)$(bindir)/pg_dump.data' $(INSTALL_PROGRAM) pg_restore.wasm '$(DESTDIR)$(bindir)/pg_restore.wasm' + $(INSTALL_PROGRAM) pg_restore.data '$(DESTDIR)$(bindir)/pg_restore.data' $(INSTALL_PROGRAM) pg_dumpall.wasm '$(DESTDIR)$(bindir)/pg_dumpall.wasm' + $(INSTALL_PROGRAM) pg_dumpall.data '$(DESTDIR)$(bindir)/pg_dumpall.data' endif installdirs: @@ -83,4 +86,5 @@ clean distclean: rm -rf tmp_check ifeq ($(PORTNAME), emscripten) rm -f pg_dump.wasm pg_restore.wasm pg_dumpall.wasm + rm -f pg_dump.data pg_restore.data pg_dumpall.data endif \ No newline at end of file From 4075070ebbb92377c2a933fa659cc2175f3c2f51 Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 21 Oct 2025 16:28:57 +0300 Subject: [PATCH 04/21] added poll function as dummy to override libc's implementation. postgresql relies on polling to see if there is data on the socket. --- pglite/includes/pglite-comm.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pglite/includes/pglite-comm.h b/pglite/includes/pglite-comm.h index 43ea84173844e..2a84cbf406d2e 100644 --- a/pglite/includes/pglite-comm.h +++ b/pglite/includes/pglite-comm.h @@ -71,6 +71,18 @@ int EMSCRIPTEN_KEEPALIVE return 0; } +struct pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; + +int EMSCRIPTEN_KEEPALIVE + poll(struct pollfd fds[], ssize_t nfds, int timeout) { + // dummy + return nfds; + } + #endif #endif // ifndef PGLITE_COMM_H \ No newline at end of file From 85ced1482c00fa6164af49441319e4ac71d8e3fa Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 21 Oct 2025 16:30:19 +0300 Subject: [PATCH 05/21] preload .pgpass file for all executables. add FS,MEMFS to exported runtime methods so we can extract files from the sandbox FS (for example wen dumping the db to a file). --- build-pglite.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build-pglite.sh b/build-pglite.sh index df9915b0aa640..dfc2b5ad973d1 100755 --- a/build-pglite.sh +++ b/build-pglite.sh @@ -38,7 +38,7 @@ else fi # we define here "all" emscripten flags in order to allow native builds (like libpglite) -EXPORTED_RUNTIME_METHODS="addFunction,removeFunction" +EXPORTED_RUNTIME_METHODS="addFunction,removeFunction,FS,MEMFS" PGLITE_EMSCRIPTEN_FLAGS="-sWASM_BIGINT \ -sSUPPORT_LONGJMP=emscripten \ -sFORCE_FILESYSTEM=1 \ @@ -47,7 +47,8 @@ PGLITE_EMSCRIPTEN_FLAGS="-sWASM_BIGINT \ -sEXPORT_NAME=Module -sALLOW_TABLE_GROWTH -sALLOW_MEMORY_GROWTH \ -sERROR_ON_UNDEFINED_SYMBOLS=0 \ -sEXPORTED_RUNTIME_METHODS=$EXPORTED_RUNTIME_METHODS \ --sTOTAL_MEMORY=32MB" +-sTOTAL_MEMORY=32MB \ +--preload-file $(pwd)/other/PGPASSFILE@/home/web_user/.pgpass" # Step 1: configure the project if [ "$RUN_CONFIGURE" = true ]; then From 9f97af838c3b3a7ec09ef9e7ab0971f93bf80292 Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 21 Oct 2025 16:30:39 +0300 Subject: [PATCH 06/21] gitignore .data files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f4f898ed7b1a5..2fe9cca6c6519 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ lib*.pc # emscripten build excludes *.js +*.data *.cjs *.wasm pglite.data From 8d428048d5a601d46247770565a45c9d988de69d Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 21 Oct 2025 17:34:29 +0300 Subject: [PATCH 07/21] change pg_config to mjs --- src/bin/pg_config/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bin/pg_config/Makefile b/src/bin/pg_config/Makefile index 3d3c44fa2b4b8..5596731e35fdc 100644 --- a/src/bin/pg_config/Makefile +++ b/src/bin/pg_config/Makefile @@ -34,8 +34,9 @@ pg_config: $(OBJS) | submake-libpgport # the following rule creates a node script that calls the pg_config.cjs/.mjs # pg_config.wasm is implicitly expected to be in the same folder pg_config_sh: pg_config - echo "#!/usr/bin/env node" > pg_config - echo 'require("./pg_config$(X)")' >> pg_config + cp pg_config$(X) pg_config.mjs + echo "#!/bin/sh" > pg_config + echo 'node $(DESTDIR)$(bindir)/pg_config.mjs' >> pg_config chmod +x pg_config install: all installdirs @@ -43,6 +44,7 @@ install: all installdirs ifeq ($(PORTNAME), emscripten) $(INSTALL_PROGRAM) pg_config.wasm '$(DESTDIR)$(bindir)/pg_config.wasm' $(INSTALL_PROGRAM) pg_config '$(DESTDIR)$(bindir)/pg_config' + $(INSTALL_PROGRAM) pg_config.mjs '$(DESTDIR)$(bindir)/pg_config.mjs' endif installdirs: From d5ebc622c893284433c48ee444f673d3c287f596 Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 21 Oct 2025 17:36:58 +0300 Subject: [PATCH 08/21] readd pg_vector pg_ivm --- build-pglite.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build-pglite.sh b/build-pglite.sh index dfc2b5ad973d1..e87e18126fd36 100755 --- a/build-pglite.sh +++ b/build-pglite.sh @@ -68,11 +68,11 @@ emmake make PORTNAME=emscripten -C contrib/ dist || { echo 'error: emmake make P # the above will also create a file with the imports that each extension needs - we pass these as input in the next step for emscripten to keep alive # Step 4: make and dist other extensions -# SAVE_PATH=$PATH -# PATH=$PATH:$INSTALL_FOLDER/bin -# emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite || { echo 'error: emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite' ; exit 41; } -# emmake make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist || { echo 'error: make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist ' ; exit 42; } -# PATH=$SAVE_PATH +SAVE_PATH=$PATH +PATH=$PATH:$INSTALL_FOLDER/bin +emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite || { echo 'error: emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite' ; exit 41; } +emmake make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist || { echo 'error: make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist ' ; exit 42; } +PATH=$SAVE_PATH # Step 5: make and install pglite EXPORTED_RUNTIME_METHODS="MEMFS,IDBFS,FS,setValue,getValue,UTF8ToString,stringToNewUTF8,stringToUTF8OnStack,addFunction,removeFunction" From 348e131950eed37f589c5f73b2e8fa12aaf239da Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 21 Oct 2025 17:37:18 +0300 Subject: [PATCH 09/21] gitignore pg_config.mjs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2fe9cca6c6519..682db69d4d24c 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ lib*.pc *.js *.data *.cjs +pg_config.mjs *.wasm pglite.data pglite.js From 8059f6b7623c7f91780bbfddf486a8b90b59c98e Mon Sep 17 00:00:00 2001 From: tudor Date: Wed, 22 Oct 2025 15:05:32 +0300 Subject: [PATCH 10/21] embed .data files instead of having to deal with the separate files. --- src/bin/pg_dump/Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile index a101bf429680c..cdd9cfcc5de96 100644 --- a/src/bin/pg_dump/Makefile +++ b/src/bin/pg_dump/Makefile @@ -59,11 +59,8 @@ install: all installdirs $(INSTALL_PROGRAM) pg_dumpall$(X) '$(DESTDIR)$(bindir)'/pg_dumpall$(X) ifeq ($(PORTNAME), emscripten) $(INSTALL_PROGRAM) pg_dump.wasm '$(DESTDIR)$(bindir)/pg_dump.wasm' - $(INSTALL_PROGRAM) pg_dump.data '$(DESTDIR)$(bindir)/pg_dump.data' $(INSTALL_PROGRAM) pg_restore.wasm '$(DESTDIR)$(bindir)/pg_restore.wasm' - $(INSTALL_PROGRAM) pg_restore.data '$(DESTDIR)$(bindir)/pg_restore.data' $(INSTALL_PROGRAM) pg_dumpall.wasm '$(DESTDIR)$(bindir)/pg_dumpall.wasm' - $(INSTALL_PROGRAM) pg_dumpall.data '$(DESTDIR)$(bindir)/pg_dumpall.data' endif installdirs: @@ -86,5 +83,4 @@ clean distclean: rm -rf tmp_check ifeq ($(PORTNAME), emscripten) rm -f pg_dump.wasm pg_restore.wasm pg_dumpall.wasm - rm -f pg_dump.data pg_restore.data pg_dumpall.data endif \ No newline at end of file From ca0590bd354350784eee51a7af3d35e4a2d39d2c Mon Sep 17 00:00:00 2001 From: tudor Date: Wed, 22 Oct 2025 15:06:02 +0300 Subject: [PATCH 11/21] script to call ES6 script (previously we we using commonjs) --- src/bin/pg_config/run_pg_config.mjs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/bin/pg_config/run_pg_config.mjs diff --git a/src/bin/pg_config/run_pg_config.mjs b/src/bin/pg_config/run_pg_config.mjs new file mode 100644 index 0000000000000..ae1dd000b1be3 --- /dev/null +++ b/src/bin/pg_config/run_pg_config.mjs @@ -0,0 +1,12 @@ +#!/usr/bin/env node +import Module from "./pg_config.mjs"; + +// If the module has a `main()` (or similar) method, call it: +if (typeof Module.main === "function") { + await Module.main(); +} else if (typeof Module === "function") { + // If it's a callable function/class, instantiate or run it + await Module(); +} else { + console.error("⚠️ Module has no callable entry point"); +} From 9b578841fd0931f1fba4079102d8982ae3d508d6 Mon Sep 17 00:00:00 2001 From: tudor Date: Wed, 22 Oct 2025 15:07:11 +0300 Subject: [PATCH 12/21] pg_config executable now calls run_pg_config.mjs ES6 script --- src/bin/pg_config/Makefile | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/bin/pg_config/Makefile b/src/bin/pg_config/Makefile index 5596731e35fdc..41c0119270d9d 100644 --- a/src/bin/pg_config/Makefile +++ b/src/bin/pg_config/Makefile @@ -21,7 +21,7 @@ OBJS = \ all: ifeq ($(PORTNAME), emscripten) -all: pg_config pg_config_sh +all: pg_config else all: pg_config endif @@ -31,20 +31,16 @@ pg_config: $(OBJS) | submake-libpgport # the emscripten build generates multiple "runnable" files (.cjs/.mjs + .wasm) # but other postgres tools expect exacly 'pg_config' as an executable -# the following rule creates a node script that calls the pg_config.cjs/.mjs +# we create a pg_config link to run_pg_config.mjs, which in turn calls pg_config.cjs/.mjs # pg_config.wasm is implicitly expected to be in the same folder -pg_config_sh: pg_config - cp pg_config$(X) pg_config.mjs - echo "#!/bin/sh" > pg_config - echo 'node $(DESTDIR)$(bindir)/pg_config.mjs' >> pg_config - chmod +x pg_config install: all installdirs $(INSTALL_SCRIPT) pg_config$(X) '$(DESTDIR)$(bindir)/pg_config$(X)' ifeq ($(PORTNAME), emscripten) $(INSTALL_PROGRAM) pg_config.wasm '$(DESTDIR)$(bindir)/pg_config.wasm' - $(INSTALL_PROGRAM) pg_config '$(DESTDIR)$(bindir)/pg_config' - $(INSTALL_PROGRAM) pg_config.mjs '$(DESTDIR)$(bindir)/pg_config.mjs' + $(INSTALL_PROGRAM) pg_config$(X) '$(DESTDIR)$(bindir)/pg_config.mjs' + $(INSTALL_PROGRAM) run_pg_config.mjs '$(DESTDIR)$(bindir)/run_pg_config.mjs' + ln -sf '$(DESTDIR)$(bindir)/run_pg_config.mjs' '$(DESTDIR)$(bindir)/pg_config' endif installdirs: From f06d9c682743f0a2a161c409544ba16e34d4dcd0 Mon Sep 17 00:00:00 2001 From: tudor Date: Wed, 22 Oct 2025 15:10:13 +0300 Subject: [PATCH 13/21] set emscripten specific flags when calling configure - for everything except pglite; embed .pgpass file to avoid having a .data file - for everything except pglite; --- build-pglite.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/build-pglite.sh b/build-pglite.sh index e87e18126fd36..3500a9dc1ebee 100755 --- a/build-pglite.sh +++ b/build-pglite.sh @@ -48,11 +48,14 @@ PGLITE_EMSCRIPTEN_FLAGS="-sWASM_BIGINT \ -sERROR_ON_UNDEFINED_SYMBOLS=0 \ -sEXPORTED_RUNTIME_METHODS=$EXPORTED_RUNTIME_METHODS \ -sTOTAL_MEMORY=32MB \ ---preload-file $(pwd)/other/PGPASSFILE@/home/web_user/.pgpass" +--embed-file $(pwd)/other/PGPASSFILE@/home/web_user/.pgpass" # Step 1: configure the project if [ "$RUN_CONFIGURE" = true ]; then - LDFLAGS_EX=$PGLITE_EMSCRIPTEN_FLAGS LDFLAGS="-sWASM_BIGINT -sUSE_PTHREADS=0" CFLAGS="${PGLITE_CFLAGS} -sWASM_BIGINT -fpic -sENVIRONMENT=node,web,worker -sSUPPORT_LONGJMP=emscripten -Wno-declaration-after-statement -Wno-macro-redefined -Wno-unused-function -Wno-missing-prototypes -Wno-incompatible-pointer-types" emconfigure ./configure ac_cv_exeext=.js --host aarch64-unknown-linux-gnu --disable-spinlocks --disable-largefile --without-llvm --without-pam --disable-largefile --with-openssl=no --without-readline --without-icu --with-includes=$INSTALL_PREFIX/include:$INSTALL_PREFIX/include/libxml2:$(pwd)/pglite/includes --with-libraries=$INSTALL_PREFIX/lib --with-uuid=ossp --with-zlib --with-libxml --with-libxslt --with-template=emscripten --prefix=$INSTALL_FOLDER || { echo 'error: emconfigure failed' ; exit 11; } + LDFLAGS="-sWASM_BIGINT -sUSE_PTHREADS=0" \ + LDFLAGS_SL="-sSIDE_MODULE=1" \ + LDFLAGS_EX=$PGLITE_EMSCRIPTEN_FLAGS \ + CFLAGS="${PGLITE_CFLAGS} -sWASM_BIGINT -fpic -sENVIRONMENT=node,web,worker -sSUPPORT_LONGJMP=emscripten -Wno-declaration-after-statement -Wno-macro-redefined -Wno-unused-function -Wno-missing-prototypes -Wno-incompatible-pointer-types" emconfigure ./configure ac_cv_exeext=.js --host aarch64-unknown-linux-gnu --disable-spinlocks --disable-largefile --without-llvm --without-pam --disable-largefile --with-openssl=no --without-readline --without-icu --with-includes=$INSTALL_PREFIX/include:$INSTALL_PREFIX/include/libxml2:$(pwd)/pglite/includes --with-libraries=$INSTALL_PREFIX/lib --with-uuid=ossp --with-zlib --with-libxml --with-libxslt --with-template=emscripten --prefix=$INSTALL_FOLDER || { echo 'error: emconfigure failed' ; exit 11; } else echo "Warning: configure has not been run because RUN_CONFIGURE=${RUN_CONFIGURE}" fi @@ -62,7 +65,7 @@ emmake make PORTNAME=emscripten -j || { echo 'error: emmake make PORTNAME=emscri emmake make PORTNAME=emscripten install || { echo 'error: emmake make PORTNAME=emscripten install' ; exit 22; } # Step 3.1: make all contrib extensions - do not install -emmake make PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C contrib/ -j || { echo 'error: emmake make PORTNAME=emscripten -C contrib/ -j' ; exit 31; } +emmake make PORTNAME=emscripten -C contrib/ -j || { echo 'error: emmake make PORTNAME=emscripten -C contrib/ -j' ; exit 31; } # Step 3.2: make dist contrib extensions - this will create an archive for each extension emmake make PORTNAME=emscripten -C contrib/ dist || { echo 'error: emmake make PORTNAME=emscripten -C contrib/ dist' ; exit 32; } # the above will also create a file with the imports that each extension needs - we pass these as input in the next step for emscripten to keep alive @@ -71,7 +74,7 @@ emmake make PORTNAME=emscripten -C contrib/ dist || { echo 'error: emmake make P SAVE_PATH=$PATH PATH=$PATH:$INSTALL_FOLDER/bin emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite || { echo 'error: emmake make OPTFLAGS="" PORTNAME=emscripten -j -C pglite' ; exit 41; } -emmake make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist || { echo 'error: make OPTFLAGS="" PORTNAME=emscripten LDFLAGS_SL="-sSIDE_MODULE=1" -C pglite/ dist ' ; exit 42; } +emmake make OPTFLAGS="" PORTNAME=emscripten -C pglite/ dist || { echo 'error: make OPTFLAGS="" PORTNAME=emscripten -C pglite/ dist ' ; exit 42; } PATH=$SAVE_PATH # Step 5: make and install pglite From b9c1299c2ffcbdaec51c92742da85877aec62daa Mon Sep 17 00:00:00 2001 From: tudor Date: Wed, 22 Oct 2025 18:01:33 +0300 Subject: [PATCH 14/21] remove printf --- src/bin/pg_dump/pg_backup_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index f57d971a23c3f..ff89ae75aee4b 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -292,7 +292,7 @@ ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status) ArchiveHandle *AH = (ArchiveHandle *) AHX; PGresult *res; - res = PQexec(AH->connection, query); printf("# 295:" __FILE__ ": PQexec fail == %d q=%s\r\n", PQresultStatus(res) != status, query ); + res = PQexec(AH->connection, query); if (PQresultStatus(res) != status) die_on_query_failure(AH, query); return res; From 9db92a87f7a4dfbb296e9467815785df7ec042ba Mon Sep 17 00:00:00 2001 From: tudor Date: Wed, 29 Oct 2025 16:48:10 +0100 Subject: [PATCH 15/21] more cleanup --- src/bin/pg_dump/pg_dump.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 17ca4363a3794..22699405a2ef6 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -69,30 +69,6 @@ #include "pg_dump.h" #include "storage/block.h" -#if !defined(__wasi__) && !defined(__EMSCRIPTEN__) -extern PGDLLIMPORT bool fe_utils_quote_all_identifiers; -#else -#if defined(WASM) -#ifdef errno - #undef errno - int errno; -#endif - -pid_t fork(void) { - return -1; -} - -# include - -__attribute__((export_name("sdk_fd_seek"))) -int sdk_fd_seek(int fd, int offset,int whence, unsigned long long *retptr) { - puts("sdk_fd_seek called !"); - return __wasi_fd_seek(fd, offset, whence, retptr); -} - -#endif -#endif - #if defined(__EMSCRIPTEN__) #include #endif @@ -859,13 +835,11 @@ main(int argc, char **argv) fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; -puts("# 832:" __FILE__ ": ConnectDatabase\r\n"); /* * Open the database using the Archiver, so it knows about it. Errors mean * death. */ ConnectDatabase(fout, &dopt.cparams, false); -puts("# 838:" __FILE__ ": ConnectDatabase->setup_connection\r\n"); setup_connection(fout, dumpencoding, dumpsnapshot, use_role); /* From 7974e0519e8154dd1b3e6b70456d9e576a811de7 Mon Sep 17 00:00:00 2001 From: tudor Date: Mon, 3 Nov 2025 16:09:38 +0100 Subject: [PATCH 16/21] always send back GUC options even if already reported --- src/backend/utils/misc/guc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 97c44df762fd6..ea076bf59903a 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -2647,6 +2647,7 @@ ReportGUCOption(struct config_generic *record) pq_sendstring(&msgbuf, val); pq_endmessage(&msgbuf); +#ifndef __EMSCRIPTEN__ /* * We need a long-lifespan copy. If guc_strdup() fails due to OOM, * we'll set last_reported to NULL and thereby possibly make a @@ -2654,6 +2655,7 @@ ReportGUCOption(struct config_generic *record) */ guc_free(record->last_reported); record->last_reported = guc_strdup(LOG, val); +#endif } pfree(val); From 8e51fcb9f14b78f81d5ce69714449f48feacc3f4 Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 4 Nov 2025 09:29:07 +0100 Subject: [PATCH 17/21] cleanup wasi/emscripten related code because it is not needed anymore, socket emulation taking care of calls to specific socket functions --- src/interfaces/libpq/fe-connect.c | 35 +------------------------------ 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index f8138e3d490cd..4c81641d3904f 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -2033,7 +2033,6 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, static int connectNoDelay(PGconn *conn) { -#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) #ifdef TCP_NODELAY int on = 1; @@ -2047,7 +2046,6 @@ connectNoDelay(PGconn *conn) SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); return 0; } -#endif #endif return 1; } @@ -2169,9 +2167,6 @@ connectFailureMessage(PGconn *conn, int errorno) static int useKeepalives(PGconn *conn) { -#if defined(__EMSCRIPTEN__) || defined(__wasi__) -return 0; -#else int val; if (conn->keepalives == NULL) @@ -2181,7 +2176,6 @@ return 0; return -1; return val != 0 ? 1 : 0; -#endif } #ifndef WIN32 @@ -2408,14 +2402,12 @@ pqConnectDBStart(PGconn *conn) * Nobody but developers should see this message, so we don't bother * translating it. */ -#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) if (!pg_link_canary_is_frontend()) { appendPQExpBufferStr(&conn->errorMessage, "libpq is incorrectly linked to backend functions\n"); goto connect_errReturn; } -#endif /* Ensure our buffers are empty */ conn->inStart = conn->inCursor = conn->inEnd = 0; conn->outCount = 0; @@ -2501,7 +2493,6 @@ pqConnectDBComplete(PGconn *conn) for (;;) { int ret = 0; -#if !defined(__wasi__) /* * (Re)start the connect_timeout timer if it's active and we are * considering a different host than we were last time through. If @@ -2516,8 +2507,6 @@ pqConnectDBComplete(PGconn *conn) last_whichhost = conn->whichhost; last_whichaddr = conn->whichaddr; } -#endif -printf("# 2519: switch (%d) PGRES_POLLING_OK=%d PGRES_POLLING_READING=%d PGRES_POLLING_WRITING=%d\n", flag, PGRES_POLLING_OK, PGRES_POLLING_READING,PGRES_POLLING_WRITING); if(!flag) abort(); /* * Wait, if necessary. Note that the initial state (just after @@ -2529,7 +2518,6 @@ if(!flag) abort(); return 1; /* success! */ case PGRES_POLLING_READING: -#if !defined(__wasi__) ret = pqWaitTimed(1, 0, conn, end_time); if (ret == -1) { @@ -2537,11 +2525,9 @@ if(!flag) abort(); conn->status = CONNECTION_BAD; return 0; } -#endif break; case PGRES_POLLING_WRITING: -#if !defined(__wasi__) ret = pqWaitTimed(0, 1, conn, end_time); if (ret == -1) { @@ -2549,7 +2535,6 @@ if(!flag) abort(); conn->status = CONNECTION_BAD; return 0; } -#endif break; default: @@ -2637,14 +2622,7 @@ PQconnectPoll(PGconn *conn) case CONNECTION_CHECK_STANDBY: { /* Load waiting data */ -#if defined(__wasi__) - int n = pqReadData(conn); - if (!n) { - sched_yield(); - } -#else -int n = pqReadData(conn); -#endif + int n = pqReadData(conn); if (n < 0) goto error_return; if (n == 0) @@ -3238,7 +3216,6 @@ int n = pqReadData(conn); * Now check (using getsockopt) that there is not an error * state waiting for us on the socket. */ -#if !defined(__wasi__) if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *) &optval, &optlen) == -1) { @@ -3325,10 +3302,6 @@ int n = pqReadData(conn); /* * Make sure we can write before advancing to next step. */ -#else -conn->options_valid = true; -conn->try_next_host = false; -#endif // __wasi__ conn->status = CONNECTION_MADE; return PGRES_POLLING_WRITING; } @@ -3895,12 +3868,6 @@ conn->try_next_host = false; * Note that conn->pghost must be non-NULL if we are going to * avoid the Kerberos code doing a hostname look-up. */ -#if defined(__wasi__) -if (!conn->pghost) { - conn->pgpass = strdup("md532e12f215ba27cb750c9e093ce4b5127"); - conn->pghost = strdup("localhost"); -} -#endif res = pg_fe_sendauth(areq, msgLength, conn); /* OK, we have processed the message; mark data consumed */ From 37e86e1d693c8642c2e84b79134e2a9ec77ecdec Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 4 Nov 2025 11:54:40 +0100 Subject: [PATCH 18/21] cleanup some wasi ifdefs --- pglite-wasm/interactive_one.c | 4 ---- pglite-wasm/pgl_mains.c | 4 ---- pglite-wasm/pgl_sjlj.c | 4 ---- pglite-wasm/pgl_stubs.h | 11 +---------- src/backend/storage/ipc/latch.c | 2 -- src/backend/tcop/postgres.c | 4 ---- 6 files changed, 1 insertion(+), 28 deletions(-) diff --git a/pglite-wasm/interactive_one.c b/pglite-wasm/interactive_one.c index 007f54f1f2913..c520e2d149c74 100644 --- a/pglite-wasm/interactive_one.c +++ b/pglite-wasm/interactive_one.c @@ -1,10 +1,6 @@ #include // access, unlink #define PGL_LOOP -#if defined(__wasi__) -// volatile sigjmp_buf void*; -#else volatile sigjmp_buf local_sigjmp_buf; -#endif // track back how many ex raised in steps of the loop until sucessfull clear_error volatile int canary_ex = 0; diff --git a/pglite-wasm/pgl_mains.c b/pglite-wasm/pgl_mains.c index 7dc200745a4d7..ab20394e07dff 100644 --- a/pglite-wasm/pgl_mains.c +++ b/pglite-wasm/pgl_mains.c @@ -218,13 +218,9 @@ PDEBUG("# 164:" __FILE__); initStringInfo(&row_description_buf); MemoryContextSwitchTo(TopMemoryContext); -#if defined(__wasi__) - puts("# 210: sjlj exception handler off in initdb-wasi"); -#else # define INITDB_SINGLE # include "pgl_sjlj.c" # undef INITDB_SINGLE -#endif // sjlj if (!ignore_till_sync) send_ready_for_query = true; /* initially, or after error */ diff --git a/pglite-wasm/pgl_sjlj.c b/pglite-wasm/pgl_sjlj.c index 469053a2705b2..56bdde5cf9755 100644 --- a/pglite-wasm/pgl_sjlj.c +++ b/pglite-wasm/pgl_sjlj.c @@ -1,6 +1,3 @@ -#if defined(__wasi__) - PDEBUG("# 2:" __FILE__ ": sjlj exception handler off"); -#else if (sigsetjmp(local_sigjmp_buf, 1) != 0) { #if !defined(INITDB_SINGLE) @@ -67,5 +64,4 @@ } PG_exception_stack = &local_sigjmp_buf; -#endif diff --git a/pglite-wasm/pgl_stubs.h b/pglite-wasm/pgl_stubs.h index 5367add820685..9a56a5973712e 100644 --- a/pglite-wasm/pgl_stubs.h +++ b/pglite-wasm/pgl_stubs.h @@ -1,15 +1,6 @@ #pragma once - -// wasi only stubs -#if defined(__wasi__) -# undef PQEXPBUFFER_H -# include "../src/interfaces/libpq/pqexpbuffer.h" - -#else -# include "../src/interfaces/libpq/pqexpbuffer.h" -#endif - +#include "../src/interfaces/libpq/pqexpbuffer.h" // option_parse_int parse_sync_method #include "../src/fe_utils/option_utils.c" diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index aeeab4544693f..2b4ded38893af 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -231,7 +231,6 @@ ResourceOwnerForgetWaitEventSet(ResourceOwner owner, WaitEventSet *set) void InitializeLatchSupport(void) { -#if !defined(__wasi__) #if defined(WAIT_USE_SELF_PIPE) int pipefd[2]; @@ -341,7 +340,6 @@ InitializeLatchSupport(void) /* Ignore SIGURG, because we'll receive it via kqueue. */ pqsignal(SIGURG, SIG_IGN); #endif -#endif /* __wasi__ */ } void diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 7f6d8f47c5cc2..a9bfd973eb12e 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -5140,9 +5140,7 @@ ShowUsage(const char *title) (long) user.tv_usec, (long) sys.tv_sec, (long) sys.tv_usec); -#if !defined(__wasi__) #ifndef WIN32 -#if !defined(__wasi__) /* * The following rusage fields are not defined by POSIX, but they're * present on all current Unix-like systems so we use them without any @@ -5184,9 +5182,7 @@ ShowUsage(const char *title) r.ru_nvcsw - Save_r.ru_nvcsw, r.ru_nivcsw - Save_r.ru_nivcsw, r.ru_nvcsw, r.ru_nivcsw); -#endif /* !__wasi__ */ #endif /* !WIN32 */ -#endif /* remove trailing newline */ if (str.data[str.len - 1] == '\n') str.data[--str.len] = '\0'; From a3c88b36f29e1417749f281215888525d3681d8f Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 4 Nov 2025 12:15:34 +0100 Subject: [PATCH 19/21] cleanup some wasi ifdefs --- src/backend/libpq/be-fsstubs.c | 20 ++++++-------------- src/include/libpq/be-fsstubs.h | 6 ++---- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c index afc579fd20683..27d317dfdc087 100644 --- a/src/backend/libpq/be-fsstubs.c +++ b/src/backend/libpq/be-fsstubs.c @@ -150,12 +150,8 @@ be_lo_close(PG_FUNCTION_ARGS) * *****************************************************************************/ -#if defined(__EMSCRIPTEN__) || defined(__wasi__) -static int -#else int -#endif -lo_read3(int fd, char *buf, int len) +lo_read(int fd, char *buf, int len) { int status; LargeObjectDesc *lobj; @@ -182,12 +178,8 @@ lo_read3(int fd, char *buf, int len) return status; } -#if defined(__EMSCRIPTEN__) || defined(__wasi__) -static int -#else int -#endif -lo_write3(int fd, const char *buf, int len) +lo_write(int fd, const char *buf, int len) { int status; LargeObjectDesc *lobj; @@ -198,7 +190,7 @@ lo_write3(int fd, const char *buf, int len) errmsg("invalid large-object descriptor: %d", fd))); lobj = cookies[fd]; - /* see comment in lo_read3() */ + /* see comment in lo_read() */ if ((lobj->flags & IFS_WRLOCK) == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -373,7 +365,7 @@ be_loread(PG_FUNCTION_ARGS) len = 0; retval = (bytea *) palloc(VARHDRSZ + len); - totalread = lo_read3(fd, VARDATA(retval), len); + totalread = lo_read(fd, VARDATA(retval), len); SET_VARSIZE(retval, totalread + VARHDRSZ); PG_RETURN_BYTEA_P(retval); @@ -390,7 +382,7 @@ be_lowrite(PG_FUNCTION_ARGS) PreventCommandIfReadOnly("lowrite()"); bytestowrite = VARSIZE_ANY_EXHDR(wbuf); - totalwritten = lo_write3(fd, VARDATA_ANY(wbuf), bytestowrite); + totalwritten = lo_write(fd, VARDATA_ANY(wbuf), bytestowrite); PG_RETURN_INT32(totalwritten); } @@ -568,7 +560,7 @@ lo_truncate_internal(int32 fd, int64 len) errmsg("invalid large-object descriptor: %d", fd))); lobj = cookies[fd]; - /* see comment in lo_read3() */ + /* see comment in lo_read() */ if ((lobj->flags & IFS_WRLOCK) == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), diff --git a/src/include/libpq/be-fsstubs.h b/src/include/libpq/be-fsstubs.h index 0d6c7124b5400..336b9cef12508 100644 --- a/src/include/libpq/be-fsstubs.h +++ b/src/include/libpq/be-fsstubs.h @@ -19,10 +19,8 @@ * Probably these should have had the underscore-free names, * but too late now... */ -#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) -extern int lo_read3(int fd, char *buf, int len); -extern int lo_write3(int fd, const char *buf, int len); -#endif +extern int lo_read(int fd, char *buf, int len); +extern int lo_write(int fd, const char *buf, int len); /* * Cleanup LOs at xact commit/abort From 87319827d2df324ba449fd56adfbdaa24c9b7598 Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 4 Nov 2025 12:27:49 +0100 Subject: [PATCH 20/21] more wasi ifdefs cleanup --- src/backend/libpq/auth.c | 4 ++-- src/backend/utils/error/elog.c | 5 ----- src/backend/utils/fmgr/dfmgr.c | 5 +---- src/bin/pg_dump/parallel.c | 4 +--- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 4ae4ed67a3d8b..956d6f294595b 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -1856,7 +1856,7 @@ auth_peer(hbaPort *port) { uid_t uid; gid_t gid; -#if !defined(WIN32) && !defined(__wasi__) +#if !defined(WIN32) struct passwd *pw; int ret; #endif @@ -1875,7 +1875,7 @@ auth_peer(hbaPort *port) return STATUS_ERROR; } -#if !defined(WIN32) && !defined(__wasi__) +#if !defined(WIN32) errno = 0; /* clear errno before call */ pw = getpwuid(uid); if (!pw) diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index f8dc8562571a7..dcd1ea8f050ed 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -543,12 +543,7 @@ errfinish(const char *filename, int lineno, const char *funcname) */ recursion_depth--; -#if defined(__wasi__) - fprintf(stderr, "# 547: PG_RE_THROW(ERROR : %d) ignored\r\n", recursion_depth); - abort(); -#else PG_RE_THROW(); -#endif } /* Emit the message to the right places */ diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index 55c606dc74631..092004dcf3b3f 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -121,15 +121,12 @@ load_external_function(const char *filename, const char *funcname, /* Look up the function within the library. */ retval = dlsym(lib_handle, funcname); -#if !defined(__wasi__) + if (retval == NULL && signalNotFound) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("could not find function \"%s\" in file \"%s\"", funcname, fullname))); -#else - fprintf(stderr, "could not find function \"%s\" in file \"%s\" rv=%p snf=%b\n", funcname, fullname, retval, signalNotFound); -#endif pfree(fullname); return retval; diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c index c1b141a5c32cb..a09247fae47e3 100644 --- a/src/bin/pg_dump/parallel.c +++ b/src/bin/pg_dump/parallel.c @@ -49,7 +49,7 @@ * The pstate->te[] entry for each worker is valid when it's in WRKR_WORKING * state, and must be NULL in other states. */ -#define PG_DUMP_PARALLEL + #include "postgres_fe.h" #ifndef WIN32 @@ -445,7 +445,6 @@ ShutdownWorkersHard(ParallelState *pstate) static void WaitForTerminatingWorkers(ParallelState *pstate) { -#if !defined(__wasi__) while (!HasEveryWorkerTerminated(pstate)) { ParallelSlot *slot = NULL; @@ -505,7 +504,6 @@ WaitForTerminatingWorkers(ParallelState *pstate) slot->workerStatus = WRKR_TERMINATED; pstate->te[j] = NULL; } -#endif /* __wasi__ */ } From 19e5f48b4122a3658c213de7f21be5a200c0c66f Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 4 Nov 2025 16:44:05 +0100 Subject: [PATCH 21/21] cleanup --- src/port/pqsignal.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/port/pqsignal.c b/src/port/pqsignal.c index fa9317bca314d..53cec67123c23 100644 --- a/src/port/pqsignal.c +++ b/src/port/pqsignal.c @@ -174,13 +174,4 @@ pqsignal(int signo, pqsigfunc func) #endif } -/* sneak emsdk or wasi wasm port support into libpgport */ -#if defined(SDK_PORT) -# if defined(__wasi__) -# include "sdk_port-wasi.c" -# endif -# if defined(__EMSCRIPTEN__) -// # include "sdk_port-emscripten.c" -# endif -#endif