aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-01-08 16:47:35 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-01-08 16:47:35 +0000
commit757dfd6327b6abeb592aef8c689d59faf6b3f82e (patch)
tree42baf330fc046e6afe5bb7010db51fea2aa48412
parent9c1443e66fa30357365ab2225ff6543721641eb8 (diff)
downloadpostgresql-757dfd6327b6abeb592aef8c689d59faf6b3f82e.tar.gz
postgresql-757dfd6327b6abeb592aef8c689d59faf6b3f82e.zip
Tweak joinlist creation to avoid generating useless one-element subproblems
when collapsing of JOIN trees is stopped by join_collapse_limit. For instance a list of 11 LEFT JOINs with limit 8 now produces something like ((1 2 3 4 5 6 7 8) 9 10 11 12) instead of (((1 2 3 4 5 6 7 8) (9)) 10 11 12) The latter structure is really only required for a FULL JOIN. Noted while studying an example from Shane Ambler.
-rw-r--r--src/backend/optimizer/plan/initsplan.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 9604bf8e6db..05e2de6e3fd 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.123.2.1 2006/12/07 19:33:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.123.2.2 2007/01/08 16:47:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -402,13 +402,34 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
* except at a FULL JOIN or where join_collapse_limit would be
* exceeded.
*/
- if (j->jointype != JOIN_FULL &&
- (list_length(leftjoinlist) + list_length(rightjoinlist) <=
- join_collapse_limit))
+ if (j->jointype == JOIN_FULL)
+ {
+ /* force the join order exactly at this node */
+ joinlist = list_make1(list_make2(leftjoinlist, rightjoinlist));
+ }
+ else if (list_length(leftjoinlist) + list_length(rightjoinlist) <=
+ join_collapse_limit)
+ {
+ /* OK to combine subproblems */
joinlist = list_concat(leftjoinlist, rightjoinlist);
+ }
else
- /* force the join order at this node */
- joinlist = list_make1(list_make2(leftjoinlist, rightjoinlist));
+ {
+ /* can't combine, but needn't force join order above here */
+ Node *leftpart,
+ *rightpart;
+
+ /* avoid creating useless 1-element sublists */
+ if (list_length(leftjoinlist) == 1)
+ leftpart = (Node *) linitial(leftjoinlist);
+ else
+ leftpart = (Node *) leftjoinlist;
+ if (list_length(rightjoinlist) == 1)
+ rightpart = (Node *) linitial(rightjoinlist);
+ else
+ rightpart = (Node *) rightjoinlist;
+ joinlist = list_make2(leftpart, rightpart);
+ }
}
else
{