Thread: ERROR: failed to build any 4-way joins
Test suite (as simple as I can produce): CREATE TABLE foo (a int, b int); INSERT INTO foo VALUES (1,2); INSERT INTO foo VALUES (2,3); INSERT INTO foo VALUES (3,3); CREATE VIEW fooview AS SELECT f1.a AS a_for_max_b FROM ( SELECT MAX(foo.b) AS MaxB FROM foo ) f2 INNER JOIN foo f1 ON f2.MaxB = f1.b; And this query fails: SELECT * FROM fooview fv1 LEFT OUTER JOIN fooview fv2 ON TRUE = TRUE; It also fails with RIGHT join, but it doesn't fail with INNER or FULL joins. If view is defined (essentially the same) as CREATE VIEW fooview AS SELECT f1.a AS a_for_max_b FROM foo f1 WHERE f1.b = (SELECT MAX(f2.b) FROM foo f2); then all is ok. -- Teodor Sigaev E-mail: teodor@sigaev.ru WWW: http://www.sigaev.ru/
Sorry, versions are 8.2 & 8.3. 8.1 works well -- Teodor Sigaev E-mail: teodor@sigaev.ru WWW: http://www.sigaev.ru/
Teodor Sigaev <teodor@sigaev.ru> writes: > Test suite (as simple as I can produce): Mmm, sweet :-(. There is only one legal way to form the outer join, but make_rels_by_joins() doesn't try it because have_relevant_joinclause() says there is no relevant joinclause ... as indeed there is not, the "true = true" thing having been optimized away. I guess we need a hack to treat empty outer join conditions specially. > Sorry, versions are 8.2 & 8.3. 8.1 works well Right, not a problem before 8.2 because outer join order was driven by the syntax instead of by searching for a good join order. Also, you need at least two base relations on each side of the outer join, else the "last ditch" case in make_rels_by_joins() finds the join. regards, tom lane
I wrote: > I guess we need a hack > to treat empty outer join conditions specially. Actually, it can happen with non-empty join conditions too, if the join condition doesn't mention the outer side; for instance, using your example explain SELECT * from fooview fv1 LEFT OUTER JOIN fooview fv2 on fv2.a_for_max_b < 10; So my original thoughts of a narrow special case for "OUTER JOIN ON TRUE" went up in smoke, and I ended up just having have_relevant_joinclause() troll for relevant outer joins all the time. This probably isn't going to cost enough planning time to matter, anyway. regards, tom lane
> went up in smoke, and I ended up just having have_relevant_joinclause() Thank you a lot, I was near around it :) -- Teodor Sigaev E-mail: teodor@sigaev.ru WWW: http://www.sigaev.ru/