*** a/contrib/dblink/Makefile --- b/contrib/dblink/Makefile *************** *** 20,22 **** top_builddir = ../.. --- 20,27 ---- include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif + + ifeq ($(PORTNAME), win32) + override PG_CPPFLAGS := -I$(libpqbe_srcdir) $(PG_CPPFLAGS) + override SHLIB_LINK := $(libpqbe) $(SHLIB_LINK) + endif *** a/contrib/dblink/dblink.c --- b/contrib/dblink/dblink.c *************** *** 67,72 **** --- 67,76 ---- #include "dblink.h" + #ifdef WIN32 + #include "port/win32/libpqbe.h" + #endif + PG_MODULE_MAGIC; typedef struct remoteConn *** a/src/Makefile --- b/src/Makefile *************** *** 21,26 **** all install installdirs uninstall distprep: --- 21,27 ---- $(MAKE) -C backend/snowball $@ $(MAKE) -C include $@ $(MAKE) -C interfaces $@ + $(MAKE) -C backend/port/win32/libpqbe $@ $(MAKE) -C backend/replication/libpqwalreceiver $@ $(MAKE) -C bin $@ $(MAKE) -C pl $@ *************** *** 52,57 **** clean: --- 53,59 ---- $(MAKE) -C backend/snowball $@ $(MAKE) -C include $@ $(MAKE) -C interfaces $@ + $(MAKE) -C backend/port/win32/libpqbe $@ $(MAKE) -C backend/replication/libpqwalreceiver $@ $(MAKE) -C bin $@ $(MAKE) -C pl $@ *************** *** 67,72 **** distclean maintainer-clean: --- 69,75 ---- $(MAKE) -C backend/snowball $@ $(MAKE) -C include $@ $(MAKE) -C interfaces $@ + $(MAKE) -C backend/port/win32/libpqbe $@ $(MAKE) -C backend/replication/libpqwalreceiver $@ $(MAKE) -C bin $@ $(MAKE) -C pl $@ *************** *** 82,87 **** coverage: --- 85,91 ---- $(MAKE) -C backend/utils/mb/conversion_procs $@ $(MAKE) -C backend/snowball $@ $(MAKE) -C interfaces $@ + $(MAKE) -C backend/port/win32/libpqbe $@ $(MAKE) -C backend/replication/libpqwalreceiver $@ $(MAKE) -C bin $@ $(MAKE) -C pl $@ *** a/src/Makefile.global.in --- b/src/Makefile.global.in *************** *** 395,400 **** else --- 395,411 ---- libpq_pgport = -L$(top_builddir)/src/port -lpgport $(libpq) endif + # This macro is for use by backend libraries that use libpq. + ifdef PGXS + libpqbe_srcdir = $(includedir) + libpqbe_builddir = $(libdir) + libpqbe = -L$(libdir) -lpqbe $(libpq) + else + libpqbe_srcdir = $(top_srcdir)/src/include/port/win32 + libpqbe_builddir = $(top_builddir)/src/backend/port/win32/libpqbe + libpqbe = -L$(libpqbe_builddir) -lpqbe $(libpq) + endif + submake-libpq: $(MAKE) -C $(libpq_builddir) all *************** *** 402,408 **** submake-libpq: submake-libpgport: $(MAKE) -C $(top_builddir)/src/port all ! .PHONY: submake-libpq submake-libpgport ########################################################################## --- 413,422 ---- submake-libpgport: $(MAKE) -C $(top_builddir)/src/port all ! submake-libpqbe: submake-libpq ! $(MAKE) -C $(libpqbe_builddir) all ! ! .PHONY: submake-libpq submake-libpgport submake-libpqbe ########################################################################## *** /dev/null --- b/src/backend/port/win32/libpqbe/Makefile *************** *** 0 **** --- 1,36 ---- + #------------------------------------------------------------------------- + # + # Makefile-- + # Makefile for src/backend/port/win32/libpqbe + # + # IDENTIFICATION + # $PostgreSQL$ + # + #------------------------------------------------------------------------- + + subdir = src/backend/port/win32/libpqbe + top_builddir = ../../../../.. + include $(top_builddir)/src/Makefile.global + + override CPPFLAGS := -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS) + + OBJS = libpqbe.o + SHLIB_LINK = $(libpq) + NAME = libpqbe + + SHLIB_EXPORTS = exports.txt + + ifeq ($(PORTNAME),win32) + all: submake-libpq all-shared-lib + + include $(top_srcdir)/src/Makefile.shlib + + install: all installdirs install-lib + + installdirs: installdirs-lib + + uninstall: uninstall-lib + + clean distclean maintainer-clean: clean-lib + rm -f $(OBJS) + endif *** /dev/null --- b/src/backend/port/win32/libpqbe/exports.txt *************** *** 0 **** --- 1,3 ---- + # $PostgreSQL$ + # Functions to be exported by libpqbe DLL + pgwin32_PQexec 1 *** /dev/null --- b/src/backend/port/win32/libpqbe/libpqbe.c *************** *** 0 **** --- 1,102 ---- + /*------------------------------------------------------------------------- + * + * libpqbe.c + * functions related to sending a query from the backend + * + * Portions Copyright (c) 2010-2010, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * $PostgreSQL$ + * + *------------------------------------------------------------------------- + */ + #include "postgres.h" + + #include "libpq-fe.h" + #include "port/win32/libpqbe.h" + + /* + * Send a query and wait for the results by using the asynchronous libpq + * functions and the backend version of select(). + * + * On Windows, dblink and walreceiver must use this function instead of + * the blocking libpq functions like PQexec() since they use the vanilla + * select() and are uninterruptible by our emulated signals. On the other + * hand, this function is interruptible since it uses the signal emulation + * layer compatible select(). + */ + PGresult * + pgwin32_PQexec(PGconn *conn, const char *query) + { + PGresult *result = NULL; + PGresult *lastResult = NULL; + + /* + * Submit a query. Since we don't use non-blocking mode, this also + * can block. But its risk is relatively small, so we ignore that + * for now. + */ + if (!PQsendQuery(conn, query)) + return NULL; + + for (;;) + { + /* + * Receive data until PQgetResult has been ready to get the + * result without blocking. + */ + while (PQisBusy(conn)) + { + int ret; + int sock = PQsocket(conn); + fd_set input_mask; + + if (sock < 0) + ereport(ERROR, + (errcode_for_socket_access(), + errmsg("socket not open"))); + + FD_ZERO(&input_mask); + FD_SET (sock, &input_mask); + + ret = select(sock + 1, &input_mask, NULL, NULL, NULL); + if (ret == 0 || (ret < 0 && errno == EINTR)) + continue; /* interrupted */ + if (ret < 0) + ereport(ERROR, + (errcode_for_socket_access(), + errmsg("select() failed: %m"))); + if (PQconsumeInput(conn) == 0) + return NULL; + } + + /* + * Emulate the PQexec()'s behavior of returning the last result, + * if there's many. + * + * We don't try to concatenate error messages like PQexec() does. + * Doesn't seem worth the effort. + */ + if ((result = PQgetResult(conn)) == NULL) + break; /* query is complete */ + if (lastResult) + { + if (PQresultStatus(lastResult) == PGRES_FATAL_ERROR && + PQresultStatus(result) == PGRES_FATAL_ERROR) + { + PQclear(result); + result = lastResult; + } + else + PQclear(lastResult); + } + lastResult = result; + if (PQresultStatus(result) == PGRES_COPY_IN || + PQresultStatus(result) == PGRES_COPY_OUT || + PQstatus(conn) == CONNECTION_BAD) + break; + } + + return lastResult; + } *** a/src/backend/replication/libpqwalreceiver/Makefile --- b/src/backend/replication/libpqwalreceiver/Makefile *************** *** 15,24 **** include $(top_builddir)/src/Makefile.global override CPPFLAGS := -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS) OBJS = libpqwalreceiver.o SHLIB_LINK = $(libpq) NAME = libpqwalreceiver ! all: submake-libpq all-shared-lib include $(top_srcdir)/src/Makefile.shlib --- 15,33 ---- override CPPFLAGS := -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS) OBJS = libpqwalreceiver.o + ifeq ($(PORTNAME), win32) + override CPPFLAGS := -I$(libpqbe_srcdir) $(CPPFLAGS) + SHLIB_LINK = $(libpqbe) + else SHLIB_LINK = $(libpq) + endif NAME = libpqwalreceiver ! ifeq ($(PORTNAME), win32) ! all: submake-libpqbe all-shared-lib ! else ! all: submake-libpq all-shared-lib ! endif include $(top_srcdir)/src/Makefile.shlib *** a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c --- b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c *************** *** 25,30 **** --- 25,34 ---- #include "replication/walreceiver.h" #include "utils/builtins.h" + #ifdef WIN32 + #include "port/win32/libpqbe.h" + #endif + #ifdef HAVE_POLL_H #include #endif *** /dev/null --- b/src/include/port/win32/libpqbe.h *************** *** 0 **** --- 1,23 ---- + /*------------------------------------------------------------------------- + * + * libpqbe.h + * functions related to sending a query from the backend + * + * Portions Copyright (c) 2010-2010, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * $PostgreSQL$ + * + *------------------------------------------------------------------------- + */ + + #ifndef LIBPQBE_H + #define LIBPQBE_H + + #include "libpq-fe.h" + + #define PQexec(conn, query) pgwin32_PQexec(conn, query) + PGresult *pgwin32_PQexec(PGconn *conn, const char *query); + + #endif /* LIBPQBE_H */