summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane2012-04-13 19:32:34 +0000
committerTom Lane2012-04-13 20:07:17 +0000
commite3ffd05b02468b1a53de31a322cedf195576a625 (patch)
tree5631a32e6f9275af24b8382f6c776c56b16aa8ad /src/test
parentc0cc526e8b1e821dfced692a68e4c8978c2bdbc1 (diff)
Weaken the planner's tests for relevant joinclauses.
We should be willing to cross-join two small relations if that allows us to use an inner indexscan on a large relation (that is, the potential indexqual for the large table requires both smaller relations). This worked in simple cases but fell apart as soon as there was a join clause to a fourth relation, because the existence of any two-relation join clause caused the planner to not consider clauseless joins between other base relations. The added regression test shows an example case adapted from a recent complaint from Benoit Delbosc. Adjust have_relevant_joinclause, have_relevant_eclass_joinclause, and has_relevant_eclass_joinclause to consider that a join clause mentioning three or more relations is sufficient grounds for joining any subset of those relations, even if we have to do so via a cartesian join. Since such clauses are relatively uncommon, this shouldn't affect planning speed on typical queries; in fact it should help a bit, because the latter two functions in particular get significantly simpler. Although this is arguably a bug fix, I'm not going to risk back-patching it, since it might have currently-unforeseen consequences.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/join.out51
-rw-r--r--src/test/regress/sql/join.sql18
2 files changed, 69 insertions, 0 deletions
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index c0c72833339..e5dceff7658 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -2667,6 +2667,57 @@ select * from int4_tbl a full join int4_tbl b on false;
(10 rows)
--
+-- test for ability to use a cartesian join when necessary
+--
+explain (costs off)
+select * from
+ tenk1 join int4_tbl on f1 = twothousand,
+ int4(sin(1)) q1,
+ int4(sin(0)) q2
+where q1 = thousand or q2 = thousand;
+ QUERY PLAN
+-----------------------------------------------------------------------------
+ Hash Join
+ Hash Cond: (tenk1.twothousand = int4_tbl.f1)
+ -> Nested Loop
+ Join Filter: ((q1.q1 = tenk1.thousand) OR (q2.q2 = tenk1.thousand))
+ -> Nested Loop
+ -> Function Scan on q1
+ -> Function Scan on q2
+ -> Bitmap Heap Scan on tenk1
+ Recheck Cond: ((q1.q1 = thousand) OR (q2.q2 = thousand))
+ -> BitmapOr
+ -> Bitmap Index Scan on tenk1_thous_tenthous
+ Index Cond: (q1.q1 = thousand)
+ -> Bitmap Index Scan on tenk1_thous_tenthous
+ Index Cond: (q2.q2 = thousand)
+ -> Hash
+ -> Seq Scan on int4_tbl
+(16 rows)
+
+explain (costs off)
+select * from
+ tenk1 join int4_tbl on f1 = twothousand,
+ int4(sin(1)) q1,
+ int4(sin(0)) q2
+where thousand = (q1 + q2);
+ QUERY PLAN
+--------------------------------------------------------------
+ Hash Join
+ Hash Cond: (tenk1.twothousand = int4_tbl.f1)
+ -> Nested Loop
+ -> Nested Loop
+ -> Function Scan on q1
+ -> Function Scan on q2
+ -> Bitmap Heap Scan on tenk1
+ Recheck Cond: (thousand = (q1.q1 + q2.q2))
+ -> Bitmap Index Scan on tenk1_thous_tenthous
+ Index Cond: (thousand = (q1.q1 + q2.q2))
+ -> Hash
+ -> Seq Scan on int4_tbl
+(12 rows)
+
+--
-- test join removal
--
begin;
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index 2d53cf1725b..bc9b7812cf8 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -690,6 +690,24 @@ select * from int4_tbl a full join int4_tbl b on true;
select * from int4_tbl a full join int4_tbl b on false;
--
+-- test for ability to use a cartesian join when necessary
+--
+
+explain (costs off)
+select * from
+ tenk1 join int4_tbl on f1 = twothousand,
+ int4(sin(1)) q1,
+ int4(sin(0)) q2
+where q1 = thousand or q2 = thousand;
+
+explain (costs off)
+select * from
+ tenk1 join int4_tbl on f1 = twothousand,
+ int4(sin(1)) q1,
+ int4(sin(0)) q2
+where thousand = (q1 + q2);
+
+--
-- test join removal
--