My recent fix for semijoin planning didn't actually work for a semijoin with a
RHS that can't be unique-ified --- join_is_legal has to check that before deciding to build a join, else we'll have an unimplementable joinrel. Per report from Greg Stark.
This commit is contained in:
parent
5f77b1ac51
commit
213256cfa9
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.95 2008/11/22 22:47:06 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.96 2008/11/28 19:29:07 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -420,11 +420,13 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||||
reversed = true;
|
reversed = true;
|
||||||
}
|
}
|
||||||
else if (sjinfo->jointype == JOIN_SEMI &&
|
else if (sjinfo->jointype == JOIN_SEMI &&
|
||||||
bms_equal(sjinfo->syn_righthand, rel2->relids))
|
bms_equal(sjinfo->syn_righthand, rel2->relids) &&
|
||||||
|
create_unique_path(root, rel2, rel2->cheapest_total_path,
|
||||||
|
sjinfo) != NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* For a semijoin, we can join the RHS to anything else by
|
* For a semijoin, we can join the RHS to anything else by
|
||||||
* unique-ifying the RHS.
|
* unique-ifying the RHS (if the RHS can be unique-ified).
|
||||||
*/
|
*/
|
||||||
if (match_sjinfo)
|
if (match_sjinfo)
|
||||||
return false; /* invalid join path */
|
return false; /* invalid join path */
|
||||||
|
@ -432,7 +434,9 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||||
reversed = false;
|
reversed = false;
|
||||||
}
|
}
|
||||||
else if (sjinfo->jointype == JOIN_SEMI &&
|
else if (sjinfo->jointype == JOIN_SEMI &&
|
||||||
bms_equal(sjinfo->syn_righthand, rel1->relids))
|
bms_equal(sjinfo->syn_righthand, rel1->relids) &&
|
||||||
|
create_unique_path(root, rel1, rel1->cheapest_total_path,
|
||||||
|
sjinfo) != NULL)
|
||||||
{
|
{
|
||||||
/* Reversed semijoin case */
|
/* Reversed semijoin case */
|
||||||
if (match_sjinfo)
|
if (match_sjinfo)
|
||||||
|
@ -664,7 +668,10 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
|
||||||
/*
|
/*
|
||||||
* If we know how to unique-ify the RHS and one input rel is
|
* If we know how to unique-ify the RHS and one input rel is
|
||||||
* exactly the RHS (not a superset) we can consider unique-ifying
|
* exactly the RHS (not a superset) we can consider unique-ifying
|
||||||
* it and then doing a regular join.
|
* it and then doing a regular join. (The create_unique_path
|
||||||
|
* check here is probably redundant with what join_is_legal did,
|
||||||
|
* but if so the check is cheap because it's cached. So test
|
||||||
|
* anyway to be sure.)
|
||||||
*/
|
*/
|
||||||
if (bms_equal(sjinfo->syn_righthand, rel2->relids) &&
|
if (bms_equal(sjinfo->syn_righthand, rel2->relids) &&
|
||||||
create_unique_path(root, rel2, rel2->cheapest_total_path,
|
create_unique_path(root, rel2, rel2->cheapest_total_path,
|
||||||
|
|
Loading…
Reference in New Issue