pg_regress inputdir

Started by Jorgen Austvik - Sun Norwayover 17 years ago17 messages
#1Jorgen Austvik - Sun Norway
Jorgen.Austvik@Sun.COM
1 attachment(s)

Hi,

with regards to --inputdir, --srcdir, --outputdir and --schedule,
pg_regress does something like this:

convert files in <srcdir>/input, and place them in ./sql
convert files in <srcdir>/output, and place them in ./expected
read schedule from <schedule>
for each test in schedule:
read test from <inputdir>/sql/<testname>.sql
read expected result from <inputdir>/expected/<testname>.out
write results to <outputdir>/results/<testname>.out

My problem when running pg_regress standalone, is that converted files
are written to e.g. ./sql, but read from e.g. <inputdir>/sql, which
makes the --inputdir parameter pretty unusable if it is set to something
different from some path leading to cwd.

Illustrated with code:

Writing converted source file (pg_regress.s:493):
snprintf(destfile, MAXPGPATH, "%s/%s.%s", dest, prefix, suffix);

(Where dest is "sql" or "expected".)

Reading files (pg_regress_main.c:37+38):
snprintf(infile, sizeof(infile), "%s/sql/%s.sql", inputdir, testname);

The attached patch makes pg_regress write converted files to
<inputdir>/sql and <inputdir>/expected, which is one way to make it read
and write to the same directory. Tested on Solaris x86 with pgsql "make
check" and standalone.

-J
--

J�rgen Austvik, Software Engineering - QA
Sun Microsystems Database Group

http://blogs.sun.com/austvik/
http://www.austvik.net/

Attachments:

pg_regress-inputdir.patchtext/x-patch; name=pg_regress-inputdir.patchDownload
Index: src/test/regress/pg_regress.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/pg_regress.c,v
retrieving revision 1.45
diff -u -r1.45 pg_regress.c
--- src/test/regress/pg_regress.c	17 May 2008 20:02:01 -0000	1.45
+++ src/test/regress/pg_regress.c	29 Jul 2008 12:36:38 -0000
@@ -490,7 +490,7 @@
 		/* build the full actual paths to open */
 		snprintf(prefix, strlen(*name) - 6, "%s", *name);
 		snprintf(srcfile, MAXPGPATH, "%s/%s", indir, *name);
-		snprintf(destfile, MAXPGPATH, "%s/%s.%s", dest, prefix, suffix);
+		snprintf(destfile, MAXPGPATH, "%s/%s/%s.%s", inputdir, dest, prefix, suffix);
 
 		infile = fopen(srcfile, "r");
 		if (!infile)
#2Alvaro Herrera
alvherre@commandprompt.com
In reply to: Jorgen Austvik - Sun Norway (#1)
Re: pg_regress inputdir

Jorgen Austvik - Sun Norway wrote:

The attached patch makes pg_regress write converted files to
<inputdir>/sql and <inputdir>/expected, which is one way to make it read
and write to the same directory. Tested on Solaris x86 with pgsql "make
check" and standalone.

I think this breaks VPATH builds in both letter and spirit. Why do you
need this anyway?

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

#3Jorgen Austvik - Sun Norway
Jorgen.Austvik@Sun.COM
In reply to: Alvaro Herrera (#2)
Re: pg_regress inputdir

Alvaro Herrera wrote:

Jorgen Austvik - Sun Norway wrote:

The attached patch makes pg_regress write converted files to
<inputdir>/sql and <inputdir>/expected, which is one way to make it read
and write to the same directory. Tested on Solaris x86 with pgsql "make
check" and standalone.

I think this breaks VPATH builds in both letter and spirit.

Letter:

--------8<---------------8<---------------8<---------------8<---------------8<---------------8<-------
bash-3.2$ ggrep -R "\-\-inputdir" *
src/test/regress/pg_regress.c: printf(_(" --inputdir=DIR
take input files from DIR (default \".\")\n"));
Binary file src/test/regress/pg_regress.o matches
Binary file src/test/regress/pg_regress matches
Binary file
src/test/regress/tmp_check/install/usr/local/pgsql/lib/pgxs/src/test/regress/pg_regress
matches
--------8<---------------8<---------------8<---------------8<---------------8<---------------8<-------

Since it is not used in PostgreSQL build (only default value - "."), I
have problems seeing how writing to e.g. "./sql/file" instead of writing
to "sql/file" could break anything. Please explain.

Spirit:

Nobody has ever accuse me of being spiritual ;-), but if you have a URI
that explains the VPATH spirit, I'd be interested to read about it.

Why do you need this anyway?

I tried to explain that in the first mail, but let me try again.

Use case:
Running pg_regress outside of PostgreSQL build system. pg_regress is
installed in e.g. /usr/postgres/8.3/bin/, "input", "output", "sql" and
"expected" are installed in some other path, e.g.
/usr/postgres/8.3/share/test. User is in ~ and tries to run the
PostgreSQL regression tests. It doesn't work, in fact the only way to
make it work is to cd to the parent directory of "sql" and "expected".

Today, using --inputdir in pg_regress does not work for any other value
than something that resolves to cwd, since it will write a file to
"./sql", but try to read the same file from "<inputdir>/sql".

-J
--

J�rgen Austvik, Software Engineering - QA
Sun Microsystems Database Group

http://blogs.sun.com/austvik/
http://www.austvik.net/

#4Alvaro Herrera
alvherre@commandprompt.com
In reply to: Jorgen Austvik - Sun Norway (#3)
Re: pg_regress inputdir

Jorgen Austvik - Sun Norway wrote:

Alvaro Herrera wrote:

I think this breaks VPATH builds in both letter and spirit.

Letter:

--------8<---------------8<---------------8<---------------8<---------------8<---------------8<-------
bash-3.2$ ggrep -R "\-\-inputdir" *
src/test/regress/pg_regress.c: printf(_(" --inputdir=DIR take input
files from DIR (default \".\")\n"));
Binary file src/test/regress/pg_regress.o matches
Binary file src/test/regress/pg_regress matches
Binary file
src/test/regress/tmp_check/install/usr/local/pgsql/lib/pgxs/src/test/regress/pg_regress
matches
--------8<---------------8<---------------8<---------------8<---------------8<---------------8<-------

Since it is not used in PostgreSQL build (only default value - "."), I
have problems seeing how writing to e.g. "./sql/file" instead of writing
to "sql/file" could break anything. Please explain.

Well, that's exactly my point -- because in a normal build, it is only
passed as . but in a VPATH dir it is passed as the source dir (relative
or absolute path as when you invoked configure).

Spirit:

Nobody has ever accuse me of being spiritual ;-), but if you have a URI
that explains the VPATH spirit, I'd be interested to read about it.

The VPATH spirit is that generated files should reside in the build
directory, not in the source directory. Try creating an empty directory
somewhere, cd'ing to that, and calling /path/to/pgsqlsource/configure.
In the resulting dir try "make installcheck" and see what is passed as
--inputdir.

Hmm ... maybe I spoke too soon; I don't see --inputdir used anywhere.

Why do you need this anyway?

I tried to explain that in the first mail, but let me try again.

Use case:
Running pg_regress outside of PostgreSQL build system. pg_regress is
installed in e.g. /usr/postgres/8.3/bin/, "input", "output", "sql" and
"expected" are installed in some other path, e.g.
/usr/postgres/8.3/share/test. User is in ~ and tries to run the
PostgreSQL regression tests. It doesn't work, in fact the only way to
make it work is to cd to the parent directory of "sql" and "expected".

Today, using --inputdir in pg_regress does not work for any other value
than something that resolves to cwd, since it will write a file to
"./sql", but try to read the same file from "<inputdir>/sql".

Maybe I'm missing something, but I don't see any reason why this is a
scenario worth supporting. What's the problem with cd'ing into the
directory containing the tests?

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#5Jorgen Austvik - Sun Norway
Jorgen.Austvik@Sun.COM
In reply to: Alvaro Herrera (#4)
Re: pg_regress inputdir

Alvaro Herrera wrote:

Today, using --inputdir in pg_regress does not work for any other value
than something that resolves to cwd, since it will write a file to
"./sql", but try to read the same file from "<inputdir>/sql".

Maybe I'm missing something, but I don't see any reason why this is a
scenario worth supporting. What's the problem with cd'ing into the
directory containing the tests?

I agree - cd or some symlinks to cover up that the --inputdir parameter
does not work if you set it to anything except the default is a workaround.

Do we also agree that if you set --inputdir to anything other than the
default, pg_regress will not work (will write a file to one folder, and
try to read the same file from another)?

And if we agree above - should we make setting --inputdir work (read and
write from/to same directory), remove the --inputdir parameter (since
setting it to anything different from default value doesn't work), or
keep it there (to confuse people)?

-J
--

J�rgen Austvik, Software Engineering - QA
Sun Microsystems Database Group

#6Alvaro Herrera
alvherre@commandprompt.com
In reply to: Jorgen Austvik - Sun Norway (#5)
Re: pg_regress inputdir

Jorgen Austvik - Sun Norway wrote:

Do we also agree that if you set --inputdir to anything other than the
default, pg_regress will not work (will write a file to one folder, and
try to read the same file from another)?

And if we agree above - should we make setting --inputdir work (read and
write from/to same directory), remove the --inputdir parameter (since
setting it to anything different from default value doesn't work), or
keep it there (to confuse people)?

I think the problem here is that you have to set --outputdir too.

$ LC_ALL=C /pgsql/build/00head/src/test/regress/pg_regress --inputdir=/pgsql/source/00head/src/test/regress --outputdir=/pgsql/build/00head/src/test/regress timetz
(using postmaster on Unix socket, port 55432)
============== dropping database "regression" ==============
DROP DATABASE
============== creating database "regression" ==============
CREATE DATABASE
ALTER DATABASE
============== running regression test queries ==============
test timetz ... ok

=====================
All 1 tests passed.
=====================

Note that this is a VPATH build, so the input and output dirs are
different.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#7Alvaro Herrera
alvherre@commandprompt.com
In reply to: Alvaro Herrera (#6)
Re: pg_regress inputdir

Alvaro Herrera wrote:

Jorgen Austvik - Sun Norway wrote:

Do we also agree that if you set --inputdir to anything other than the
default, pg_regress will not work (will write a file to one folder, and
try to read the same file from another)?

And if we agree above - should we make setting --inputdir work (read and
write from/to same directory), remove the --inputdir parameter (since
setting it to anything different from default value doesn't work), or
keep it there (to confuse people)?

I think the problem here is that you have to set --outputdir too.

Huh, scratch that, I chose a bad test. create_function_2 obviously fails as
you say:

$ LC_ALL=C /pgsql/build/00head/src/test/regress/pg_regress --inputdir=/pgsql/source/00head/src/test/regress --srcdir=/pgsql/source/00head/src/test/regress/ create_function_2
(using postmaster on Unix socket, port 55432)
============== dropping database "regression" ==============
DROP DATABASE
============== creating database "regression" ==============
CREATE DATABASE
ALTER DATABASE
============== running regression test queries ==============
test create_function_2 ... /bin/sh: /pgsql/source/00head/src/test/regress/sql/create_function_2.sql: No such file or directory
diff: /pgsql/source/00head/src/test/regress/expected/create_function_2.out: No such file or directory
diff: ./results/create_function_2.out: No such file or directory
diff command failed with status 512: diff -w "/pgsql/source/00head/src/test/regress/expected/create_function_2.out" "./results/create_function_2.out" > "./results/create_function_2.out.diff"

I'm not sure if the problem here is --inputdir or --srcdir, or the fact
that we fail to provide a --builddir switch. In my opinion, the need
for running tests outside the test dir is not very strong (or we would
have heard complaints before), and thus the solution is to remove
--inputdir and --outputdir.

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

#8Jorgen Austvik - Sun Norway
Jorgen.Austvik@Sun.COM
In reply to: Alvaro Herrera (#7)
1 attachment(s)
Re: pg_regress inputdir

Alvaro Herrera wrote:

In my opinion, the need
for running tests outside the test dir is not very strong (or we would
have heard complaints before), and thus the solution is to remove
--inputdir and --outputdir.

Attached is a patch that removes --inputdir and --outputdir. I still
prefere the first patch (that fixed my problem), but removing them is
probably better than having them when they don't work.

Tested with psql make check on solaris x86.

-J
--

J�rgen Austvik, Software Engineering - QA
Sun Microsystems Database Group

Attachments:

pg_regress_remove_inoutdir.patchtext/x-patch; name=pg_regress_remove_inoutdir.patchDownload
Index: src/test/regress/pg_regress_main.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/pg_regress_main.c,v
retrieving revision 1.3
diff -u -r1.3 pg_regress_main.c
--- src/test/regress/pg_regress_main.c	1 Jan 2008 19:46:00 -0000	1.3
+++ src/test/regress/pg_regress_main.c	4 Aug 2008 11:19:04 -0000
@@ -34,12 +34,9 @@
 	char		expectfile[MAXPGPATH];
 	char		psql_cmd[MAXPGPATH * 3];
 
-	snprintf(infile, sizeof(infile), "%s/sql/%s.sql",
-			 inputdir, testname);
-	snprintf(outfile, sizeof(outfile), "%s/results/%s.out",
-			 outputdir, testname);
-	snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out",
-			 inputdir, testname);
+	snprintf(infile, sizeof(infile), "sql/%s.sql", testname);
+	snprintf(outfile, sizeof(outfile), "results/%s.out", testname);
+	snprintf(expectfile, sizeof(expectfile), "expected/%s.out", testname);
 
 	add_stringlist_item(resultfiles, outfile);
 	add_stringlist_item(expectfiles, expectfile);
Index: src/test/regress/pg_regress.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/pg_regress.c,v
retrieving revision 1.46
diff -u -r1.46 pg_regress.c
--- src/test/regress/pg_regress.c	3 Aug 2008 05:12:38 -0000	1.46
+++ src/test/regress/pg_regress.c	4 Aug 2008 11:19:04 -0000
@@ -32,6 +32,9 @@
 #include "getopt_long.h"
 #include "pg_config_paths.h"
 
+#define LOG_DIRECTORY "log"
+#define RESULTS_DIRECTORY "results"
+
 /* for resultmap we need a list of pairs of strings */
 typedef struct _resultmap
 {
@@ -68,8 +71,6 @@
 /* options settable from command line */
 _stringlist *dblist = NULL;
 bool		debug = false;
-char	   *inputdir = ".";
-char	   *outputdir = ".";
 char	   *psqldir = NULL;
 static _stringlist *loadlanguage = NULL;
 static int	max_connections = 0;
@@ -560,8 +561,7 @@
 	FILE	   *f;
 
 	/* scan the file ... */
-	snprintf(buf, sizeof(buf), "%s/resultmap", inputdir);
-	f = fopen(buf, "r");
+	f = fopen("resultmap", "r");
 	if (!f)
 	{
 		/* OK if it doesn't exist, else complain */
@@ -1702,8 +1702,7 @@
 	FILE	   *difffile;
 
 	/* create the log file (copy of running status output) */
-	snprintf(file, sizeof(file), "%s/regression.out", outputdir);
-	logfilename = strdup(file);
+	logfilename = "regression.out";
 	logfile = fopen(logfilename, "w");
 	if (!logfile)
 	{
@@ -1713,8 +1712,7 @@
 	}
 
 	/* create the diffs file as empty */
-	snprintf(file, sizeof(file), "%s/regression.diffs", outputdir);
-	difffilename = strdup(file);
+	difffilename = "regression.diffs";
 	difffile = fopen(difffilename, "w");
 	if (!difffile)
 	{
@@ -1726,9 +1724,8 @@
 	fclose(difffile);
 
 	/* also create the output directory if not present */
-	snprintf(file, sizeof(file), "%s/results", outputdir);
-	if (!directory_exists(file))
-		make_directory(file);
+	if (!directory_exists(RESULTS_DIRECTORY))
+		make_directory(RESULTS_DIRECTORY);
 }
 
 static void
@@ -1799,14 +1796,12 @@
 	printf(_("Options:\n"));
 	printf(_("  --dbname=DB               use database DB (default \"regression\")\n"));
 	printf(_("  --debug                   turn on debug mode in programs that are run\n"));
-	printf(_("  --inputdir=DIR            take input files from DIR (default \".\")\n"));
 	printf(_("  --load-language=lang      load the named language before running the\n"));
 	printf(_("                            tests; can appear multiple times\n"));
 	printf(_("  --create-role=ROLE        create the specified role before testing\n"));
 	printf(_("  --max-connections=N       maximum number of concurrent connections\n"));
 	printf(_("                            (default is 0 meaning unlimited)\n"));
 	printf(_("  --multibyte=ENCODING      use ENCODING as the multibyte encoding\n"));
-	printf(_("  --outputdir=DIR           place output files in DIR (default \".\")\n"));
 	printf(_("  --schedule=FILE           use test ordering schedule from FILE\n"));
 	printf(_("                            (can be used multiple times to concatenate)\n"));
 	printf(_("  --srcdir=DIR              absolute path to source directory (for VPATH builds)\n"));
@@ -1844,11 +1839,9 @@
 		{"version", no_argument, NULL, 'V'},
 		{"dbname", required_argument, NULL, 1},
 		{"debug", no_argument, NULL, 2},
-		{"inputdir", required_argument, NULL, 3},
 		{"load-language", required_argument, NULL, 4},
 		{"max-connections", required_argument, NULL, 5},
 		{"multibyte", required_argument, NULL, 6},
-		{"outputdir", required_argument, NULL, 7},
 		{"schedule", required_argument, NULL, 8},
 		{"temp-install", required_argument, NULL, 9},
 		{"no-locale", no_argument, NULL, 10},
@@ -1900,9 +1893,6 @@
 			case 2:
 				debug = true;
 				break;
-			case 3:
-				inputdir = strdup(optarg);
-				break;
 			case 4:
 				add_stringlist_item(&loadlanguage, optarg);
 				break;
@@ -1912,9 +1902,6 @@
 			case 6:
 				encoding = strdup(optarg);
 				break;
-			case 7:
-				outputdir = strdup(optarg);
-				break;
 			case 8:
 				add_stringlist_item(&schedulelist, optarg);
 				break;
@@ -2028,37 +2015,37 @@
 		make_directory(temp_install);
 
 		/* and a directory for log files */
-		snprintf(buf, sizeof(buf), "%s/log", outputdir);
-		if (!directory_exists(buf))
-			make_directory(buf);
+		if (!directory_exists(LOG_DIRECTORY))
+			make_directory(LOG_DIRECTORY);
 
 		/* "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,
-				 makeprog, top_builddir, temp_install, outputdir);
+				 SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install with_perl=no with_python=no > \"%s/install.log\" 2>&1" SYSTEMQUOTE,
+				 makeprog, top_builddir, temp_install, LOG_DIRECTORY);
 #else
 		snprintf(buf, sizeof(buf),
-				 SYSTEMQUOTE "perl \"%s/src/tools/msvc/install.pl\" \"%s/install\" >\"%s/log/install.log\" 2>&1" SYSTEMQUOTE,
-				 top_builddir, temp_install, outputdir);
+				 SYSTEMQUOTE "perl \"%s/src/tools/msvc/install.pl\" \"%s/install\" >\"%s/install.log\" 2>&1" SYSTEMQUOTE,
+				 top_builddir, temp_install, LOG_DIRECTORY);
 #endif
 		if (system(buf))
 		{
-			fprintf(stderr, _("\n%s: installation failed\nExamine %s/log/install.log for the reason.\nCommand was: %s\n"), progname, outputdir, buf);
+			fprintf(stderr, _("\n%s: installation failed\nExamine %s/install.log for the reason.\nCommand was: %s\n"), progname, LOG_DIRECTORY, buf);
 			exit_nicely(2);
 		}
 
 		/* initdb */
 		header(_("initializing database system"));
 		snprintf(buf, sizeof(buf),
-				 SYSTEMQUOTE "\"%s/initdb\" -D \"%s/data\" -L \"%s\" --noclean%s%s > \"%s/log/initdb.log\" 2>&1" SYSTEMQUOTE,
+				 SYSTEMQUOTE "\"%s/initdb\" -D \"%s/data\" -L \"%s\" --noclean%s%s > \"%s/initdb.log\" 2>&1" SYSTEMQUOTE,
 				 bindir, temp_install, datadir,
 				 debug ? " --debug" : "",
 				 nolocale ? " --no-locale" : "",
-				 outputdir);
+				 LOG_DIRECTORY
+                                );
 		if (system(buf))
 		{
-			fprintf(stderr, _("\n%s: initdb failed\nExamine %s/log/initdb.log for the reason.\nCommand was: %s\n"), progname, outputdir, buf);
+			fprintf(stderr, _("\n%s: initdb failed\nExamine %s/initdb.log for the reason.\nCommand was: %s\n"), progname, LOG_DIRECTORY, buf);
 			exit_nicely(2);
 		}
 
@@ -2093,11 +2080,11 @@
 		 */
 		header(_("starting postmaster"));
 		snprintf(buf, sizeof(buf),
-				 SYSTEMQUOTE "\"%s/postgres\" -D \"%s/data\" -F%s -c \"listen_addresses=%s\" > \"%s/log/postmaster.log\" 2>&1" SYSTEMQUOTE,
+				 SYSTEMQUOTE "\"%s/postgres\" -D \"%s/data\" -F%s -c \"listen_addresses=%s\" > \"%s/postmaster.log\" 2>&1" SYSTEMQUOTE,
 				 bindir, temp_install,
 				 debug ? " -d 5" : "",
 				 hostname ? hostname : "",
-				 outputdir);
+				 LOG_DIRECTORY);
 		postmaster_pid = spawn_process(buf);
 		if (postmaster_pid == INVALID_PID)
 		{
@@ -2129,7 +2116,7 @@
 			if (WaitForSingleObject(postmaster_pid, 0) == WAIT_OBJECT_0)
 #endif
 			{
-				fprintf(stderr, _("\n%s: postmaster failed\nExamine %s/log/postmaster.log for the reason\n"), progname, outputdir);
+				fprintf(stderr, _("\n%s: postmaster failed\nExamine %s/postmaster.log for the reason\n"), progname, LOG_DIRECTORY);
 				exit_nicely(2);
 			}
 
@@ -2137,7 +2124,7 @@
 		}
 		if (i >= 60)
 		{
-			fprintf(stderr, _("\n%s: postmaster did not respond within 60 seconds\nExamine %s/log/postmaster.log for the reason\n"), progname, outputdir);
+			fprintf(stderr, _("\n%s: postmaster did not respond within 60 seconds\nExamine %s/postmaster.log for the reason\n"), progname, LOG_DIRECTORY);
 
 			/*
 			 * If we get here, the postmaster is probably wedged somewhere in
#9Peter Eisentraut
peter_e@gmx.net
In reply to: Jorgen Austvik - Sun Norway (#8)
Re: pg_regress inputdir

Jorgen Austvik - Sun Norway wrote:

Alvaro Herrera wrote:

In my opinion, the need
for running tests outside the test dir is not very strong (or we would
have heard complaints before), and thus the solution is to remove
--inputdir and --outputdir.

Attached is a patch that removes --inputdir and --outputdir. I still
prefere the first patch (that fixed my problem), but removing them is
probably better than having them when they don't work.

There is interest among packagers to run the regression tests or other
tests after the build. The Red Hat RPMs have shipped a postgresql-test
package for years with a hacked-up makefile that will probably overwrite
random files that it shouldn't in /usr/lib. So I would rather be in
favor of coming up with a solution that would make this work rather than
removing the options. The solution would probably be adding another
option to place the generated files, but the exact behavior would need
to be worked out.

#10Alvaro Herrera
alvherre@commandprompt.com
In reply to: Peter Eisentraut (#9)
Re: pg_regress inputdir

Peter Eisentraut wrote:

There is interest among packagers to run the regression tests or other
tests after the build. The Red Hat RPMs have shipped a postgresql-test
package for years with a hacked-up makefile that will probably overwrite
random files that it shouldn't in /usr/lib. So I would rather be in
favor of coming up with a solution that would make this work rather than
removing the options. The solution would probably be adding another
option to place the generated files, but the exact behavior would need
to be worked out.

Hmm. I took a look at the RPM makefiles and patches, and it doesn't
seem like changing this part of pg_regress would solve anything. The
RPM changes are about shared libraries, whereas this is just about
moving the generated files (equivalent to those in the "sql" directory).

For an example of the hacked-up makefiles and stuff, see here:
https://projects.commandprompt.com/public/pgcore/browser/rpm/redhat/8.3/postgresql/F-9/

The relevant files are Makefile.regress, postgresql-test.patch, and
postgresql-8.3.spec (lines 440ff).

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#10)
Re: pg_regress inputdir

Alvaro Herrera <alvherre@commandprompt.com> writes:

Peter Eisentraut wrote:

There is interest among packagers to run the regression tests or other
tests after the build. The Red Hat RPMs have shipped a postgresql-test
package for years with a hacked-up makefile that will probably overwrite
random files that it shouldn't in /usr/lib. So I would rather be in
favor of coming up with a solution that would make this work rather than
removing the options. The solution would probably be adding another
option to place the generated files, but the exact behavior would need
to be worked out.

Hmm. I took a look at the RPM makefiles and patches, and it doesn't
seem like changing this part of pg_regress would solve anything.

Well, it would be interesting if it were possible for an unprivileged
user to run postgresql-test. That would mean arranging for the tests to
not write anything in the regression source directory, but only in some
user-private directory; ie, keeping the modifiable and non-modifiable
files separate. Which I think is what Peter is getting at above.

However, at least for Red Hat I don't think I could use such a feature
if I had it :-(. You'll note that Makefile.regress has to fool around
with SELinux labeling, which I think isn't possible for any old random
user. That's not something that could be avoided if we had a pg_regress
that was careful about modifiable vs non-modifiable files, because the
restriction is actually enforced against the installed postgresql
binaries.

regards, tom lane

#12Alvaro Herrera
alvherre@commandprompt.com
In reply to: Jorgen Austvik - Sun Norway (#1)
Re: pg_regress inputdir

Jorgen Austvik - Sun Norway wrote:

The attached patch makes pg_regress write converted files to
<inputdir>/sql and <inputdir>/expected, which is one way to make it read
and write to the same directory. Tested on Solaris x86 with pgsql "make
check" and standalone.

Okay, so this patch does change it in a way that it still works, but
what else do you need to be able to run the test from another directory?
I tried to run the test from another directory with this patch
installed, and found that it didn't work because it's replacing
@abs_builddir@ in the input files improperly (to the current path; it
should be using the output dir path, I think)

So maybe this is a step in the right direction, but ISTM you need a
slightly larger patch for it to be actually useful.

If I am not making sense, then maybe I am not understanding what you
mean by running it standalone. In that case, please explain.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#13Peter Eisentraut
peter_e@gmx.net
In reply to: Alvaro Herrera (#12)
Re: pg_regress inputdir

Alvaro Herrera wrote:

Jorgen Austvik - Sun Norway wrote:

The attached patch makes pg_regress write converted files to
<inputdir>/sql and <inputdir>/expected, which is one way to make it read
and write to the same directory. Tested on Solaris x86 with pgsql "make
check" and standalone.

Okay, so this patch does change it in a way that it still works, but
what else do you need to be able to run the test from another directory?
I tried to run the test from another directory with this patch
installed, and found that it didn't work because it's replacing
@abs_builddir@ in the input files improperly (to the current path; it
should be using the output dir path, I think)

So maybe this is a step in the right direction, but ISTM you need a
slightly larger patch for it to be actually useful.

If I am not making sense, then maybe I am not understanding what you
mean by running it standalone. In that case, please explain.

I think the appropriate interface would be adding another option to
pg_regress called --workdir or --tempdir, which defaults to PWD, and
write the converted sql files there, and then look for the sql files to
execute in workdir/sql and in inputdir/sql. In some way, this copies
the vpath search mechanism.

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#13)
Re: pg_regress inputdir

Peter Eisentraut <peter_e@gmx.net> writes:

Alvaro Herrera wrote:

I tried to run the test from another directory with this patch
installed, and found that it didn't work because it's replacing
@abs_builddir@ in the input files improperly (to the current path; it
should be using the output dir path, I think)

I think the appropriate interface would be adding another option to
pg_regress called --workdir or --tempdir, which defaults to PWD, and
write the converted sql files there, and then look for the sql files to
execute in workdir/sql and in inputdir/sql. In some way, this copies
the vpath search mechanism.

That would be required to make pg_regress run as far as its own
facilities are concerned. But I think Alvaro is worried about something
at a higher level: the regression test process as a whole has some
directory layout assumptions built into it, particularly in regards
to where to find .so's. If we don't have a workable solution for that
it's not really going to help to change pg_regress like this.

regards, tom lane

#15Alvaro Herrera
alvherre@commandprompt.com
In reply to: Tom Lane (#14)
Re: pg_regress inputdir

Tom Lane wrote:

Peter Eisentraut <peter_e@gmx.net> writes:

I think the appropriate interface would be adding another option to
pg_regress called --workdir or --tempdir, which defaults to PWD, and
write the converted sql files there, and then look for the sql files to
execute in workdir/sql and in inputdir/sql. In some way, this copies
the vpath search mechanism.

That would be required to make pg_regress run as far as its own
facilities are concerned. But I think Alvaro is worried about something
at a higher level: the regression test process as a whole has some
directory layout assumptions built into it, particularly in regards
to where to find .so's. If we don't have a workable solution for that
it's not really going to help to change pg_regress like this.

Maybe the same work dir can be used as a place to store the shared
objects. I think all it'd require is to change @abs_builddir@ to point
to workdir.

That should work fine as long as nobody attempts to put the workdir in
some mount point that's marked noexec (which is somewhat common with
/tmp)

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#16Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#14)
Re: pg_regress inputdir

Tom Lane wrote:

But I think Alvaro is worried about something
at a higher level: the regression test process as a whole has some
directory layout assumptions built into it, particularly in regards
to where to find .so's.

The only information about the location of the .so's is in the test
files themselves, which seems reasonable, because they are created and
installed at the same time as the .so's that they are presumably
supposed to test. So I see no problem here.

#17Peter Eisentraut
peter_e@gmx.net
In reply to: Peter Eisentraut (#16)
1 attachment(s)
Re: pg_regress inputdir

Peter Eisentraut wrote:

Tom Lane wrote:

But I think Alvaro is worried about something
at a higher level: the regression test process as a whole has some
directory layout assumptions built into it, particularly in regards
to where to find .so's.

The only information about the location of the .so's is in the test
files themselves, which seems reasonable, because they are created and
installed at the same time as the .so's that they are presumably
supposed to test. So I see no problem here.

Here is a more involved patch that fixes all these issues. The major
simplication is that the input files are looked for in both the build
tree and the source tree (like a vpath search), which allowed me to
remove a lot of redundant makefile code. I could also remove the
--srcdir option but added --dlpath to address the above mentioned issue
and changed some option defaults. Now you can run pg_regress inside and
outside of the build tree. It isn't quite ready for the general public,
but a packager that wants to adopt this can use it. Currently, you need
to create the directories sql, expected, and testtablespace yourself,
when running outside the build tree. We can attempt to sort that out
later, but SELinux might make it difficult.

Attachments:

pgregress.difftext/plain; name=pgregress.diff; x-mac-creator=0; x-mac-type=0Download
diff -cr -x TAGS ../cvs-pgsql/src/makefiles/pgxs.mk ./src/makefiles/pgxs.mk
*** ../cvs-pgsql/src/makefiles/pgxs.mk	2008-04-07 17:15:58.000000000 +0300
--- ./src/makefiles/pgxs.mk	2008-09-22 20:40:39.000000000 +0300
***************
*** 232,254 ****
  # where to find psql for running the tests
  PSQLDIR = $(bindir)
  
- # When doing a VPATH build, must copy over the test .sql and .out
- # files so that the driver script can find them.  We have to use an
- # absolute path for the targets, because otherwise make will try to
- # locate the missing files using VPATH, and will find them in
- # $(srcdir), but the point here is that we want to copy them from
- # $(srcdir) to the build directory.
- 
- ifdef VPATH
- abs_builddir := $(shell pwd)
- test_files_src := $(wildcard $(srcdir)/sql/*.sql) $(wildcard $(srcdir)/expected/*.out) $(wildcard $(srcdir)/data/*.data)
- test_files_build := $(patsubst $(srcdir)/%, $(abs_builddir)/%, $(test_files_src))
- 
- all: $(test_files_build)
- $(test_files_build): $(abs_builddir)/%: $(srcdir)/%
- 	ln -s $< $@
- endif # VPATH
- 
  .PHONY: submake
  submake:
  ifndef PGXS
--- 232,237 ----
diff -cr -x TAGS ../cvs-pgsql/src/pl/plperl/GNUmakefile ./src/pl/plperl/GNUmakefile
*** ../cvs-pgsql/src/pl/plperl/GNUmakefile	2008-04-07 17:15:58.000000000 +0300
--- ./src/pl/plperl/GNUmakefile	2008-09-22 20:29:07.000000000 +0300
***************
*** 50,76 ****
  SPI.c: SPI.xs
  	$(PERL) $(perl_privlibexp)/ExtUtils/xsubpp -typemap $(perl_privlibexp)/ExtUtils/typemap $< >$@
  
- # When doing a VPATH build, copy over the .sql and .out files so that the
- # test script can find them.  See comments in src/test/regress/GNUmakefile.
- ifdef VPATH
- 
- ifneq ($(PORTNAME),win32)
- abs_srcdir := $(shell cd $(srcdir) && pwd)
- abs_builddir := $(shell pwd)
- else
- abs_srcdir := $(shell cd $(srcdir) && pwd -W)
- abs_builddir := $(shell pwd -W)
- endif
- 
- test_files_src := $(wildcard $(srcdir)/sql/*.sql) $(wildcard $(srcdir)/expected/*.out)
- test_files_build := $(patsubst $(srcdir)/%, $(abs_builddir)/%, $(test_files_src))
- 
- all: $(test_files_build)
- $(test_files_build): $(abs_builddir)/%: $(srcdir)/%
- 	ln -s $< $@
- 
- endif
- 
  install: all installdirs install-lib
  
  installdirs: installdirs-lib
--- 50,55 ----
diff -cr -x TAGS ../cvs-pgsql/src/pl/plpython/Makefile ./src/pl/plpython/Makefile
*** ../cvs-pgsql/src/pl/plpython/Makefile	2008-04-07 17:15:58.000000000 +0300
--- ./src/pl/plpython/Makefile	2008-09-22 20:30:40.000000000 +0300
***************
*** 66,92 ****
  
  all: all-lib
  
- # When doing a VPATH build, copy over the .sql and .out files so that the
- # test script can find them.  See comments in src/test/regress/GNUmakefile.
- ifdef VPATH
- 
- ifneq ($(PORTNAME),win32)
- abs_srcdir := $(shell cd $(srcdir) && pwd)
- abs_builddir := $(shell pwd)
- else
- abs_srcdir := $(shell cd $(srcdir) && pwd -W)
- abs_builddir := $(shell pwd -W)
- endif
- 
- test_files_src := $(wildcard $(srcdir)/sql/*.sql) $(wildcard $(srcdir)/expected/*.out)
- test_files_build := $(patsubst $(srcdir)/%, $(abs_builddir)/%, $(test_files_src))
- 
- all: $(test_files_build)
- $(test_files_build): $(abs_builddir)/%: $(srcdir)/%
- 	ln -s $< $@
- 
- endif
- 
  install: all installdirs install-lib
  
  installdirs: installdirs-lib
--- 66,71 ----
diff -cr -x TAGS ../cvs-pgsql/src/pl/tcl/Makefile ./src/pl/tcl/Makefile
*** ../cvs-pgsql/src/pl/tcl/Makefile	2008-04-07 17:15:58.000000000 +0300
--- ./src/pl/tcl/Makefile	2008-09-22 20:31:13.000000000 +0300
***************
*** 49,75 ****
  all: all-lib
  	$(MAKE) -C modules $@
  
- # When doing a VPATH build, copy over the .sql and .out files so that the
- # test script can find them.  See comments in src/test/regress/GNUmakefile.
- ifdef VPATH
- 
- ifneq ($(PORTNAME),win32)
- abs_srcdir := $(shell cd $(srcdir) && pwd)
- abs_builddir := $(shell pwd)
- else
- abs_srcdir := $(shell cd $(srcdir) && pwd -W)
- abs_builddir := $(shell pwd -W)
- endif
- 
- test_files_src := $(wildcard $(srcdir)/sql/*.sql) $(wildcard $(srcdir)/expected/*.out)
- test_files_build := $(patsubst $(srcdir)/%, $(abs_builddir)/%, $(test_files_src))
- 
- all: $(test_files_build)
- $(test_files_build): $(abs_builddir)/%: $(srcdir)/%
- 	ln -s $< $@
- 
- endif
- 
  install: all installdirs install-lib
  	$(MAKE) -C modules $@
  
--- 49,54 ----
diff -cr -x TAGS ../cvs-pgsql/src/test/regress/GNUmakefile ./src/test/regress/GNUmakefile
*** ../cvs-pgsql/src/test/regress/GNUmakefile	2008-05-30 03:04:32.000000000 +0300
--- ./src/test/regress/GNUmakefile	2008-09-22 19:57:57.000000000 +0300
***************
*** 65,73 ****
  $(top_builddir)/src/port/pg_config_paths.h: $(top_builddir)/src/Makefile.global
  	$(MAKE) -C $(top_builddir)/src/port pg_config_paths.h
  
! install: pg_regress$(X)
  	$(INSTALL_PROGRAM) pg_regress$(X) '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_regress$(X)'
  
  uninstall:
  	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_regress$(X)'
  
--- 65,76 ----
  $(top_builddir)/src/port/pg_config_paths.h: $(top_builddir)/src/Makefile.global
  	$(MAKE) -C $(top_builddir)/src/port pg_config_paths.h
  
! install: all installdirs
  	$(INSTALL_PROGRAM) pg_regress$(X) '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_regress$(X)'
  
+ installdirs:
+ 	$(mkinstalldirs) '$(DESTDIR)$(pgxsdir)/$(subdir)'
+ 
  uninstall:
  	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_regress$(X)'
  
***************
*** 83,116 ****
  
  # Test input and expected files.  These are created by pg_regress itself, so we
  # don't have a rule to create them.  We do need rules to clean them however.
! ifile_list := $(subst .source,, $(notdir $(wildcard $(top_srcdir)/$(subdir)/input/*.source)))
! input_files  := $(foreach file, $(ifile_list), sql/$(file).sql)
! ofile_list := $(subst .source,, $(notdir $(wildcard $(top_srcdir)/$(subdir)/output/*.source)))
! output_files := $(foreach file, $(ofile_list), expected/$(file).out)
! 
! ifneq ($(PORTNAME),win32)
! abs_srcdir := $(shell cd $(srcdir) && pwd)
! abs_builddir := $(shell pwd)
! else
! abs_srcdir := $(shell cd $(srcdir) && pwd -W)
! abs_builddir := $(shell pwd -W)
! endif
! 
! # When doing a VPATH build, copy over the remaining .sql and .out
! # files so that the driver script can find them.  We have to use an
! # absolute path for the targets, because otherwise make will try to
! # locate the missing files using VPATH, and will find them in
! # $(srcdir), but the point here is that we want to copy them from
! # $(srcdir) to the build directory.
! 
! ifdef VPATH
! remaining_files_src := $(wildcard $(srcdir)/sql/*.sql) $(wildcard $(srcdir)/expected/*.out) $(srcdir)/resultmap
! remaining_files_build := $(patsubst $(srcdir)/%, $(abs_builddir)/%, $(remaining_files_src))
! 
! all: $(remaining_files_build)
! $(remaining_files_build): $(abs_builddir)/%: $(srcdir)/%
! 	ln -s $< $@
! endif
  
  
  # Get some extra C modules from contrib/spi...
--- 86,113 ----
  
  # Test input and expected files.  These are created by pg_regress itself, so we
  # don't have a rule to create them.  We do need rules to clean them however.
! input_files = $(patsubst $(srcdir)/input/%.source,sql/%.sql, $(wildcard $(srcdir)/input/*.source))
! output_files := $(patsubst $(srcdir)/output/%.source,expected/%.out, $(wildcard $(srcdir)/output/*.source))
! 
! 
! # not installed by default
! 
! regress_data_files = \
! 	$(filter-out $(addprefix $(srcdir)/,$(output_files)),$(wildcard $(srcdir)/expected/*.out)) \
! 	$(wildcard $(srcdir)/input/*.source) \
! 	$(wildcard $(srcdir)/output/*.source) \
! 	$(filter-out $(addprefix $(srcdir)/,$(input_files)),$(wildcard $(srcdir)/sql/*.sql)) \
! 	$(wildcard $(srcdir)/data/*.data) \
! 	$(srcdir)/parallel_schedule $(srcdir)/serial_schedule $(srcdir)/resultmap
! 
! install-tests: all install install-lib installdirs-tests
! 	$(MAKE) -C $(top_builddir)/contrib/spi install
! 	for file in $(regress_data_files); do \
! 	  $(INSTALL_DATA) $$file '$(DESTDIR)$(pkglibdir)/regress/'$$file; \
! 	done
! 
! installdirs-tests: installdirs
! 	$(mkinstalldirs)  $(patsubst $(srcdir)/%/,'$(DESTDIR)$(pkglibdir)/regress/%',$(sort $(dir $(regress_data_files))))
  
  
  # Get some extra C modules from contrib/spi...
***************
*** 144,157 ****
  ## Run tests
  ##
  
  check: all
! 	./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --srcdir=$(abs_srcdir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) $(TEMP_CONF)
  
  installcheck: all
! 	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --srcdir=$(abs_srcdir) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE)
  
  installcheck-parallel: all
! 	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/parallel_schedule --srcdir=$(abs_srcdir) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE)
  
  
  # old interfaces follow...
--- 141,156 ----
  ## Run tests
  ##
  
+ pg_regress_call = ./pg_regress --inputdir=$(srcdir) --dlpath=. --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE)
+ 
  check: all
! 	$(pg_regress_call) --temp-install=./tmp_check --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(TEMP_CONF)
  
  installcheck: all
! 	$(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule
  
  installcheck-parallel: all
! 	$(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT)
  
  
  # old interfaces follow...
***************
*** 161,170 ****
  runtest-parallel: installcheck-parallel
  
  bigtest: all
! 	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --srcdir=$(abs_srcdir) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) numeric_big 
  
  bigcheck: all
! 	./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --srcdir=$(abs_srcdir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) numeric_big
  
  
  ##
--- 160,169 ----
  runtest-parallel: installcheck-parallel
  
  bigtest: all
! 	$(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule numeric_big 
  
  bigcheck: all
! 	$(pg_regress_call) --temp-install=./tmp_check --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) numeric_big
  
  
  ##
***************
*** 173,187 ****
  
  clean distclean maintainer-clean: clean-lib
  # things built by `all' target
! 	rm -f $(OBJS) refint$(DLSUFFIX) autoinc$(DLSUFFIX)
! 	rm -f $(output_files) $(input_files) pg_regress_main.o pg_regress.o pg_regress$(X)
  # things created by various check targets
  	rm -rf testtablespace
  	rm -rf results tmp_check log
  	rm -f regression.diffs regression.out regress.out run_check.out
- ifeq ($(PORTNAME), cygwin)
- 	rm -f regress.def
- endif
- ifdef VPATH
- 	rm -f $(remaining_files_build)
- endif
--- 172,180 ----
  
  clean distclean maintainer-clean: clean-lib
  # things built by `all' target
! 	rm -f $(OBJS) refint$(DLSUFFIX) autoinc$(DLSUFFIX) pg_regress_main.o pg_regress.o pg_regress$(X)
  # 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
diff -cr -x TAGS ../cvs-pgsql/src/test/regress/input/create_function_1.source ./src/test/regress/input/create_function_1.source
*** ../cvs-pgsql/src/test/regress/input/create_function_1.source	2008-05-30 03:04:32.000000000 +0300
--- ./src/test/regress/input/create_function_1.source	2008-09-22 12:08:46.000000000 +0300
***************
*** 4,55 ****
  
  CREATE FUNCTION widget_in(cstring)
     RETURNS widget
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  
  CREATE FUNCTION widget_out(widget)
     RETURNS cstring
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  
  CREATE FUNCTION int44in(cstring)
     RETURNS city_budget
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  
  CREATE FUNCTION int44out(city_budget)
     RETURNS cstring
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  
  CREATE FUNCTION check_primary_key ()
  	RETURNS trigger
! 	AS '@abs_builddir@/refint@DLSUFFIX@'
  	LANGUAGE C;
  
  CREATE FUNCTION check_foreign_key ()
  	RETURNS trigger
! 	AS '@abs_builddir@/refint@DLSUFFIX@'
  	LANGUAGE C;
  
  CREATE FUNCTION autoinc ()
  	RETURNS trigger
! 	AS '@abs_builddir@/autoinc@DLSUFFIX@'
  	LANGUAGE C;
  
  CREATE FUNCTION funny_dup17 ()
          RETURNS trigger
!         AS '@abs_builddir@/regress@DLSUFFIX@'
          LANGUAGE C;
  
  CREATE FUNCTION ttdummy ()
          RETURNS trigger
!         AS '@abs_builddir@/regress@DLSUFFIX@'
          LANGUAGE C;
  
  CREATE FUNCTION set_ttdummy (int4)
          RETURNS int4
!         AS '@abs_builddir@/regress@DLSUFFIX@'
          LANGUAGE C STRICT;
  
  -- Things that shouldn't work:
--- 4,55 ----
  
  CREATE FUNCTION widget_in(cstring)
     RETURNS widget
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  
  CREATE FUNCTION widget_out(widget)
     RETURNS cstring
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  
  CREATE FUNCTION int44in(cstring)
     RETURNS city_budget
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  
  CREATE FUNCTION int44out(city_budget)
     RETURNS cstring
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  
  CREATE FUNCTION check_primary_key ()
  	RETURNS trigger
! 	AS '@libdir@/refint@DLSUFFIX@'
  	LANGUAGE C;
  
  CREATE FUNCTION check_foreign_key ()
  	RETURNS trigger
! 	AS '@libdir@/refint@DLSUFFIX@'
  	LANGUAGE C;
  
  CREATE FUNCTION autoinc ()
  	RETURNS trigger
! 	AS '@libdir@/autoinc@DLSUFFIX@'
  	LANGUAGE C;
  
  CREATE FUNCTION funny_dup17 ()
          RETURNS trigger
!         AS '@libdir@/regress@DLSUFFIX@'
          LANGUAGE C;
  
  CREATE FUNCTION ttdummy ()
          RETURNS trigger
!         AS '@libdir@/regress@DLSUFFIX@'
          LANGUAGE C;
  
  CREATE FUNCTION set_ttdummy (int4)
          RETURNS int4
!         AS '@libdir@/regress@DLSUFFIX@'
          LANGUAGE C STRICT;
  
  -- Things that shouldn't work:
***************
*** 73,79 ****
      AS 'nosuchfile';
  
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
!     AS '@abs_builddir@/regress@DLSUFFIX@', 'nosuchsymbol';
  
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
      AS 'nosuch';
--- 73,79 ----
      AS 'nosuchfile';
  
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
!     AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol';
  
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
      AS 'nosuch';
diff -cr -x TAGS ../cvs-pgsql/src/test/regress/input/create_function_2.source ./src/test/regress/input/create_function_2.source
*** ../cvs-pgsql/src/test/regress/input/create_function_2.source	2006-02-27 18:09:50.000000000 +0200
--- ./src/test/regress/input/create_function_2.source	2008-09-22 12:09:34.000000000 +0300
***************
*** 36,71 ****
  
  CREATE FUNCTION pt_in_widget(point, widget)
     RETURNS bool
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION overpaid(emp)
     RETURNS bool
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION boxarea(box)
     RETURNS float8
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION interpt_pp(path, path)
     RETURNS point
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION reverse_name(name)
     RETURNS name
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION oldstyle_length(int4, text)
     RETURNS int4
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  --
  -- Function dynamic loading
  --
! LOAD '@abs_builddir@/regress@DLSUFFIX@';
  
--- 36,71 ----
  
  CREATE FUNCTION pt_in_widget(point, widget)
     RETURNS bool
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION overpaid(emp)
     RETURNS bool
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION boxarea(box)
     RETURNS float8
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION interpt_pp(path, path)
     RETURNS point
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION reverse_name(name)
     RETURNS name
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  CREATE FUNCTION oldstyle_length(int4, text)
     RETURNS int4
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  
  --
  -- Function dynamic loading
  --
! LOAD '@libdir@/regress@DLSUFFIX@';
  
diff -cr -x TAGS ../cvs-pgsql/src/test/regress/output/create_function_1.source ./src/test/regress/output/create_function_1.source
*** ../cvs-pgsql/src/test/regress/output/create_function_1.source	2008-09-02 15:11:11.000000000 +0300
--- ./src/test/regress/output/create_function_1.source	2008-09-22 12:13:59.000000000 +0300
***************
*** 3,51 ****
  --
  CREATE FUNCTION widget_in(cstring)
     RETURNS widget
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  NOTICE:  type "widget" is not yet defined
  DETAIL:  Creating a shell type definition.
  CREATE FUNCTION widget_out(widget)
     RETURNS cstring
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  NOTICE:  argument type widget is only a shell
  CREATE FUNCTION int44in(cstring)
     RETURNS city_budget
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  NOTICE:  type "city_budget" is not yet defined
  DETAIL:  Creating a shell type definition.
  CREATE FUNCTION int44out(city_budget)
     RETURNS cstring
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  NOTICE:  argument type city_budget is only a shell
  CREATE FUNCTION check_primary_key ()
  	RETURNS trigger
! 	AS '@abs_builddir@/refint@DLSUFFIX@'
  	LANGUAGE C;
  CREATE FUNCTION check_foreign_key ()
  	RETURNS trigger
! 	AS '@abs_builddir@/refint@DLSUFFIX@'
  	LANGUAGE C;
  CREATE FUNCTION autoinc ()
  	RETURNS trigger
! 	AS '@abs_builddir@/autoinc@DLSUFFIX@'
  	LANGUAGE C;
  CREATE FUNCTION funny_dup17 ()
          RETURNS trigger
!         AS '@abs_builddir@/regress@DLSUFFIX@'
          LANGUAGE C;
  CREATE FUNCTION ttdummy ()
          RETURNS trigger
!         AS '@abs_builddir@/regress@DLSUFFIX@'
          LANGUAGE C;
  CREATE FUNCTION set_ttdummy (int4)
          RETURNS int4
!         AS '@abs_builddir@/regress@DLSUFFIX@'
          LANGUAGE C STRICT;
  -- Things that shouldn't work:
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
--- 3,51 ----
  --
  CREATE FUNCTION widget_in(cstring)
     RETURNS widget
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  NOTICE:  type "widget" is not yet defined
  DETAIL:  Creating a shell type definition.
  CREATE FUNCTION widget_out(widget)
     RETURNS cstring
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  NOTICE:  argument type widget is only a shell
  CREATE FUNCTION int44in(cstring)
     RETURNS city_budget
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  NOTICE:  type "city_budget" is not yet defined
  DETAIL:  Creating a shell type definition.
  CREATE FUNCTION int44out(city_budget)
     RETURNS cstring
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C STRICT;
  NOTICE:  argument type city_budget is only a shell
  CREATE FUNCTION check_primary_key ()
  	RETURNS trigger
! 	AS '@libdir@/refint@DLSUFFIX@'
  	LANGUAGE C;
  CREATE FUNCTION check_foreign_key ()
  	RETURNS trigger
! 	AS '@libdir@/refint@DLSUFFIX@'
  	LANGUAGE C;
  CREATE FUNCTION autoinc ()
  	RETURNS trigger
! 	AS '@libdir@/autoinc@DLSUFFIX@'
  	LANGUAGE C;
  CREATE FUNCTION funny_dup17 ()
          RETURNS trigger
!         AS '@libdir@/regress@DLSUFFIX@'
          LANGUAGE C;
  CREATE FUNCTION ttdummy ()
          RETURNS trigger
!         AS '@libdir@/regress@DLSUFFIX@'
          LANGUAGE C;
  CREATE FUNCTION set_ttdummy (int4)
          RETURNS int4
!         AS '@libdir@/regress@DLSUFFIX@'
          LANGUAGE C STRICT;
  -- Things that shouldn't work:
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
***************
*** 75,82 ****
      AS 'nosuchfile';
  ERROR:  could not access file "nosuchfile": No such file or directory
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
!     AS '@abs_builddir@/regress@DLSUFFIX@', 'nosuchsymbol';
! ERROR:  could not find function "nosuchsymbol" in file "@abs_builddir@/regress@DLSUFFIX@"
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
      AS 'nosuch';
  ERROR:  there is no built-in function named "nosuch"
--- 75,82 ----
      AS 'nosuchfile';
  ERROR:  could not access file "nosuchfile": No such file or directory
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
!     AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol';
! ERROR:  could not find function "nosuchsymbol" in file "@libdir@/regress@DLSUFFIX@"
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
      AS 'nosuch';
  ERROR:  there is no built-in function named "nosuch"
diff -cr -x TAGS ../cvs-pgsql/src/test/regress/output/create_function_2.source ./src/test/regress/output/create_function_2.source
*** ../cvs-pgsql/src/test/regress/output/create_function_2.source	2006-02-27 18:09:50.000000000 +0200
--- ./src/test/regress/output/create_function_2.source	2008-09-22 12:13:30.000000000 +0300
***************
*** 29,57 ****
     LANGUAGE SQL;
  CREATE FUNCTION pt_in_widget(point, widget)
     RETURNS bool
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION overpaid(emp)
     RETURNS bool
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION boxarea(box)
     RETURNS float8
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION interpt_pp(path, path)
     RETURNS point
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION reverse_name(name)
     RETURNS name
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION oldstyle_length(int4, text)
     RETURNS int4
!    AS '@abs_builddir@/regress@DLSUFFIX@'
     LANGUAGE C;
  --
  -- Function dynamic loading
  --
! LOAD '@abs_builddir@/regress@DLSUFFIX@';
--- 29,57 ----
     LANGUAGE SQL;
  CREATE FUNCTION pt_in_widget(point, widget)
     RETURNS bool
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION overpaid(emp)
     RETURNS bool
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION boxarea(box)
     RETURNS float8
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION interpt_pp(path, path)
     RETURNS point
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION reverse_name(name)
     RETURNS name
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  CREATE FUNCTION oldstyle_length(int4, text)
     RETURNS int4
!    AS '@libdir@/regress@DLSUFFIX@'
     LANGUAGE C;
  --
  -- Function dynamic loading
  --
! LOAD '@libdir@/regress@DLSUFFIX@';
diff -cr -x TAGS ../cvs-pgsql/src/test/regress/pg_regress.c ./src/test/regress/pg_regress.c
*** ../cvs-pgsql/src/test/regress/pg_regress.c	2008-08-05 08:16:08.000000000 +0300
--- ./src/test/regress/pg_regress.c	2008-09-22 21:01:20.000000000 +0300
***************
*** 47,52 ****
--- 47,56 ----
   * out where "make install" will put stuff under the temp_install directory.
   * In non-temp_install mode, the only thing we need is the location of psql,
   * which we expect to find in psqldir, or in the PATH if psqldir isn't given.
+  *
+  * XXX Because pg_regress is not installed in bindir, we can't support
+  * this for relocatable trees as it is.  --psqldir would need to be
+  * specified in those cases.
   */
  char	   *bindir = PGBINDIR;
  char	   *libdir = LIBDIR;
***************
*** 70,76 ****
  bool		debug = false;
  char	   *inputdir = ".";
  char	   *outputdir = ".";
! char	   *psqldir = NULL;
  static _stringlist *loadlanguage = NULL;
  static int	max_connections = 0;
  static char *encoding = NULL;
--- 74,80 ----
  bool		debug = false;
  char	   *inputdir = ".";
  char	   *outputdir = ".";
! char	   *psqldir = PGBINDIR;
  static _stringlist *loadlanguage = NULL;
  static int	max_connections = 0;
  static char *encoding = NULL;
***************
*** 83,90 ****
  static bool nolocale = false;
  static char *hostname = NULL;
  static int	port = -1;
  static char *user = NULL;
- static char *srcdir = NULL;
  static _stringlist *extraroles = NULL;
  
  /* internal variables */
--- 87,94 ----
  static bool nolocale = false;
  static char *hostname = NULL;
  static int	port = -1;
+ static char *dlpath = PKGLIBDIR;
  static char *user = NULL;
  static _stringlist *extraroles = NULL;
  
  /* internal variables */
***************
*** 391,400 ****
   * the given suffix.
   */
  static void
! convert_sourcefiles_in(char *source, char *dest, char *suffix)
  {
- 	char		abs_srcdir[MAXPGPATH];
- 	char		abs_builddir[MAXPGPATH];
  	char		testtablespace[MAXPGPATH];
  	char		indir[MAXPGPATH];
  	struct stat	st;
--- 395,402 ----
   * the given suffix.
   */
  static void
! convert_sourcefiles_in(char *source_subdir, char *dest_subdir, char *suffix)
  {
  	char		testtablespace[MAXPGPATH];
  	char		indir[MAXPGPATH];
  	struct stat	st;
***************
*** 403,429 ****
  	char	  **names;
  	int			count = 0;
  
! #ifdef WIN32
! 	char	   *c;
! #endif
! 
! 	if (!getcwd(abs_builddir, sizeof(abs_builddir)))
! 	{
! 		fprintf(stderr, _("%s: could not get current directory: %s\n"),
! 				progname, strerror(errno));
! 		exit_nicely(2);
! 	}
! 
! 	/*
! 	 * in a VPATH build, use the provided source directory; otherwise, use the
! 	 * current directory.
! 	 */
! 	if (srcdir)
! 		strlcpy(abs_srcdir, srcdir, MAXPGPATH);
! 	else
! 		strlcpy(abs_srcdir, abs_builddir, MAXPGPATH);
! 
! 	snprintf(indir, MAXPGPATH, "%s/%s", abs_srcdir, source);
  
  	/* Check that indir actually exists and is a directory */
  	ret = stat(indir, &st);
--- 405,411 ----
  	char	  **names;
  	int			count = 0;
  
! 	snprintf(indir, MAXPGPATH, "%s/%s", inputdir, source_subdir);
  
  	/* Check that indir actually exists and is a directory */
  	ret = stat(indir, &st);
***************
*** 441,457 ****
  		/* Error logged in pgfnames */
  		exit_nicely(2);
  
! #ifdef WIN32
! 	/* in Win32, replace backslashes with forward slashes */
! 	for (c = abs_builddir; *c; c++)
! 		if (*c == '\\')
! 			*c = '/';
! 	for (c = abs_srcdir; *c; c++)
! 		if (*c == '\\')
! 			*c = '/';
! #endif
! 
! 	snprintf(testtablespace, MAXPGPATH, "%s/testtablespace", abs_builddir);
  
  #ifdef WIN32
  	/*
--- 423,429 ----
  		/* Error logged in pgfnames */
  		exit_nicely(2);
  
! 	snprintf(testtablespace, MAXPGPATH, "%s/testtablespace", outputdir);
  
  #ifdef WIN32
  	/*
***************
*** 490,496 ****
  		/* build the full actual paths to open */
  		snprintf(prefix, strlen(*name) - 6, "%s", *name);
  		snprintf(srcfile, MAXPGPATH, "%s/%s", indir, *name);
! 		snprintf(destfile, MAXPGPATH, "%s/%s.%s", dest, prefix, suffix);
  
  		infile = fopen(srcfile, "r");
  		if (!infile)
--- 462,468 ----
  		/* build the full actual paths to open */
  		snprintf(prefix, strlen(*name) - 6, "%s", *name);
  		snprintf(srcfile, MAXPGPATH, "%s/%s", indir, *name);
! 		snprintf(destfile, MAXPGPATH, "%s/%s.%s", dest_subdir, prefix, suffix);
  
  		infile = fopen(srcfile, "r");
  		if (!infile)
***************
*** 508,516 ****
  		}
  		while (fgets(line, sizeof(line), infile))
  		{
! 			replace_string(line, "@abs_srcdir@", abs_srcdir);
! 			replace_string(line, "@abs_builddir@", abs_builddir);
  			replace_string(line, "@testtablespace@", testtablespace);
  			replace_string(line, "@DLSUFFIX@", DLSUFFIX);
  			fputs(line, outfile);
  		}
--- 480,489 ----
  		}
  		while (fgets(line, sizeof(line), infile))
  		{
! 			replace_string(line, "@abs_srcdir@", inputdir);
! 			replace_string(line, "@abs_builddir@", outputdir);
  			replace_string(line, "@testtablespace@", testtablespace);
+ 			replace_string(line, "@libdir@", dlpath);
  			replace_string(line, "@DLSUFFIX@", DLSUFFIX);
  			fputs(line, outfile);
  		}
***************
*** 520,526 ****
  
  	/*
  	 * If we didn't process any files, complain because it probably means
! 	 * somebody neglected to pass the needed --srcdir argument.
  	 */
  	if (count <= 0)
  	{
--- 493,499 ----
  
  	/*
  	 * If we didn't process any files, complain because it probably means
! 	 * somebody neglected to pass the needed --inputdir argument.
  	 */
  	if (count <= 0)
  	{
***************
*** 1087,1093 ****
  	return l;
  }
  
! static bool
  file_exists(const char *file)
  {
  	FILE	   *f = fopen(file, "r");
--- 1060,1066 ----
  	return l;
  }
  
! bool
  file_exists(const char *file)
  {
  	FILE	   *f = fopen(file, "r");
***************
*** 1792,1797 ****
--- 1765,1798 ----
  	}
  }
  
+ static char *
+ make_absolute_path(const char *in)
+ {
+ 	char *result;
+ 
+ 	if (is_absolute_path(in))
+ 		result = strdup(in);
+ 	else
+ 	{
+ 		static char		cwdbuf[MAXPGPATH];
+ 
+ 		if (!cwdbuf[0])
+ 		{
+ 			if (!getcwd(cwdbuf, sizeof(cwdbuf)))
+ 			{
+ 				fprintf(stderr, _("could not get current working directory: %s\n"), strerror(errno));
+ 				exit_nicely(2);
+ 			}
+ 		}
+ 
+ 		result = malloc(strlen(cwdbuf) + strlen(in) + 2);
+ 		sprintf(result, "%s/%s", cwdbuf, in);
+ 	}
+ 
+ 	canonicalize_path(result);
+ 	return result;
+ }
+ 
  static void
  help(void)
  {
***************
*** 1812,1818 ****
  	printf(_("  --outputdir=DIR           place output files in DIR (default \".\")\n"));
  	printf(_("  --schedule=FILE           use test ordering schedule from FILE\n"));
  	printf(_("                            (can be used multiple times to concatenate)\n"));
! 	printf(_("  --srcdir=DIR              absolute path to source directory (for VPATH builds)\n"));
  	printf(_("  --temp-install=DIR        create a temporary installation in DIR\n"));
  	printf(_("\n"));
  	printf(_("Options for \"temp-install\" mode:\n"));
--- 1813,1819 ----
  	printf(_("  --outputdir=DIR           place output files in DIR (default \".\")\n"));
  	printf(_("  --schedule=FILE           use test ordering schedule from FILE\n"));
  	printf(_("                            (can be used multiple times to concatenate)\n"));
! 	printf(_("  --dlpath=DIR              look for dynamic libraries in DIR\n"));
  	printf(_("  --temp-install=DIR        create a temporary installation in DIR\n"));
  	printf(_("\n"));
  	printf(_("Options for \"temp-install\" mode:\n"));
***************
*** 1861,1867 ****
  		{"port", required_argument, NULL, 14},
  		{"user", required_argument, NULL, 15},
  		{"psqldir", required_argument, NULL, 16},
! 		{"srcdir", required_argument, NULL, 17},
  		{"create-role", required_argument, NULL, 18},
  		{"temp-config", required_argument, NULL, 19},
  		{NULL, 0, NULL, 0}
--- 1862,1868 ----
  		{"port", required_argument, NULL, 14},
  		{"user", required_argument, NULL, 15},
  		{"psqldir", required_argument, NULL, 16},
! 		{"dlpath", required_argument, NULL, 17},
  		{"create-role", required_argument, NULL, 18},
  		{"temp-config", required_argument, NULL, 19},
  		{NULL, 0, NULL, 0}
***************
*** 1922,1943 ****
  				add_stringlist_item(&schedulelist, optarg);
  				break;
  			case 9:
! 				/* temp_install must be absolute path */
! 				if (is_absolute_path(optarg))
! 					temp_install = strdup(optarg);
! 				else
! 				{
! 					char		cwdbuf[MAXPGPATH];
! 
! 					if (!getcwd(cwdbuf, sizeof(cwdbuf)))
! 					{
! 						fprintf(stderr, _("could not get current working directory: %s\n"), strerror(errno));
! 						exit_nicely(2);
! 					}
! 					temp_install = malloc(strlen(cwdbuf) + strlen(optarg) + 2);
! 					sprintf(temp_install, "%s/%s", cwdbuf, optarg);
! 				}
! 				canonicalize_path(temp_install);
  				break;
  			case 10:
  				nolocale = true;
--- 1923,1929 ----
  				add_stringlist_item(&schedulelist, optarg);
  				break;
  			case 9:
! 				temp_install = make_absolute_path(optarg);
  				break;
  			case 10:
  				nolocale = true;
***************
*** 1969,1975 ****
  					psqldir = strdup(optarg);
  				break;
  			case 17:
! 				srcdir = strdup(optarg);
  				break;
  			case 18:
  				split_to_stringlist(strdup(optarg), ", ", &extraroles);
--- 1955,1961 ----
  					psqldir = strdup(optarg);
  				break;
  			case 17:
! 				dlpath = strdup(optarg);
  				break;
  			case 18:
  				split_to_stringlist(strdup(optarg), ", ", &extraroles);
***************
*** 1997,2002 ****
--- 1983,1992 ----
  	if (temp_install)
  		port = temp_port;
  
+ 	inputdir = make_absolute_path(inputdir);
+ 	outputdir = make_absolute_path(outputdir);
+ 	dlpath = make_absolute_path(dlpath);
+ 
  	/*
  	 * Initialization
  	 */
diff -cr -x TAGS ../cvs-pgsql/src/test/regress/pg_regress.h ./src/test/regress/pg_regress.h
*** ../cvs-pgsql/src/test/regress/pg_regress.h	2008-01-01 21:46:00.000000000 +0200
--- ./src/test/regress/pg_regress.h	2008-09-20 19:24:29.000000000 +0300
***************
*** 57,59 ****
--- 57,60 ----
  PID_TYPE	spawn_process(const char *cmdline);
  void		exit_nicely(int code);
  void		replace_string(char *string, char *replace, char *replacement);
+ bool		file_exists(const char *file);
diff -cr -x TAGS ../cvs-pgsql/src/test/regress/pg_regress_main.c ./src/test/regress/pg_regress_main.c
*** ../cvs-pgsql/src/test/regress/pg_regress_main.c	2008-01-01 21:46:00.000000000 +0200
--- ./src/test/regress/pg_regress_main.c	2008-09-21 19:23:08.000000000 +0300
***************
*** 34,45 ****
  	char		expectfile[MAXPGPATH];
  	char		psql_cmd[MAXPGPATH * 3];
  
  	snprintf(infile, sizeof(infile), "%s/sql/%s.sql",
! 			 inputdir, testname);
  	snprintf(outfile, sizeof(outfile), "%s/results/%s.out",
  			 outputdir, testname);
  	snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out",
! 			 inputdir, testname);
  
  	add_stringlist_item(resultfiles, outfile);
  	add_stringlist_item(expectfiles, expectfile);
--- 34,59 ----
  	char		expectfile[MAXPGPATH];
  	char		psql_cmd[MAXPGPATH * 3];
  
+ 	/*
+ 	 * Look for files in the output dir first, consistent with a vpath
+ 	 * search.  This is mainly to create more reasonable error
+ 	 * messages if the file is not found.  It also allows local test
+ 	 * overrides when running pg_regress outside of the source tree.
+ 	 */
  	snprintf(infile, sizeof(infile), "%s/sql/%s.sql",
! 			 outputdir, testname);
! 	if (!file_exists(infile))
! 		snprintf(infile, sizeof(infile), "%s/sql/%s.sql",
! 				 inputdir, testname);
! 
  	snprintf(outfile, sizeof(outfile), "%s/results/%s.out",
  			 outputdir, testname);
+ 
  	snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out",
! 			 outputdir, testname);
! 	if (!file_exists(expectfile))
! 		snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out",
! 				 inputdir, testname);
  
  	add_stringlist_item(resultfiles, outfile);
  	add_stringlist_item(expectfiles, expectfile);