diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index d04a1aaf6a2..f5349320cdc 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5615,4 +5615,64 @@ a c SET SESSION join_cache_level = DEFAULT; SET SESSION join_buffer_size = DEFAULT; DROP TABLE t1,t2; +# +# Bug #671901: hash join using a ref to a varchar field +# +CREATE TABLE t1 ( +v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, +i int DEFAULT NULL +); +INSERT INTO t1 VALUES +('k',8), ('abcdefjh',-575340544), ('f',77), ('because', 2), ('f',-517472256), +('abcdefjhj',5), ('z',7); +CREATE TABLE t2 ( +v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, +i int DEFAULT NULL, +INDEX idx (v) +); +INSERT INTO t2 VALUES +('did',5), ('was',-1631322112), ('are',3), ('abcdefjhjk',3), +('abcdefjhjk',4), ('tell',-824573952), ('t',0),('v',-1711013888), +('abcdefjhjk',1015414784), ('or',4), ('now',0), ('abcdefjhjk',-32702464), +('abcdefjhjk',4), ('time',1078394880), ('f',4), ('m',-1845559296), +('ff', 5), ('abcdefjhjk',-1074397184); +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t2 ref idx idx 13 test.t1.v 2 +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +v i +f 4 +f 4 +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 +1 SIMPLE t2 ref idx idx 13 func 2 Using index condition +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); +v i +f 5 +f 5 +SET SESSION join_cache_level = 4; +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t2 ref idx idx 13 test.t1.v 2 Using join buffer (flat, BNLH join) +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +v i +f 4 +f 4 +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 +1 SIMPLE t2 ref idx idx 13 func 2 Using where; Using join buffer (flat, BNLH join) +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); +v i +f 5 +f 5 +SET SESSION join_cache_level = DEFAULT; +DROP TABLE t1,t2; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 16bd2d515ad..615c8068c0f 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -2315,5 +2315,48 @@ SET SESSION join_buffer_size = DEFAULT; DROP TABLE t1,t2; +--echo # +--echo # Bug #671901: hash join using a ref to a varchar field +--echo # + +CREATE TABLE t1 ( + v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, + i int DEFAULT NULL +); +INSERT INTO t1 VALUES + ('k',8), ('abcdefjh',-575340544), ('f',77), ('because', 2), ('f',-517472256), + ('abcdefjhj',5), ('z',7); + +CREATE TABLE t2 ( + v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, + i int DEFAULT NULL, + INDEX idx (v) +); +INSERT INTO t2 VALUES + ('did',5), ('was',-1631322112), ('are',3), ('abcdefjhjk',3), + ('abcdefjhjk',4), ('tell',-824573952), ('t',0),('v',-1711013888), + ('abcdefjhjk',1015414784), ('or',4), ('now',0), ('abcdefjhjk',-32702464), + ('abcdefjhjk',4), ('time',1078394880), ('f',4), ('m',-1845559296), + ('ff', 5), ('abcdefjhjk',-1074397184); + +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); + +SET SESSION join_cache_level = 4; +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); + +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_select.h b/sql/sql_select.h index 363aac90e95..522f1543ad6 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -2431,6 +2431,15 @@ class store_key_field: public store_key TABLE *table= copy_field.to_field->table; my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); + + /* + It looks like the next statement is needed only for a simplified + hash function over key values used now in BNLH join. + When the implementation of this function will be replaced for a proper + full version this statement probably should be removed. + */ + bzero(copy_field.to_ptr,copy_field.to_length); + copy_field.do_copy(©_field); dbug_tmp_restore_column_map(table->write_set, old_map); null_key= to_field->is_null(); @@ -2464,6 +2473,15 @@ public: my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); int res= FALSE; + + /* + It looks like the next statement is needed only for a simplified + hash function over key values used now in BNLH join. + When the implementation of this function will be replaced for a proper + full version this statement probably should be removed. + */ + to_field->reset(); + if (use_value) item->save_val(to_field); else