From 242066cc8e587ccbe5e1cf38c4f085f080dcd5e0 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 7 Feb 2017 16:34:11 -0500
Subject: [PATCH] Speed up "brin" regression test a little bit.

In the large DO block, collect row TIDs into array variables instead of
creating and dropping a pile of temporary tables.  In a normal build,
this reduces the brin test script's runtime from about 1.1 sec to 0.4 sec
on my workstation.  That's not all that exciting perhaps, but in a
CLOBBER_CACHE_ALWAYS test build, the runtime drops from 20 min to 17 min,
which is a little more useful.  In combination with some other changes
I plan to propose, this will help provide a noticeable reduction in
cycle time for CLOBBER_CACHE_ALWAYS buildfarm critters.
---
 src/test/regress/expected/brin.out | 42 +++++++++++-------------------
 src/test/regress/sql/brin.sql      | 42 +++++++++++-------------------
 2 files changed, 30 insertions(+), 54 deletions(-)

diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out
index 21676e53a0d..f0008dd31b4 100644
--- a/src/test/regress/expected/brin.out
+++ b/src/test/regress/expected/brin.out
@@ -288,13 +288,13 @@ DECLARE
 	r record;
 	r2 record;
 	cond text;
+	idx_ctids tid[];
+	ss_ctids tid[];
 	count int;
-	mismatch bool;
 	plan_ok bool;
 	plan_line text;
 BEGIN
 	FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers, unnest(op) WITH ORDINALITY AS oper LOOP
-		mismatch := false;
 
 		-- prepare the condition
 		IF r.value IS NULL THEN
@@ -304,13 +304,12 @@ BEGIN
 		END IF;
 
 		-- run the query using the brin index
-		CREATE TEMP TABLE brin_result (cid tid);
 		SET enable_seqscan = 0;
 		SET enable_bitmapscan = 1;
 
 		plan_ok := false;
-		FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT ctid FROM brintest WHERE %s $y$, cond) LOOP
-			IF plan_line LIKE 'Bitmap Heap Scan on brintest%' THEN
+		FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP
+			IF plan_line LIKE '%Bitmap Heap Scan on brintest%' THEN
 				plan_ok := true;
 			END IF;
 		END LOOP;
@@ -318,16 +317,16 @@ BEGIN
 			RAISE WARNING 'did not get bitmap indexscan plan for %', r;
 		END IF;
 
-		EXECUTE format($y$INSERT INTO brin_result SELECT ctid FROM brintest WHERE %s $y$, cond);
+		EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond)
+			INTO idx_ctids;
 
 		-- run the query using a seqscan
-		CREATE TEMP TABLE brin_result_ss (cid tid);
 		SET enable_seqscan = 1;
 		SET enable_bitmapscan = 0;
 
 		plan_ok := false;
-		FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT ctid FROM brintest WHERE %s $y$, cond) LOOP
-			IF plan_line LIKE 'Seq Scan on brintest%' THEN
+		FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP
+			IF plan_line LIKE '%Seq Scan on brintest%' THEN
 				plan_ok := true;
 			END IF;
 		END LOOP;
@@ -335,22 +334,16 @@ BEGIN
 			RAISE WARNING 'did not get seqscan plan for %', r;
 		END IF;
 
-		EXECUTE format($y$INSERT INTO brin_result_ss SELECT ctid FROM brintest WHERE %s $y$, cond);
+		EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond)
+			INTO ss_ctids;
 
 		-- make sure both return the same results
-		PERFORM * FROM brin_result EXCEPT ALL SELECT * FROM brin_result_ss;
-		GET DIAGNOSTICS count = ROW_COUNT;
-		IF count <> 0 THEN
-			mismatch = true;
-		END IF;
-		PERFORM * FROM brin_result_ss EXCEPT ALL SELECT * FROM brin_result;
-		GET DIAGNOSTICS count = ROW_COUNT;
-		IF count <> 0 THEN
-			mismatch = true;
-		END IF;
+		count := array_length(idx_ctids, 1);
 
-		-- report the results of each scan to make the differences obvious
-		IF mismatch THEN
+		IF NOT (count = array_length(ss_ctids, 1) AND
+				idx_ctids @> ss_ctids AND
+				idx_ctids <@ ss_ctids) THEN
+			-- report the results of each scan to make the differences obvious
 			RAISE WARNING 'something not right in %: count %', r, count;
 			SET enable_seqscan = 1;
 			SET enable_bitmapscan = 0;
@@ -366,12 +359,7 @@ BEGIN
 		END IF;
 
 		-- make sure we found expected number of matches
-		SELECT count(*) INTO count FROM brin_result;
 		IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF;
-
-		-- drop the temporary tables
-		DROP TABLE brin_result;
-		DROP TABLE brin_result_ss;
 	END LOOP;
 END;
 $x$;
diff --git a/src/test/regress/sql/brin.sql b/src/test/regress/sql/brin.sql
index e7f6f779010..5bf53873f77 100644
--- a/src/test/regress/sql/brin.sql
+++ b/src/test/regress/sql/brin.sql
@@ -294,13 +294,13 @@ DECLARE
 	r record;
 	r2 record;
 	cond text;
+	idx_ctids tid[];
+	ss_ctids tid[];
 	count int;
-	mismatch bool;
 	plan_ok bool;
 	plan_line text;
 BEGIN
 	FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers, unnest(op) WITH ORDINALITY AS oper LOOP
-		mismatch := false;
 
 		-- prepare the condition
 		IF r.value IS NULL THEN
@@ -310,13 +310,12 @@ BEGIN
 		END IF;
 
 		-- run the query using the brin index
-		CREATE TEMP TABLE brin_result (cid tid);
 		SET enable_seqscan = 0;
 		SET enable_bitmapscan = 1;
 
 		plan_ok := false;
-		FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT ctid FROM brintest WHERE %s $y$, cond) LOOP
-			IF plan_line LIKE 'Bitmap Heap Scan on brintest%' THEN
+		FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP
+			IF plan_line LIKE '%Bitmap Heap Scan on brintest%' THEN
 				plan_ok := true;
 			END IF;
 		END LOOP;
@@ -324,16 +323,16 @@ BEGIN
 			RAISE WARNING 'did not get bitmap indexscan plan for %', r;
 		END IF;
 
-		EXECUTE format($y$INSERT INTO brin_result SELECT ctid FROM brintest WHERE %s $y$, cond);
+		EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond)
+			INTO idx_ctids;
 
 		-- run the query using a seqscan
-		CREATE TEMP TABLE brin_result_ss (cid tid);
 		SET enable_seqscan = 1;
 		SET enable_bitmapscan = 0;
 
 		plan_ok := false;
-		FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT ctid FROM brintest WHERE %s $y$, cond) LOOP
-			IF plan_line LIKE 'Seq Scan on brintest%' THEN
+		FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP
+			IF plan_line LIKE '%Seq Scan on brintest%' THEN
 				plan_ok := true;
 			END IF;
 		END LOOP;
@@ -341,22 +340,16 @@ BEGIN
 			RAISE WARNING 'did not get seqscan plan for %', r;
 		END IF;
 
-		EXECUTE format($y$INSERT INTO brin_result_ss SELECT ctid FROM brintest WHERE %s $y$, cond);
+		EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond)
+			INTO ss_ctids;
 
 		-- make sure both return the same results
-		PERFORM * FROM brin_result EXCEPT ALL SELECT * FROM brin_result_ss;
-		GET DIAGNOSTICS count = ROW_COUNT;
-		IF count <> 0 THEN
-			mismatch = true;
-		END IF;
-		PERFORM * FROM brin_result_ss EXCEPT ALL SELECT * FROM brin_result;
-		GET DIAGNOSTICS count = ROW_COUNT;
-		IF count <> 0 THEN
-			mismatch = true;
-		END IF;
+		count := array_length(idx_ctids, 1);
 
-		-- report the results of each scan to make the differences obvious
-		IF mismatch THEN
+		IF NOT (count = array_length(ss_ctids, 1) AND
+				idx_ctids @> ss_ctids AND
+				idx_ctids <@ ss_ctids) THEN
+			-- report the results of each scan to make the differences obvious
 			RAISE WARNING 'something not right in %: count %', r, count;
 			SET enable_seqscan = 1;
 			SET enable_bitmapscan = 0;
@@ -372,12 +365,7 @@ BEGIN
 		END IF;
 
 		-- make sure we found expected number of matches
-		SELECT count(*) INTO count FROM brin_result;
 		IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF;
-
-		-- drop the temporary tables
-		DROP TABLE brin_result;
-		DROP TABLE brin_result_ss;
 	END LOOP;
 END;
 $x$;
-- 
GitLab