check installcheck installcheck-parallel:
    $(MAKE) -C src/test $@
 
+# TODO: add contrib
+$(call recurse,check-world,src/test src/pl src/interfaces/ecpg,check)
+
 $(call recurse,installcheck-world,src/test src/pl src/interfaces/ecpg contrib,installcheck)
 
 GNUmakefile: GNUmakefile.in $(top_builddir)/config.status
    rm -rf $(distdir) $(dummy)
    @echo "Distribution integrity checks out."
 
-.PHONY: dist distdir distcheck docs install-docs world install-world installcheck-world
+.PHONY: dist distdir distcheck docs install-docs world check-world install-world installcheck-world
 
 # GNUmakefile won't exist yet, so we catch that case as well.
 
 
-all check install installdirs installcheck installcheck-parallel uninstall clean distclean maintainer-clean dist distcheck world install-world installcheck-world:
+all check install installdirs installcheck installcheck-parallel uninstall clean distclean maintainer-clean dist distcheck world check-world install-world installcheck-world:
    @if [ ! -f GNUmakefile ] ; then \
       echo "You need to run the 'configure' program first. See the file"; \
       echo "'INSTALL' for installation instructions." ; \
 
 GZIP   = gzip
 BZIP2  = bzip2
 
-PL_TESTDB = pl_regression
-CONTRIB_TESTDB = contrib_regression
-
 # Installation.
 
 INSTALL    = $(SHELL) $(top_srcdir)/config/install-sh -c
 .PHONY: submake-libpq submake-libpgport
 
 
+##########################################################################
+#
+# Testing support
+
+PL_TESTDB = pl_regression
+CONTRIB_TESTDB = contrib_regression
+
+pg_regress_check = $(top_builddir)/src/test/regress/pg_regress --inputdir=$(srcdir) --temp-install=./tmp_check --top-builddir=$(top_builddir)
+pg_regress_installcheck = $(top_builddir)/src/test/regress/pg_regress --inputdir=$(srcdir) --psqldir=$(PSQLDIR)
+
+pg_regress_clean_files = results/ regression.diffs regression.out tmp_check/ log/
+
+
 ##########################################################################
 #
 # Customization
 
 endif
 ifdef REGRESS
 # things created by various check targets
-   rm -rf results tmp_check log
-   rm -f regression.diffs regression.out regress.out run_check.out
+   rm -rf $(pg_regress_clean_files)
 ifeq ($(PORTNAME), win)
    rm -f regress.def
 endif
 
 # against installed postmaster
 installcheck: submake
-   $(top_builddir)/src/test/regress/pg_regress --inputdir=$(srcdir) --psqldir=$(PSQLDIR) $(REGRESS_OPTS) $(REGRESS)
+   $(pg_regress_installcheck) $(REGRESS_OPTS) $(REGRESS)
 
 # in-tree test doesn't work yet (no way to install my shared library)
 #check: all submake
-#  $(top_builddir)/src/test/regress/pg_regress --temp-install \
-#    --top-builddir=$(top_builddir) $(REGRESS_OPTS) $(REGRESS)
+#  $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS)
 check:
    @echo "'make check' is not supported."
    @echo "Do 'make install', then 'make installcheck' instead."
 
 /plperl_opmask.h
 
 # Generated subdirectories
+/log/
 /results/
+/tmp_check/
 
 
 uninstall: uninstall-lib
 
+check: submake
+   $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS)
+
 installcheck: submake
-   $(top_builddir)/src/test/regress/pg_regress --inputdir=$(srcdir) --psqldir=$(PSQLDIR) $(REGRESS_OPTS) $(REGRESS)
+   $(pg_regress_installcheck) $(REGRESS_OPTS) $(REGRESS)
 
 .PHONY: submake
 submake:
 
 clean distclean maintainer-clean: clean-lib
    rm -f SPI.c Util.c $(OBJS) perlchunks.h plperl_opmask.h
-   rm -rf results
-   rm -f regression.diffs regression.out
+   rm -rf $(pg_regress_clean_files)
 
 else # can't build
 
 
 # Generated subdirectories
+/log/
 /results/
+/tmp_check/
 
 clean3:
    rm -rf python3/
 
+check: submake prep3
+   $(pg_regress_check) --inputdir=./python3 --outputdir=./python3 $(REGRESS_OPTS) $(REGRESS)
+
 installcheck: submake prep3
-   $(top_builddir)/src/test/regress/pg_regress --inputdir=./python3 --outputdir=./python3 --psqldir=$(PSQLDIR) $(REGRESS_OPTS) $(REGRESS)
+   $(pg_regress_installcheck) --inputdir=./python3 --outputdir=./python3 $(REGRESS_OPTS) $(REGRESS)
 
 clean: clean3
 else
+check: submake
+   $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS)
+
 installcheck: submake
-   $(top_builddir)/src/test/regress/pg_regress --inputdir=$(srcdir) --psqldir=$(PSQLDIR) $(REGRESS_OPTS) $(REGRESS)
+   $(pg_regress_installcheck) $(REGRESS_OPTS) $(REGRESS)
 endif
 
 .PHONY: submake
 
 clean distclean maintainer-clean: clean-lib
    rm -f $(OBJS)
-   rm -rf results
-   rm -f regression.diffs regression.out
+   rm -rf $(pg_regress_clean_files)
 ifeq ($(PORTNAME), win32)
    rm -f python${pytverstr}.def
 endif
 
 # Generated subdirectories
+/log/
 /results/
+/tmp_check/
 
 uninstall: uninstall-lib
    $(MAKE) -C modules $@
 
+check: submake
+   $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS)
+
 installcheck: submake
-   $(top_builddir)/src/test/regress/pg_regress --inputdir=$(srcdir) --psqldir=$(PSQLDIR) $(REGRESS_OPTS) $(REGRESS)
+   $(pg_regress_installcheck) $(REGRESS_OPTS) $(REGRESS)
 
 .PHONY: submake
 submake:
 
 clean distclean maintainer-clean: clean-lib
    rm -f $(OBJS)
-   rm -rf results
-   rm -f regression.diffs regression.out
+   rm -rf $(pg_regress_clean_files)
    $(MAKE) -C modules $@
 
 ## Run tests
 ##
 
-pg_regress_call = ./pg_regress --inputdir=$(srcdir) --dlpath=. $(if $(MULTIBYTE),--multibyte=$(MULTIBYTE)) $(NOLOCALE)
+REGRESS_OPTS = --dlpath=. $(if $(MULTIBYTE),--multibyte=$(MULTIBYTE)) $(NOLOCALE)
 
 check: all tablespace-setup
-   $(pg_regress_call) --temp-install=./tmp_check --top-builddir=$(top_builddir) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(TEMP_CONF) $(EXTRA_TESTS)
+   $(pg_regress_check) $(REGRESS_OPTS) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(TEMP_CONF) $(EXTRA_TESTS)
 
 installcheck: all tablespace-setup
-   $(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule $(EXTRA_TESTS)
+   $(pg_regress_installcheck) $(REGRESS_OPTS) --schedule=$(srcdir)/serial_schedule $(EXTRA_TESTS)
 
 installcheck-parallel: all tablespace-setup
-   $(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(EXTRA_TESTS)
+   $(pg_regress_installcheck) $(REGRESS_OPTS) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(EXTRA_TESTS)
 
 standbycheck: all
-   $(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/standby_schedule --use-existing
+   $(pg_regress_installcheck) $(REGRESS_OPTS) --schedule=$(srcdir)/standby_schedule --use-existing
 
 # old interfaces follow...
 
 runtest-parallel: installcheck-parallel
 
 bigtest: all tablespace-setup
-   $(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule numeric_big
+   $(pg_regress_installcheck) $(REGRESS_OPTS) --schedule=$(srcdir)/serial_schedule numeric_big
 
 bigcheck: all tablespace-setup
-   $(pg_regress_call) --temp-install=./tmp_check --top-builddir=$(top_builddir) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) numeric_big
+   $(pg_regress_check) $(REGRESS_OPTS) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) numeric_big
 
 
 ##
 # things created by various check targets
    rm -f $(output_files) $(input_files)
    rm -rf testtablespace
-   rm -rf results tmp_check log
-   rm -f regression.diffs regression.out regress.out run_check.out
+   rm -rf $(pg_regress_clean_files)
 
        /* "make install" */
 #ifndef WIN32_ONLY_COMPILER
        snprintf(buf, sizeof(buf),
-                SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install with_perl=no with_python=no > \"%s/log/install.log\" 2>&1" SYSTEMQUOTE,
+                SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install > \"%s/log/install.log\" 2>&1" SYSTEMQUOTE,
                 makeprog, top_builddir, temp_install, outputdir);
 #else
        snprintf(buf, sizeof(buf),