mirror of
https://github.com/postgres/postgres.git
synced 2025-05-05 09:19:17 +03:00
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.
This commit is contained in:
parent
9c1443e66f
commit
757dfd6327
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* 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_concat(leftjoinlist, rightjoinlist);
|
|
||||||
else
|
|
||||||
/* force the join order at this node */
|
|
||||||
joinlist = list_make1(list_make2(leftjoinlist, rightjoinlist));
|
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
|
||||||
|
{
|
||||||
|
/* 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
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user