Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf9094c4

Browse files
committed
Prevent generation of invalid plans for RIGHT or FULL joins with multiple
join clauses. The mergejoin executor wants all the join clauses to appearas merge quals, not as extra joinquals, for these kinds of joins. But theplanner would consider plans in which partially-sorted input paths wereused, leading to only some of the join clauses becoming merge quals.This is fine for inner/left joins, not fine for right/full joins.
1 parent15a6cd0 commitf9094c4

File tree

1 file changed

+52
-8
lines changed

1 file changed

+52
-8
lines changed

‎src/backend/optimizer/path/joinpath.c

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.62 2001/03/22 03:59:35 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.63 2001/04/15 00:48:17 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -290,20 +290,34 @@ match_unsorted_outer(Query *root,
290290
JoinTypejointype)
291291
{
292292
boolnestjoinOK;
293+
booluseallclauses;
293294
Path*bestinnerjoin;
294295
List*i;
295296

296297
/*
297-
* Nestloop only supports inner and left joins.
298+
* Nestloop only supports inner and left joins. Also, if we are doing
299+
* a right or full join, we must use *all* the mergeclauses as join
300+
* clauses, else we will not have a valid plan. (Although these two flags
301+
* are currently inverses, keep them separate for clarity and possible
302+
* future changes.)
298303
*/
299304
switch (jointype)
300305
{
301306
caseJOIN_INNER:
302307
caseJOIN_LEFT:
303308
nestjoinOK= true;
309+
useallclauses= false;
304310
break;
305-
default:
311+
caseJOIN_RIGHT:
312+
caseJOIN_FULL:
306313
nestjoinOK= false;
314+
useallclauses= true;
315+
break;
316+
default:
317+
elog(ERROR,"match_unsorted_outer: unexpected join type %d",
318+
(int)jointype);
319+
nestjoinOK= false;/* keep compiler quiet */
320+
useallclauses= false;
307321
break;
308322
}
309323

@@ -339,8 +353,8 @@ match_unsorted_outer(Query *root,
339353

340354
/*
341355
* Always consider a nestloop join with this outer and
342-
* cheapest-total-cost inner.Consider nestloops using the
343-
* cheapest-startup-cost inner as well, and the best
356+
* cheapest-total-cost inner.Consider nestloops using the
357+
* cheapest-startup-cost inner as well, and the best
344358
* innerjoin indexpath.
345359
*/
346360
add_path(joinrel, (Path*)
@@ -377,6 +391,8 @@ match_unsorted_outer(Query *root,
377391
/* Done with this outer path if no chance for a mergejoin */
378392
if (mergeclauses==NIL)
379393
continue;
394+
if (useallclauses&&length(mergeclauses)!=length(mergeclause_list))
395+
continue;
380396

381397
/* Compute the required ordering of the inner path */
382398
innersortkeys=make_pathkeys_for_mergeclauses(root,
@@ -402,13 +418,14 @@ match_unsorted_outer(Query *root,
402418

403419
/*
404420
* Look for presorted inner paths that satisfy the innersortkey
405-
* list or any truncation thereof.Here, we consider both cheap
406-
* startup cost and cheap total cost. Ignore
421+
* list --- or any truncation thereof, if we are allowed to build
422+
* a mergejoin using a subset of the merge clauses. Here, we
423+
* consider both cheap startup cost and cheap total cost. Ignore
407424
* innerrel->cheapest_total_path, since we already made a path
408425
* with it.
409426
*/
410427
num_sortkeys=length(innersortkeys);
411-
if (num_sortkeys>1)
428+
if (num_sortkeys>1&& !useallclauses)
412429
trialsortkeys=listCopy(innersortkeys);/* need modifiable copy */
413430
else
414431
trialsortkeys=innersortkeys;/* won't really truncate */
@@ -503,6 +520,11 @@ match_unsorted_outer(Query *root,
503520
}
504521
cheapest_startup_inner=innerpath;
505522
}
523+
/*
524+
* Don't consider truncated sortkeys if we need all clauses.
525+
*/
526+
if (useallclauses)
527+
break;
506528
}
507529
}
508530
}
@@ -532,8 +554,26 @@ match_unsorted_inner(Query *root,
532554
List*mergeclause_list,
533555
JoinTypejointype)
534556
{
557+
booluseallclauses;
535558
List*i;
536559

560+
switch (jointype)
561+
{
562+
caseJOIN_INNER:
563+
caseJOIN_LEFT:
564+
useallclauses= false;
565+
break;
566+
caseJOIN_RIGHT:
567+
caseJOIN_FULL:
568+
useallclauses= true;
569+
break;
570+
default:
571+
elog(ERROR,"match_unsorted_inner: unexpected join type %d",
572+
(int)jointype);
573+
useallclauses= false;/* keep compiler quiet */
574+
break;
575+
}
576+
537577
foreach(i,innerrel->pathlist)
538578
{
539579
Path*innerpath= (Path*)lfirst(i);
@@ -547,8 +587,12 @@ match_unsorted_inner(Query *root,
547587
mergeclauses=find_mergeclauses_for_pathkeys(root,
548588
innerpath->pathkeys,
549589
mergeclause_list);
590+
591+
/* Done with this inner path if no chance for a mergejoin */
550592
if (mergeclauses==NIL)
551593
continue;
594+
if (useallclauses&&length(mergeclauses)!=length(mergeclause_list))
595+
continue;
552596

553597
/* Compute the required ordering of the outer path */
554598
outersortkeys=make_pathkeys_for_mergeclauses(root,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp