Commit bcbde8af authored by igor@rurik.mysql.com's avatar igor@rurik.mysql.com

sql_select.cc:

  Fixed bug #12144.
  Added an optimization that avoids key access with null keys for the 'ref'
  method when used in outer joins. The regilar optimization with adding
  IS NOT NULL expressions is not applied for outer join on expressions as
  the predicates of these expressions are not pushed down in 4.1.
null_key.result, null_key.test:
  Added a test case for bug #12144.
parent ef3bc773
...@@ -364,3 +364,34 @@ select * from t1; ...@@ -364,3 +364,34 @@ select * from t1;
id id2 id id2
1 1 1 1
drop table t1; drop table t1;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int, b int, INDEX idx(a));
CREATE TABLE t3 (b int, INDEX idx(b));
INSERT INTO t1 VALUES (1), (2), (3), (4);
INSERT INTO t2 VALUES (1, 1), (3, 1);
INSERT INTO t3 VALUES
(NULL), (NULL), (NULL), (NULL), (NULL),
(NULL), (NULL), (NULL), (NULL), (NULL),
(2);
ANALYZE table t1, t2, t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
test.t3 analyze status OK
EXPLAIN SELECT SQL_CALC_FOUND_ROWS * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
LEFT JOIN t3 ON t2.b=t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
1 SIMPLE t2 ref idx idx 5 test.t1.a 1
1 SIMPLE t3 ref idx idx 5 test.t2.b 1 Using index
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
LEFT JOIN t3 ON t2.b=t3.b;
a a b b
1 1 1 NULL
2 NULL NULL NULL
3 3 1 NULL
4 NULL NULL NULL
SELECT FOUND_ROWS();
FOUND_ROWS()
4
DROP TABLE t1,t2,t3;
...@@ -191,3 +191,29 @@ select * from t1 where id2 is null or id2 > 0; ...@@ -191,3 +191,29 @@ select * from t1 where id2 is null or id2 > 0;
delete from t1 where id <=> NULL; delete from t1 where id <=> NULL;
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Test for bug #12144: optimizations for key access with null keys
# used for outer joins
#
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int, b int, INDEX idx(a));
CREATE TABLE t3 (b int, INDEX idx(b));
INSERT INTO t1 VALUES (1), (2), (3), (4);
INSERT INTO t2 VALUES (1, 1), (3, 1);
INSERT INTO t3 VALUES
(NULL), (NULL), (NULL), (NULL), (NULL),
(NULL), (NULL), (NULL), (NULL), (NULL),
(2);
ANALYZE table t1, t2, t3;
EXPLAIN SELECT SQL_CALC_FOUND_ROWS * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
LEFT JOIN t3 ON t2.b=t3.b;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LEFT JOIN t2 ON t1.a=t2.a
LEFT JOIN t3 ON t2.b=t3.b;
SELECT FOUND_ROWS();
DROP TABLE t1,t2,t3;
...@@ -2255,7 +2255,9 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, ...@@ -2255,7 +2255,9 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
*/ */
(*key_fields)->null_rejecting= (cond->functype() == Item_func::EQ_FUNC) && (*key_fields)->null_rejecting= (cond->functype() == Item_func::EQ_FUNC) &&
((*value)->type() == Item::FIELD_ITEM) && ((*value)->type() == Item::FIELD_ITEM) &&
((Item_field*)*value)->field->maybe_null();
(((Item_field*)*value)->field->maybe_null() ||
((Item_field *)*value)->field->table->maybe_null);
(*key_fields)++; (*key_fields)++;
} }
...@@ -6310,6 +6312,11 @@ join_read_always_key(JOIN_TAB *tab) ...@@ -6310,6 +6312,11 @@ join_read_always_key(JOIN_TAB *tab)
int error; int error;
TABLE *table= tab->table; TABLE *table= tab->table;
for (uint i= 0 ; i < tab->ref.key_parts ; i++)
{
if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
return -1;
}
if (!table->file->inited) if (!table->file->inited)
table->file->ha_index_init(tab->ref.key); table->file->ha_index_init(tab->ref.key);
if (cp_buffer_from_ref(tab->join->thd, &tab->ref)) if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment