diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2011-12-16 03:46:04 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2011-12-16 03:46:04 +0400 |
commit | 4dd456c220f702aeb0c9c32a52d7fe5c05ddca14 (patch) | |
tree | 3bed5696f87e4f9c2f856c5f5e4a1b88f3da8d4b | |
parent | 876f16afbb038992bc984960821d8bb8a830cc6f (diff) | |
parent | 04e9004fa32c9066788db6f2633022a912f349e2 (diff) | |
download | mariadb-git-4dd456c220f702aeb0c9c32a52d7fe5c05ddca14.tar.gz |
Merge
-rw-r--r-- | mysql-test/r/subselect3.result | 4 | ||||
-rw-r--r-- | mysql-test/r/subselect3_jcl6.result | 4 | ||||
-rw-r--r-- | mysql-test/r/subselect_sj.result | 27 | ||||
-rw-r--r-- | mysql-test/r/subselect_sj_jcl6.result | 27 | ||||
-rw-r--r-- | mysql-test/t/subselect_sj.test | 29 | ||||
-rw-r--r-- | sql/sql_select.cc | 33 | ||||
-rw-r--r-- | sql/sql_select.h | 11 |
7 files changed, 121 insertions, 14 deletions
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 7d13bce1f85..8c55df90f62 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -1274,11 +1274,11 @@ insert into t1 select A.a, B.a, 'filler' from t0 A, t0 B; create table t2 as select * from t1; explain select * from t2 where a in (select b from t1 where a=3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan +1 PRIMARY t1 ref a a 5 const 8 Using index; LooseScan 1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) explain select * from t2 where (b,a) in (select a,b from t1 where a=3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan +1 PRIMARY t1 ref a a 5 const 8 Using index; LooseScan 1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) drop table t1,t2; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result index 5ad5878623d..66b305bcf14 100644 --- a/mysql-test/r/subselect3_jcl6.result +++ b/mysql-test/r/subselect3_jcl6.result @@ -1283,11 +1283,11 @@ insert into t1 select A.a, B.a, 'filler' from t0 A, t0 B; create table t2 as select * from t1; explain select * from t2 where a in (select b from t1 where a=3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan +1 PRIMARY t1 ref a a 5 const 8 Using index; LooseScan 1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) explain select * from t2 where (b,a) in (select a,b from t1 where a=3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan +1 PRIMARY t1 ref a a 5 const 8 Using index; LooseScan 1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) drop table t1,t2; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index a7b3cffb8d2..82804681eef 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -2149,4 +2149,31 @@ a a SET optimizer_prune_level=DEFAULT; SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +# +# BUG#901399: Wrong result (extra row) with semijoin=ON, materialization=OFF, optimizer_prune_level=0 +# +set @opl_901399= @@optimizer_prune_level; +set @os_091399= @@optimizer_switch; +SET optimizer_prune_level=0; +SET optimizer_switch = 'materialization=off'; +CREATE TABLE t1 ( c INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES +(0),(1),(2),(3),(4),(5), +(6),(7),(8),(9),(10),(11),(12); +CREATE TABLE t2 ( a INT, b INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (3,20),(2,21),(3,22); +SELECT * +FROM t1 AS alias1, t1 AS alias2 +WHERE ( alias1.c, alias2.c ) +IN ( +SELECT alias3.a, alias3.a +FROM t2 AS alias3, t2 alias4 +WHERE alias3.b = alias4.b +); +c c +2 2 +3 3 +set optimizer_prune_level= @opl_901399; +set optimizer_switch= @os_091399; +DROP TABLE t1,t2; set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 8de5af4cf56..7a3fe20a4e5 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2155,6 +2155,33 @@ a a SET optimizer_prune_level=DEFAULT; SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +# +# BUG#901399: Wrong result (extra row) with semijoin=ON, materialization=OFF, optimizer_prune_level=0 +# +set @opl_901399= @@optimizer_prune_level; +set @os_091399= @@optimizer_switch; +SET optimizer_prune_level=0; +SET optimizer_switch = 'materialization=off'; +CREATE TABLE t1 ( c INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES +(0),(1),(2),(3),(4),(5), +(6),(7),(8),(9),(10),(11),(12); +CREATE TABLE t2 ( a INT, b INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (3,20),(2,21),(3,22); +SELECT * +FROM t1 AS alias1, t1 AS alias2 +WHERE ( alias1.c, alias2.c ) +IN ( +SELECT alias3.a, alias3.a +FROM t2 AS alias3, t2 alias4 +WHERE alias3.b = alias4.b +); +c c +2 2 +3 3 +set optimizer_prune_level= @opl_901399; +set optimizer_switch= @os_091399; +DROP TABLE t1,t2; set optimizer_switch=@subselect_sj_tmp; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index 4f8ed7f1643..55074787700 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1967,5 +1967,34 @@ SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # BUG#901399: Wrong result (extra row) with semijoin=ON, materialization=OFF, optimizer_prune_level=0 +--echo # +set @opl_901399= @@optimizer_prune_level; +set @os_091399= @@optimizer_switch; +SET optimizer_prune_level=0; +SET optimizer_switch = 'materialization=off'; + +CREATE TABLE t1 ( c INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES + (0),(1),(2),(3),(4),(5), + (6),(7),(8),(9),(10),(11),(12); +CREATE TABLE t2 ( a INT, b INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (3,20),(2,21),(3,22); + +SELECT * +FROM t1 AS alias1, t1 AS alias2 +WHERE ( alias1.c, alias2.c ) + IN ( + SELECT alias3.a, alias3.a + FROM t2 AS alias3, t2 alias4 + WHERE alias3.b = alias4.b + ); +set optimizer_prune_level= @opl_901399; +set optimizer_switch= @os_091399; + +DROP TABLE t1,t2; + + # The following command must be the last one the file set optimizer_switch=@subselect_sj_tmp; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7a8f4e854ec..2c17e5dbff6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -61,7 +61,7 @@ static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse, bool skip_unprefixed_keyparts); static int sort_keyuse(KEYUSE *a,KEYUSE *b); static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, - table_map used_tables); + bool allow_full_scan, table_map used_tables); void best_access_path(JOIN *join, JOIN_TAB *s, table_map remaining_tables, uint idx, bool disable_jbuf, double record_count, @@ -3313,7 +3313,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, s->type= JT_CONST; join->const_table_map|=table->map; set_position(join,const_count++,s,start_keyuse); - if (create_ref_for_key(join, s, start_keyuse, + if (create_ref_for_key(join, s, start_keyuse, FALSE, found_const_table_map)) goto error; if ((tmp=join_read_const_table(s, @@ -7068,15 +7068,21 @@ get_best_combination(JOIN *join) if (j->type == JT_SYSTEM) goto loop_end; - if ( !(keyuse= join->best_positions[tablenr].key) || - (join->best_positions[tablenr].sj_strategy == SJ_OPT_LOOSE_SCAN)) + if ( !(keyuse= join->best_positions[tablenr].key)) { j->type=JT_ALL; - j->index= join->best_positions[tablenr].loosescan_picker.loosescan_key; if (tablenr != join->const_tables) join->full_join=1; } - else if (create_ref_for_key(join, j, keyuse, used_tables)) + + /*if (join->best_positions[tablenr].sj_strategy == SJ_OPT_LOOSE_SCAN) + { + DBUG_ASSERT(!keyuse || keyuse->key == + join->best_positions[tablenr].loosescan_picker.loosescan_key); + j->index= join->best_positions[tablenr].loosescan_picker.loosescan_key; + }*/ + + if (keyuse && create_ref_for_key(join, j, keyuse, TRUE, used_tables)) DBUG_RETURN(TRUE); // Something went wrong if ((j->type == JT_REF || j->type == JT_EQ_REF) && @@ -7249,7 +7255,8 @@ static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables) } static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, - KEYUSE *org_keyuse, table_map used_tables) + KEYUSE *org_keyuse, bool allow_full_scan, + table_map used_tables) { uint keyparts, length, key; TABLE *table; @@ -7307,6 +7314,14 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, keyuse++; } while (keyuse->table == table && keyuse->key == key); } /* not ftkey */ + + if (!keyparts && allow_full_scan) + { + /* It's a LooseIndexScan strategy scanning whole index */ + j->type= JT_ALL; + j->index= key; + DBUG_RETURN(FALSE); + } /* set up fieldref */ j->ref.key_parts= keyparts; @@ -15188,7 +15203,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) join_tab->loosescan_match_tab->found_match) { KEY *key= join_tab->table->key_info + join_tab->index; - key_copy(join_tab->loosescan_buf, info->record, key, + key_copy(join_tab->loosescan_buf, join_tab->table->record[0], key, join_tab->loosescan_key_len); skip_over= TRUE; } @@ -17571,7 +17586,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit_arg, while (keyuse->key != new_ref_key && keyuse->table == tab->table) keyuse++; - if (create_ref_for_key(tab->join, tab, keyuse, + if (create_ref_for_key(tab->join, tab, keyuse, FALSE, tab->join->const_table_map)) goto use_filesort; diff --git a/sql/sql_select.h b/sql/sql_select.h index 99ed8abc04b..ad4607a4b78 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -296,7 +296,16 @@ typedef struct st_join_table { double partial_join_cardinality; table_map dependent,key_dependent; - uint use_quick,index; + /* + 1 - use quick select + 2 - use "Range checked for each record" + */ + uint use_quick; + /* + Index to use. Note: this is valid only for 'index' access, but not range or + ref access. + */ + uint index; uint status; ///< Save status for cache uint used_fields; ulong used_fieldlength; |