Commit 1fc04e0b authored by unknown's avatar unknown
Browse files

Fix for BUG#4480: In joins with SELECT_STRAIGHT_JOIN re-order tables by outer join dependency,

so we read dependent tables after tables they depend on (this is needed for outer joins)


mysql-test/r/join_outer.result:
  Test for BUG#4480
mysql-test/t/join_outer.test:
  Test for BUG#4480
parent de5ce111
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -853,4 +853,19 @@ id select_type table type possible_keys key key_len ref rows Extra
1	SIMPLE	t1	const	PRIMARY	PRIMARY	4	const	1	Using index
1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	
1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	2	
drop table t1,t2;
create table t1 (a int, b int);
insert into t1 values (1,1),(2,2),(3,3);
create table t2 (a int, b int);
insert into t2 values (1,1), (2,2);
select * from t2 right join t1 on t2.a=t1.a;
a	b	a	b
1	1	1	1
2	2	2	2
NULL	NULL	3	3
select straight_join * from t2 right join t1 on t2.a=t1.a;
a	b	a	b
1	1	1	1
2	2	2	2
NULL	NULL	3	3
DROP TABLE t0,t1,t2,t3;
+10 −0
Original line number Diff line number Diff line
@@ -606,4 +606,14 @@ INSERT INTO t1 VALUES (0);
SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1;
EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1;

# Test for BUG#4480
drop table t1,t2;
create table t1 (a int, b int);
insert into t1 values (1,1),(2,2),(3,3);
create table t2 (a int, b int);
insert into t2 values (1,1), (2,2);

select * from t2 right join t1 on t2.a=t1.a;
select straight_join * from t2 right join t1 on t2.a=t1.a;

DROP TABLE t0,t1,t2,t3;
+32 −10
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ static void best_extension_by_limited_search(JOIN *join,
                                             uint prune_level);
static uint determine_search_depth(JOIN* join);
static int join_tab_cmp(const void* ptr1, const void* ptr2);
static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
/*
  TODO: 'find_best' is here only temporarily until 'greedy_search' is
  tested and approved.
@@ -3678,22 +3679,26 @@ choose_plan(JOIN *join, table_map join_tables)
{
  uint search_depth= join->thd->variables.optimizer_search_depth;
  uint prune_level=  join->thd->variables.optimizer_prune_level;

  bool straight_join= join->select_options & SELECT_STRAIGHT_JOIN;
  DBUG_ENTER("choose_plan");

  if (join->select_options & SELECT_STRAIGHT_JOIN)
  {
    optimize_straight_join(join, join_tables);
  }
  else
  {
  /*
      Heuristic: pre-sort all access plans with respect to the number of
    if (SELECT_STRAIGHT_JOIN option is set)
      reorder tables so dependent tables come after tables they depend 
      on, otherwise keep tables in the order they were specified in the query 
    else
      Apply heuristic: pre-sort all access plans with respect to the number of
      records accessed.
  */
  qsort(join->best_ref + join->const_tables, join->tables - join->const_tables,
          sizeof(JOIN_TAB*), join_tab_cmp);
        sizeof(JOIN_TAB*), straight_join?join_tab_cmp_straight:join_tab_cmp);
  
  if (straight_join)
  {
    optimize_straight_join(join, join_tables);
  }
  else
  {
    if (search_depth == MAX_TABLES+2)
    { /*
        TODO: 'MAX_TABLES+2' denotes the old implementation of find_best before
@@ -3750,6 +3755,23 @@ join_tab_cmp(const void* ptr1, const void* ptr2)
}


/* 
  Same as join_tab_cmp, but for use with SELECT_STRAIGHT_JOIN.
*/

static int
join_tab_cmp_straight(const void* ptr1, const void* ptr2)
{
  JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
  JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;

  if (jt1->dependent & jt2->table->map)
    return 1;
  if (jt2->dependent & jt1->table->map)
    return -1;
  return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
}

/*
  Heuristic procedure to automatically guess a reasonable degree of
  exhaustiveness for the greedy search procedure.