From 8e39fd97f1566820f7dfd2b4d36dc6bd41211747 Mon Sep 17 00:00:00 2001
From: Kevin Grittner <kgrittn@postgresql.org>
Date: Tue, 4 Sep 2012 20:40:48 -0500
Subject: [PATCH] Allow isolation tests to specify multiple setup blocks.

Each setup block is run as a single PQexec submission, and some
statements such as VACUUM cannot be combined with others in such a
block.

Backpatch to 9.2.

Kevin Grittner and Tom Lane
---
 src/test/isolation/README            |  8 ++++++--
 src/test/isolation/isolationtester.c |  4 ++--
 src/test/isolation/isolationtester.h |  3 ++-
 src/test/isolation/specparse.y       | 28 +++++++++++++++++++++++++---
 4 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/src/test/isolation/README b/src/test/isolation/README
index dc96242883a..69095778c6c 100644
--- a/src/test/isolation/README
+++ b/src/test/isolation/README
@@ -49,8 +49,12 @@ subdirectory. A test specification consists of four parts, in this order:
 setup { <SQL> }
 
   The given SQL block is executed once, in one session only, before running
-  the test. Create any test tables or other required objects here. This
-  part is optional.
+  the test.  Create any test tables or other required objects here.  This
+  part is optional.  Multiple setup blocks are allowed if needed; each is
+  run separately, in the given order.  (The reason for allowing multiple
+  setup blocks is that each block is run as a single PQexec submission,
+  and some statements such as VACUUM cannot be combined with others in such
+  a block.)
 
 teardown { <SQL> }
 
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index 98f89da6bff..4c4556654b3 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -512,9 +512,9 @@ run_permutation(TestSpec * testspec, int nsteps, Step ** steps)
 	printf("\n");
 
 	/* Perform setup */
-	if (testspec->setupsql)
+	for (i = 0; i < testspec->nsetupsqls; i++)
 	{
-		res = PQexec(conns[0], testspec->setupsql);
+		res = PQexec(conns[0], testspec->setupsqls[i]);
 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
 		{
 			fprintf(stderr, "setup failed: %s", PQerrorMessage(conns[0]));
diff --git a/src/test/isolation/isolationtester.h b/src/test/isolation/isolationtester.h
index 1f61c6f1275..4c986bb5233 100644
--- a/src/test/isolation/isolationtester.h
+++ b/src/test/isolation/isolationtester.h
@@ -42,7 +42,8 @@ typedef struct
 
 typedef struct
 {
-	char	   *setupsql;
+	char	  **setupsqls;
+	int         nsetupsqls;
 	char	   *teardownsql;
 	Session   **sessions;
 	int			nsessions;
diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y
index 9d2b1a277f0..bf3a9f3b505 100644
--- a/src/test/isolation/specparse.y
+++ b/src/test/isolation/specparse.y
@@ -35,7 +35,9 @@ TestSpec		parseresult;			/* result of parsing is left here */
 	}			ptr_list;
 }
 
+%type <ptr_list> setup_list
 %type <str>  opt_setup opt_teardown
+%type <str> setup
 %type <ptr_list> step_list session_list permutation_list opt_permutation_list
 %type <ptr_list> string_list
 %type <session> session
@@ -48,12 +50,13 @@ TestSpec		parseresult;			/* result of parsing is left here */
 %%
 
 TestSpec:
-			opt_setup
+			setup_list
 			opt_teardown
 			session_list
 			opt_permutation_list
 			{
-				parseresult.setupsql = $1;
+				parseresult.setupsqls = (char **) $1.elements;
+				parseresult.nsetupsqls = $1.nelements;
 				parseresult.teardownsql = $2;
 				parseresult.sessions = (Session **) $3.elements;
 				parseresult.nsessions = $3.nelements;
@@ -62,9 +65,28 @@ TestSpec:
 			}
 		;
 
+setup_list:
+			/* EMPTY */
+			{
+				$$.elements = NULL;
+				$$.nelements = 0;
+			}
+			| setup_list setup
+			{
+				$$.elements = realloc($1.elements,
+									  ($1.nelements + 1) * sizeof(void *));
+				$$.elements[$1.nelements] = $2;
+				$$.nelements = $1.nelements + 1;
+			}
+		;
+
 opt_setup:
 			/* EMPTY */			{ $$ = NULL; }
-			| SETUP sqlblock	{ $$ = $2; }
+			| setup				{ $$ = $1; }
+		;
+
+setup:
+			SETUP sqlblock		{ $$ = $2; }
 		;
 
 opt_teardown:
-- 
GitLab