summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2014-07-22 11:01:03 -0400
committerNoah Misch <noah@leadboat.com>2014-07-22 11:01:51 -0400
commitcec0c2182cec30000fb51710ce5cdf1b0cd7de25 (patch)
tree4e0be0d8f491966c7bb83a1419a8510d91484619 /contrib
parentf54d97c5ef58b436a21373537f85bf5ac8159d8c (diff)
downloadpostgresql-cec0c2182cec30000fb51710ce5cdf1b0cd7de25.tar.gz
Diagnose incompatible OpenLDAP versions during build and test.
With OpenLDAP versions 2.4.24 through 2.4.31, inclusive, PostgreSQL backends can crash at exit. Raise a warning during "configure" based on the compile-time OpenLDAP version number, and test the crash scenario in the dblink test suite. Back-patch to 9.0 (all supported versions).
Diffstat (limited to 'contrib')
-rw-r--r--contrib/dblink/Makefile4
-rw-r--r--contrib/dblink/expected/.gitignore1
-rw-r--r--contrib/dblink/expected/dblink.out27
-rw-r--r--contrib/dblink/input/paths.source14
-rw-r--r--contrib/dblink/output/paths.source11
-rw-r--r--contrib/dblink/pg_service.conf7
-rw-r--r--contrib/dblink/sql/.gitignore1
-rw-r--r--contrib/dblink/sql/dblink.sql28
8 files changed, 92 insertions, 1 deletions
diff --git a/contrib/dblink/Makefile b/contrib/dblink/Makefile
index b84dc2ecd3..5f01ec45fb 100644
--- a/contrib/dblink/Makefile
+++ b/contrib/dblink/Makefile
@@ -9,7 +9,9 @@ SHLIB_PREREQS = submake-libpq
EXTENSION = dblink
DATA = dblink--1.0.sql dblink--unpackaged--1.0.sql
-REGRESS = dblink
+REGRESS = paths dblink
+REGRESS_OPTS = --dlpath=$(top_builddir)/src/test/regress
+EXTRA_CLEAN = sql/paths.sql expected/paths.out
# the db name is hard-coded in the tests
override USE_MODULE_DB =
diff --git a/contrib/dblink/expected/.gitignore b/contrib/dblink/expected/.gitignore
new file mode 100644
index 0000000000..d9c7942c64
--- /dev/null
+++ b/contrib/dblink/expected/.gitignore
@@ -0,0 +1 @@
+/paths.out
diff --git a/contrib/dblink/expected/dblink.out b/contrib/dblink/expected/dblink.out
index 8f07cb06cd..9650fa13af 100644
--- a/contrib/dblink/expected/dblink.out
+++ b/contrib/dblink/expected/dblink.out
@@ -105,6 +105,33 @@ SELECT *
FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
WHERE t.a > 7;
ERROR: connection not available
+-- The first-level connection's backend will crash on exit given OpenLDAP
+-- [2.4.24, 2.4.31]. We won't see evidence of any crash until the victim
+-- process terminates and the postmaster responds. If process termination
+-- entails writing a core dump, that can take awhile. Wait for the process to
+-- vanish. At that point, the postmaster has called waitpid() on the crashed
+-- process, and it will accept no new connections until it has reinitialized
+-- the cluster. (We can't exploit pg_stat_activity, because the crash happens
+-- after the backend updates shared memory to reflect its impending exit.)
+DO $pl$
+DECLARE
+ detail text;
+BEGIN
+ PERFORM wait_pid(crash_pid)
+ FROM dblink('dbname=contrib_regression', $$
+ SELECT pg_backend_pid() FROM dblink(
+ 'service=test_ldap dbname=contrib_regression',
+ -- This string concatenation is a hack to shoehorn a
+ -- set_pgservicefile call into the SQL statement.
+ 'SELECT 1' || set_pgservicefile('pg_service.conf')
+ ) t(c int)
+ $$) AS t(crash_pid int);
+EXCEPTION WHEN OTHERS THEN
+ GET STACKED DIAGNOSTICS detail = PG_EXCEPTION_DETAIL;
+ -- Expected error in a non-LDAP build.
+ IF NOT detail LIKE 'syntax error in service file%' THEN RAISE; END IF;
+END
+$pl$;
-- create a persistent connection
SELECT dblink_connect('dbname=contrib_regression');
dblink_connect
diff --git a/contrib/dblink/input/paths.source b/contrib/dblink/input/paths.source
new file mode 100644
index 0000000000..aab3a3b2bf
--- /dev/null
+++ b/contrib/dblink/input/paths.source
@@ -0,0 +1,14 @@
+-- Initialization that requires path substitution.
+
+CREATE FUNCTION putenv(text)
+ RETURNS void
+ AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv'
+ LANGUAGE C STRICT;
+
+CREATE FUNCTION wait_pid(int)
+ RETURNS void
+ AS '@libdir@/regress@DLSUFFIX@'
+ LANGUAGE C STRICT;
+
+CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
+ AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$;
diff --git a/contrib/dblink/output/paths.source b/contrib/dblink/output/paths.source
new file mode 100644
index 0000000000..e1097f0996
--- /dev/null
+++ b/contrib/dblink/output/paths.source
@@ -0,0 +1,11 @@
+-- Initialization that requires path substitution.
+CREATE FUNCTION putenv(text)
+ RETURNS void
+ AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv'
+ LANGUAGE C STRICT;
+CREATE FUNCTION wait_pid(int)
+ RETURNS void
+ AS '@libdir@/regress@DLSUFFIX@'
+ LANGUAGE C STRICT;
+CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
+ AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$;
diff --git a/contrib/dblink/pg_service.conf b/contrib/dblink/pg_service.conf
new file mode 100644
index 0000000000..92201f0ad4
--- /dev/null
+++ b/contrib/dblink/pg_service.conf
@@ -0,0 +1,7 @@
+# pg_service.conf for minimally exercising libpq use of LDAP.
+
+# Having failed to reach an LDAP server, libpq essentially ignores the
+# "service=test_ldap" in its connection string. Contact the "discard"
+# service; the test works whether or not it answers.
+[test_ldap]
+ldap://127.0.0.1:9/base?attribute?one?filter
diff --git a/contrib/dblink/sql/.gitignore b/contrib/dblink/sql/.gitignore
new file mode 100644
index 0000000000..d17507846d
--- /dev/null
+++ b/contrib/dblink/sql/.gitignore
@@ -0,0 +1 @@
+/paths.sql
diff --git a/contrib/dblink/sql/dblink.sql b/contrib/dblink/sql/dblink.sql
index 245f50e97b..e89e016df7 100644
--- a/contrib/dblink/sql/dblink.sql
+++ b/contrib/dblink/sql/dblink.sql
@@ -65,6 +65,34 @@ SELECT *
FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
WHERE t.a > 7;
+-- The first-level connection's backend will crash on exit given OpenLDAP
+-- [2.4.24, 2.4.31]. We won't see evidence of any crash until the victim
+-- process terminates and the postmaster responds. If process termination
+-- entails writing a core dump, that can take awhile. Wait for the process to
+-- vanish. At that point, the postmaster has called waitpid() on the crashed
+-- process, and it will accept no new connections until it has reinitialized
+-- the cluster. (We can't exploit pg_stat_activity, because the crash happens
+-- after the backend updates shared memory to reflect its impending exit.)
+DO $pl$
+DECLARE
+ detail text;
+BEGIN
+ PERFORM wait_pid(crash_pid)
+ FROM dblink('dbname=contrib_regression', $$
+ SELECT pg_backend_pid() FROM dblink(
+ 'service=test_ldap dbname=contrib_regression',
+ -- This string concatenation is a hack to shoehorn a
+ -- set_pgservicefile call into the SQL statement.
+ 'SELECT 1' || set_pgservicefile('pg_service.conf')
+ ) t(c int)
+ $$) AS t(crash_pid int);
+EXCEPTION WHEN OTHERS THEN
+ GET STACKED DIAGNOSTICS detail = PG_EXCEPTION_DETAIL;
+ -- Expected error in a non-LDAP build.
+ IF NOT detail LIKE 'syntax error in service file%' THEN RAISE; END IF;
+END
+$pl$;
+
-- create a persistent connection
SELECT dblink_connect('dbname=contrib_regression');