diff options
| author | Tom Lane | 2012-04-13 19:32:34 +0000 |
|---|---|---|
| committer | Tom Lane | 2012-04-13 20:07:17 +0000 |
| commit | e3ffd05b02468b1a53de31a322cedf195576a625 (patch) | |
| tree | 5631a32e6f9275af24b8382f6c776c56b16aa8ad /src/test | |
| parent | c0cc526e8b1e821dfced692a68e4c8978c2bdbc1 (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.out | 51 | ||||
| -rw-r--r-- | src/test/regress/sql/join.sql | 18 |
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 -- |
