Commit 19f9376b authored by Tom Lane's avatar Tom Lane

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.
parent 9a9a143a
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.126 2007/01/05 22:19:31 momjian Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.127 2007/01/08 16:47:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -402,13 +402,34 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, ...@@ -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 * except at a FULL JOIN or where join_collapse_limit would be
* exceeded. * exceeded.
*/ */
if (j->jointype != JOIN_FULL && if (j->jointype == JOIN_FULL)
(list_length(leftjoinlist) + list_length(rightjoinlist) <= {
join_collapse_limit)) /* 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); joinlist = list_concat(leftjoinlist, rightjoinlist);
}
else 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 else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment