Commit 75865af6 authored by unknown's avatar unknown
Browse files

Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-5.0-opt

into  rurik.mysql.com:/home/igor/mysql-5.0-opt

parents da2e23f1 f121994d
Loading
Loading
Loading
Loading
+40 −2
Original line number Diff line number Diff line
@@ -2328,9 +2328,9 @@ explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t3	system	NULL	NULL	NULL	NULL	0	const row not found
1	SIMPLE	t4	const	id4	NULL	NULL	NULL	1	
1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1	
1	SIMPLE	t4	ALL	id4	NULL	NULL	NULL	1	Using where
1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1	Using where
select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
id1	id2	id3	id4	id44
@@ -3479,3 +3479,41 @@ Warning 1466 Leading spaces are removed from name ' a '
execute stmt;
a 
1
CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
CREATE TABLE t2 (c int NOT NULL, INDEX idx(c));
INSERT INTO t2 VALUES
(1), (1), (1), (1), (1), (1), (1), (1),
(2), (2), (2), (2),
(3), (3),
(4);
EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	const	PRIMARY	PRIMARY	4	const	1	
1	SIMPLE	t2	ref	idx	idx	4	const	7	Using index
EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	const	PRIMARY	PRIMARY	4	const	1	
1	SIMPLE	t2	ref	idx	idx	4	const	1	Using index
DROP TABLE t1, t2;
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int);
INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2);
CREATE TABLE t2 (b int, c INT, INDEX idx1(b));
INSERT INTO t2 VALUES (2,1), (3,2);
CREATE TABLE t3 (d int,  e int, INDEX idx1(d));
INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50);
EXPLAIN
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
WHERE t1.id=2;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	const	PRIMARY	PRIMARY	4	const	1	
1	SIMPLE	t2	const	idx1	NULL	NULL	NULL	1	
1	SIMPLE	t3	ref	idx1	idx1	5	const	3	Using where
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
WHERE t1.id=2;
id	a	b	c	d	e
2	NULL	NULL	NULL	2	10
2	NULL	NULL	NULL	2	20
2	NULL	NULL	NULL	2	40
2	NULL	NULL	NULL	2	50
DROP TABLE t1,t2,t3;
+41 −0
Original line number Diff line number Diff line
@@ -2957,3 +2957,44 @@ SELECT 0.9888889889 * 1.011111411911;
#
prepare stmt from 'select 1 as " a "';
execute stmt;

#
# Bug #21390: wrong estimate of rows after elimination of const tables
#

CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);

CREATE TABLE t2 (c int NOT NULL, INDEX idx(c));
INSERT INTO t2 VALUES
  (1), (1), (1), (1), (1), (1), (1), (1),
  (2), (2), (2), (2),
  (3), (3),
  (4);

EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1;
EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4;

DROP TABLE t1, t2;

#
# No matches for a join after substitution of a const table
#

CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int);
INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2);

CREATE TABLE t2 (b int, c INT, INDEX idx1(b));
INSERT INTO t2 VALUES (2,1), (3,2);

CREATE TABLE t3 (d int,  e int, INDEX idx1(d));
INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50);

EXPLAIN
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
  WHERE t1.id=2;
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
  WHERE t1.id=2;


DROP TABLE t1,t2,t3;
+54 −24
Original line number Diff line number Diff line
@@ -2205,6 +2205,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
  int ref_changed;
  do
  {
  more_const_tables_found:
    ref_changed = 0;
    found_ref=0;

@@ -2216,6 +2217,30 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
    for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
    {
      table=s->table;

      /* 
        If equi-join condition by a key is null rejecting and after a
        substitution of a const table the key value happens to be null
        then we can state that there are no matches for this equi-join.
      */  
      if ((keyuse= s->keyuse) && *s->on_expr_ref)
      {
        while (keyuse->table == table)
        {
          if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
              keyuse->val->is_null() && keyuse->null_rejecting)
          {
            s->type= JT_CONST;
            mark_as_null_row(table);
            found_const_table_map|= table->map;
	    join->const_table_map|= table->map;
	    set_position(join,const_count++,s,(KEYUSE*) 0);
            goto more_const_tables_found;
           }
	  keyuse++;
        }
      }

      if (s->dependent)				// If dependent on some table
      {
	// All dep. must be constants
@@ -2266,10 +2291,11 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
	  } while (keyuse->table == table && keyuse->key == key);

	  if (eq_part.is_prefix(table->key_info[key].key_parts) &&
	      ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
	       HA_NOSAME) &&
              !table->fulltext_searched && 
              !table->pos_in_table_list->embedding)
	  {
            if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY))
                 == HA_NOSAME)
            {
	      if (const_ref == eq_part)
	      {					// Found everything for ref.
@@ -2294,6 +2320,9 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
	      else
	        found_ref|= refs;      // Table is const if all refs are const
	    }
            else if (const_ref == eq_part)
              s->const_keys.set_bit(key);
          }
	}
      }
    }
@@ -2696,7 +2725,8 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
    We use null_rejecting in add_not_null_conds() to add
    'othertbl.field IS NOT NULL' to tab->select_cond.
  */
  (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC) &&
  (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC ||
                                   cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
                                  ((*value)->type() == Item::FIELD_ITEM) &&
                                  ((Item_field*)*value)->field->maybe_null());
  (*key_fields)++;
@@ -3461,7 +3491,7 @@ best_access_path(JOIN *join,
                                                 keyuse->used_tables));
            if (tmp < best_prev_record_reads)
            {
              best_part_found_ref= keyuse->used_tables;
              best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
              best_prev_record_reads= tmp;
            }
            if (rec > keyuse->ref_table_rows)