diff options
author | unknown <sanja@montyprogram.com> | 2013-11-11 22:47:04 +0200 |
---|---|---|
committer | unknown <sanja@montyprogram.com> | 2013-11-11 22:47:04 +0200 |
commit | 3a75900b91ffb4d49396d8f83e0b55b392e83a2a (patch) | |
tree | e21a66a326a380ae8d56859ed4f06a16fce20d92 | |
parent | 8f0be1ad7c2f13a7fd96889bde3402e9a723fc33 (diff) | |
parent | dfed447888e1ab71ec0c80b61459bde6ee6eaf66 (diff) | |
download | mariadb-git-3a75900b91ffb4d49396d8f83e0b55b392e83a2a.tar.gz |
merge 5.5->10.0-base
-rw-r--r-- | client/mysqltest.cc | 4 | ||||
-rw-r--r-- | mysql-test/r/func_equal.result | 44 | ||||
-rw-r--r-- | mysql-test/r/view.result | 31 | ||||
-rw-r--r-- | mysql-test/suite/mtr2/overlay.inc | 2 | ||||
-rw-r--r-- | mysql-test/suite/mtr2/single.result | 3 | ||||
-rw-r--r-- | mysql-test/suite/mtr2/single.test | 4 | ||||
-rw-r--r-- | mysql-test/t/func_equal.test | 52 | ||||
-rw-r--r-- | mysql-test/t/view.test | 28 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 36 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 1 | ||||
-rw-r--r-- | sql/item_subselect.cc | 38 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 19 | ||||
-rw-r--r-- | storage/myisam/mysql-test/mtr2/overlay.inc | 2 | ||||
-rw-r--r-- | storage/myisam/mysql-test/mtr2/single.rdiff | 12 |
14 files changed, 245 insertions, 31 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 6e3c8d1eab3..d040cbc210d 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -3041,6 +3041,10 @@ void open_file(const char *name) 5.try in basedir */ +#ifdef __WIN__ + fix_win_paths(curname, sizeof(curname)); +#endif + bool in_overlay= opt_overlay_dir && !strncmp(curname, opt_overlay_dir, overlay_dir_len); bool in_suiteir= opt_overlay_dir && !in_overlay && diff --git a/mysql-test/r/func_equal.result b/mysql-test/r/func_equal.result index 4750af6e8d8..02593529a91 100644 --- a/mysql-test/r/func_equal.result +++ b/mysql-test/r/func_equal.result @@ -42,3 +42,47 @@ select * from t1 where a in ('4828532208463511553'); a 4828532208463511553 drop table t1; +#End of 4.1 tests +# +# MDEV-5103: server crashed on singular Item_equal +# +CREATE TABLE `t1` ( +`tipo` enum('p','r') NOT NULL DEFAULT 'r', +`arquivo_id` bigint(20) unsigned NOT NULL DEFAULT '0', +`arquivo_md5` char(32) NOT NULL, +`conteudo` longblob NOT NULL, +`usuario` varchar(15) NOT NULL, +`datahora_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', +`tipo_arquivo` varchar(255) NOT NULL, +`nome_arquivo` varchar(255) NOT NULL, +`tamanho_arquivo` bigint(20) unsigned NOT NULL DEFAULT '0', +PRIMARY KEY (`tipo`,`arquivo_id`), +UNIQUE KEY `tipo` (`tipo`,`arquivo_md5`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; +INSERT INTO `t1` (`tipo`, `arquivo_id`, `arquivo_md5`, `conteudo`, `usuario`, `datahora_gmt`, `tipo_arquivo`, `nome_arquivo`, `tamanho_arquivo`) VALUES +('r', 1, 'ad18832202b199728921807033a8a515', '', 'rspadim', '2013-10-05 13:55:50', '001_cbr643', 'CBR6431677410201314132.ret', 21306); +CREATE TABLE `t2` ( +`tipo` enum('p','r') NOT NULL DEFAULT 'p', +`arquivo_id` bigint(20) NOT NULL DEFAULT '0', +`usuario` varchar(25) NOT NULL, +`datahora` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', +`erros` longblob NOT NULL, +`importados` bigint(20) unsigned NOT NULL DEFAULT '0', +`n_importados` bigint(20) unsigned NOT NULL DEFAULT '0', +PRIMARY KEY (`tipo`,`arquivo_id`,`datahora`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; +INSERT INTO `t2` (`tipo`, `arquivo_id`, `usuario`, `datahora`, `erros`, `importados`, `n_importados`) VALUES +('r', 1, 'rspadim', '2013-10-05 14:25:30', '', 32, 0); +SELECT +arquivo_id,usuario,datahora_gmt,tipo_arquivo,nome_arquivo,tamanho_arquivo +FROM t1 AS a +WHERE datahora_gmt>='0000-00-00 00:00:00' AND +datahora_gmt<='2013-10-07 02:59:59' AND tipo='r' AND +(tipo_arquivo,arquivo_id) NOT IN +(SELECT tipo_arquivo,arquivo_id +FROM t2 +WHERE (tipo_arquivo,arquivo_id)=(a.tipo_arquivo,a.arquivo_id)) +ORDER BY arquivo_id DESC; +arquivo_id usuario datahora_gmt tipo_arquivo nome_arquivo tamanho_arquivo +drop table t2, t1; +#End of 5.3 tests diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 746ab15553a..c111343e3be 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4921,6 +4921,37 @@ q 1 q q 1 q drop view v1; drop table t1,t2; +# +# MDEV-5153: Server crashes in Item_ref::fix_fields on 2nd execution +# of PS with LEFT JOIN and MERGE view or SELECT SQ +# +CREATE TABLE t1 (i1 INT, c1 VARCHAR(6)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +CREATE TABLE t2 (c2 VARCHAR(6)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('foobar'),('qux'); +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1 WHERE ( c1 ) IN ( SELECT c2 FROM t2 ) AND i1 <= 2 ; +PREPARE stmt FROM 'SELECT * FROM t1 LEFT JOIN v1 ON (v1.i1 = t1.i1)'; +EXECUTE stmt; +i1 c1 i1 c1 +1 foo NULL NULL +2 bar NULL NULL +EXECUTE stmt; +i1 c1 i1 c1 +1 foo NULL NULL +2 bar NULL NULL +drop view v1; +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1 WHERE ( c1, c1 ) IN ( SELECT c2, c2 FROM t2 ) AND i1 <= 2 ; +EXECUTE stmt; +i1 c1 i1 c1 +1 foo NULL NULL +2 bar NULL NULL +EXECUTE stmt; +i1 c1 i1 c1 +1 foo NULL NULL +2 bar NULL NULL +deallocate prepare stmt; +drop view v1; +drop table t1,t2; # ----------------------------------------------------------------- # -- End of 5.3 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/suite/mtr2/overlay.inc b/mysql-test/suite/mtr2/overlay.inc new file mode 100644 index 00000000000..669b8315fcb --- /dev/null +++ b/mysql-test/suite/mtr2/overlay.inc @@ -0,0 +1,2 @@ +select 2; + diff --git a/mysql-test/suite/mtr2/single.result b/mysql-test/suite/mtr2/single.result index 8f7c125196a..b0bd4a256d7 100644 --- a/mysql-test/suite/mtr2/single.result +++ b/mysql-test/suite/mtr2/single.result @@ -1,3 +1,6 @@ select 1; 1 1 +select 2; +2 +2 diff --git a/mysql-test/suite/mtr2/single.test b/mysql-test/suite/mtr2/single.test index 122e1bb00e4..5acf716d6cb 100644 --- a/mysql-test/suite/mtr2/single.test +++ b/mysql-test/suite/mtr2/single.test @@ -5,4 +5,8 @@ # three times - once for the parent suite, and once for each overlay. # even if the test files are not overlayed. # +# overlay.inc is overridden in mtr2-myisam, and there is an rdiff file. +# select 1; +source overlay.inc; + diff --git a/mysql-test/t/func_equal.test b/mysql-test/t/func_equal.test index 1c219af0254..990b6d8e74e 100644 --- a/mysql-test/t/func_equal.test +++ b/mysql-test/t/func_equal.test @@ -43,4 +43,54 @@ select * from t1 where a = '4828532208463511553'; select * from t1 where a in ('4828532208463511553'); drop table t1; -# End of 4.1 tests +--echo #End of 4.1 tests + +--echo # +--echo # MDEV-5103: server crashed on singular Item_equal +--echo # + +CREATE TABLE `t1` ( + `tipo` enum('p','r') NOT NULL DEFAULT 'r', + `arquivo_id` bigint(20) unsigned NOT NULL DEFAULT '0', + `arquivo_md5` char(32) NOT NULL, + `conteudo` longblob NOT NULL, + `usuario` varchar(15) NOT NULL, + `datahora_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `tipo_arquivo` varchar(255) NOT NULL, + `nome_arquivo` varchar(255) NOT NULL, + `tamanho_arquivo` bigint(20) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`tipo`,`arquivo_id`), + UNIQUE KEY `tipo` (`tipo`,`arquivo_md5`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; + +INSERT INTO `t1` (`tipo`, `arquivo_id`, `arquivo_md5`, `conteudo`, `usuario`, `datahora_gmt`, `tipo_arquivo`, `nome_arquivo`, `tamanho_arquivo`) VALUES + ('r', 1, 'ad18832202b199728921807033a8a515', '', 'rspadim', '2013-10-05 13:55:50', '001_cbr643', 'CBR6431677410201314132.ret', 21306); + + +CREATE TABLE `t2` ( + `tipo` enum('p','r') NOT NULL DEFAULT 'p', + `arquivo_id` bigint(20) NOT NULL DEFAULT '0', + `usuario` varchar(25) NOT NULL, + `datahora` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `erros` longblob NOT NULL, + `importados` bigint(20) unsigned NOT NULL DEFAULT '0', + `n_importados` bigint(20) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`tipo`,`arquivo_id`,`datahora`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; + +INSERT INTO `t2` (`tipo`, `arquivo_id`, `usuario`, `datahora`, `erros`, `importados`, `n_importados`) VALUES + ('r', 1, 'rspadim', '2013-10-05 14:25:30', '', 32, 0); + +SELECT +arquivo_id,usuario,datahora_gmt,tipo_arquivo,nome_arquivo,tamanho_arquivo + FROM t1 AS a + WHERE datahora_gmt>='0000-00-00 00:00:00' AND + datahora_gmt<='2013-10-07 02:59:59' AND tipo='r' AND + (tipo_arquivo,arquivo_id) NOT IN + (SELECT tipo_arquivo,arquivo_id + FROM t2 + WHERE (tipo_arquivo,arquivo_id)=(a.tipo_arquivo,a.arquivo_id)) + ORDER BY arquivo_id DESC; + +drop table t2, t1; +--echo #End of 5.3 tests diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 339b64b4fe8..97e5df0349c 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4845,6 +4845,34 @@ SELECT * FROM t2 LEFT JOIN v1 ON ( c=b AND a IN ( 1,6 ) ); drop view v1; drop table t1,t2; +--echo # +--echo # MDEV-5153: Server crashes in Item_ref::fix_fields on 2nd execution +--echo # of PS with LEFT JOIN and MERGE view or SELECT SQ +--echo # + +CREATE TABLE t1 (i1 INT, c1 VARCHAR(6)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); + +CREATE TABLE t2 (c2 VARCHAR(6)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('foobar'),('qux'); + +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1 WHERE ( c1 ) IN ( SELECT c2 FROM t2 ) AND i1 <= 2 ; + +PREPARE stmt FROM 'SELECT * FROM t1 LEFT JOIN v1 ON (v1.i1 = t1.i1)'; + +EXECUTE stmt; +EXECUTE stmt; + +drop view v1; +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1 WHERE ( c1, c1 ) IN ( SELECT c2, c2 FROM t2 ) AND i1 <= 2 ; + +EXECUTE stmt; +EXECUTE stmt; + +deallocate prepare stmt; +drop view v1; +drop table t1,t2; + --echo # ----------------------------------------------------------------- --echo # -- End of 5.3 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 6814e8a8012..276b7a5f90e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1438,9 +1438,11 @@ bool Item_in_optimizer::eval_not_null_tables(uchar *opt_arg) bool Item_in_optimizer::fix_left(THD *thd) { + DBUG_ENTER("Item_in_optimizer::fix_left"); if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) || (!cache && !(cache= Item_cache::get_cache(args[0])))) - return 1; + DBUG_RETURN(1); + DBUG_PRINT("info", ("actual fix fields")); cache->setup(args[0]); if (cache->cols() == 1) @@ -1466,11 +1468,15 @@ bool Item_in_optimizer::fix_left(THD *thd) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), "SUBQUERY in ROW in left expression of IN/ALL/ANY"); - return 1; + DBUG_RETURN(1); } Item *element=args[0]->element_index(i); if (element->used_tables() || !element->const_item()) - ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT); + { + ((Item_cache *)cache->element_index(i))-> + set_used_tables(OUTER_REF_TABLE_BIT); + cache->set_used_tables(OUTER_REF_TABLE_BIT); + } else ((Item_cache *)cache->element_index(i))->set_used_tables(0); } @@ -1491,7 +1497,7 @@ bool Item_in_optimizer::fix_left(THD *thd) with_sum_func= with_sum_func || args[1]->with_sum_func; const_item_cache= const_item_cache && args[1]->const_item(); } - return 0; + DBUG_RETURN(0); } @@ -5794,6 +5800,12 @@ void Item_equal::add_const(Item *c, Item *f) func->quick_fix_field(); cond_false= !func->val_int(); } + /* + TODO: also support the case where Item_equal becomes singular with + this->is_cond_true()=1. When I attempted to mark the item as constant, + the optimizer attempted to remove it, however it is still referenced from + COND_EQUAL and I got a crash. + */ if (cond_false) const_item_cache= 1; } @@ -5998,7 +6010,8 @@ void Item_equal::merge_into_list(List<Item_equal> *list, void Item_equal::sort(Item_field_cmpfunc compare, void *arg) { - bubble_sort<Item>(&equal_items, compare, arg); + if (equal_items.elements > 1) + bubble_sort<Item>(&equal_items, compare, arg); } @@ -6126,6 +6139,12 @@ bool Item_equal::fix_fields(THD *thd, Item **ref) void Item_equal::update_used_tables() { not_null_tables_cache= used_tables_cache= 0; + /* + TODO: also support the case where Item_equal becomes singular with + this->is_cond_true()=1. When I attempted to mark the item as constant, + the optimizer attempted to remove it, however it is still referenced from + COND_EQUAL and I got a crash. + */ if ((const_item_cache= cond_false)) return; Item_equal_fields_iterator it(*this); @@ -6175,6 +6194,8 @@ longlong Item_equal::val_int() { if (cond_false) return 0; + if (is_cond_true()) + return 1; Item *item= get_const(); Item_equal_fields_iterator it(*this); if (!item) @@ -6199,6 +6220,11 @@ longlong Item_equal::val_int() void Item_equal::fix_length_and_dec() { Item *item= get_first(NO_PARTICULAR_TAB, NULL); + if (!item) + { + DBUG_ASSERT(is_cond_true()); // it should be the only constant + item= equal_items.head(); + } eval_item= cmp_item::get_comparator(item->cmp_type(), item, item->collation.collation); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 50d1eb036ff..6c814429122 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1826,6 +1826,7 @@ public: Item_equal(Item_equal *item_equal); /* Currently the const item is always the first in the list of equal items */ inline Item* get_const() { return with_const ? equal_items.head() : NULL; } + inline bool is_cond_true() { return equal_items.elements == 1; } void add_const(Item *c, Item *f = NULL); /** Add a non-constant item to the multiple equality */ void add(Item *f) { equal_items.push_back(f); } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 6809ee0dfb5..7144289a1de 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2277,11 +2277,11 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, DBUG_RETURN(true); Item *item_eq= new Item_func_eq(new - Item_ref(&select_lex->context, - (*optimizer->get_cache())-> - addr(i), - (char *)"<no matter>", - (char *)in_left_expr_name), + Item_direct_ref(&select_lex->context, + (*optimizer->get_cache())-> + addr(i), + (char *)"<no matter>", + (char *)in_left_expr_name), new Item_ref(&select_lex->context, select_lex->ref_pointer_array + i, @@ -3000,7 +3000,7 @@ out: bool Item_in_subselect::select_in_like_transformer(JOIN *join) { - Query_arena *arena, backup; + Query_arena *arena= 0, backup; SELECT_LEX *current= thd->lex->current_select; const char *save_where= thd->where; bool trans_res= true; @@ -3022,9 +3022,6 @@ Item_in_subselect::select_in_like_transformer(JOIN *join) } } - if (changed) - DBUG_RETURN(false); - thd->where= "IN/ALL/ANY subquery"; /* @@ -3035,25 +3032,29 @@ Item_in_subselect::select_in_like_transformer(JOIN *join) note: we won't need Item_in_optimizer when handling degenerate cases like "... IN (SELECT 1)" */ + arena= thd->activate_stmt_arena_if_needed(&backup); if (!optimizer) { - arena= thd->activate_stmt_arena_if_needed(&backup); result= (!(optimizer= new Item_in_optimizer(left_expr, this))); - if (arena) - thd->restore_active_arena(arena, &backup); if (result) - goto err; + goto out; } thd->lex->current_select= current->return_after_parsing(); - result= (!left_expr->fixed && - left_expr->fix_fields(thd, optimizer->arguments())); + result= optimizer->fix_left(thd); /* fix_fields can change reference to left_expr, we need reassign it */ left_expr= optimizer->arguments()[0]; - thd->lex->current_select= current; + + if (changed) + { + trans_res= false; + goto out; + } + + if (result) - goto err; + goto out; /* Both transformers call fix_fields() only for Items created inside them, @@ -3062,7 +3063,6 @@ Item_in_subselect::select_in_like_transformer(JOIN *join) of Item, we have to call fix_fields() for it only with original arena to avoid memory leack) */ - arena= thd->activate_stmt_arena_if_needed(&backup); if (left_expr->cols() == 1) trans_res= single_value_transformer(join); else @@ -3077,9 +3077,9 @@ Item_in_subselect::select_in_like_transformer(JOIN *join) } trans_res= row_value_transformer(join); } +out: if (arena) thd->restore_active_arena(arena, &backup); -err: thd->where= save_where; DBUG_RETURN(trans_res); } diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index f218e4c35f2..de5448ace63 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1272,11 +1272,11 @@ void get_delayed_table_estimates(TABLE *table, @brief Replaces an expression destructively inside the expression tree of the WHERE clase. - @note Because of current requirements for semijoin flattening, we do not - need to recurse here, hence this function will only examine the top-level - AND conditions. (see JOIN::prepare, comment starting with "Check if the - subquery predicate can be executed via materialization". - + @note We substitute AND/OR structure because it was copied by + copy_andor_structure and some changes could be done in the copy but + should be left permanent, also there could be several layers of AND over + AND and OR over OR because ::fix_field() possibly is not called. + @param join The top-level query. @param old_cond The expression to be replaced. @param new_cond The expression to be substituted. @@ -1304,13 +1304,20 @@ static bool replace_where_subcondition(JOIN *join, Item **expr, Item *item; while ((item= li++)) { - if (item == old_cond) + if (item == old_cond) { li.replace(new_cond); if (do_fix_fields) new_cond->fix_fields(join->thd, li.ref()); return FALSE; } + else if (item->type() == Item::COND_ITEM) + { + DBUG_ASSERT(!(*expr)->fixed); + replace_where_subcondition(join, li.ref(), + old_cond, new_cond, + do_fix_fields); + } } } /* diff --git a/storage/myisam/mysql-test/mtr2/overlay.inc b/storage/myisam/mysql-test/mtr2/overlay.inc new file mode 100644 index 00000000000..4113a306496 --- /dev/null +++ b/storage/myisam/mysql-test/mtr2/overlay.inc @@ -0,0 +1,2 @@ +select 3; + diff --git a/storage/myisam/mysql-test/mtr2/single.rdiff b/storage/myisam/mysql-test/mtr2/single.rdiff new file mode 100644 index 00000000000..fd590d53d4a --- /dev/null +++ b/storage/myisam/mysql-test/mtr2/single.rdiff @@ -0,0 +1,12 @@ +--- suite/mtr2/single.result 2013-11-10 03:58:37.000000000 +0400 ++++ suite/mtr2/single.reject 2013-11-10 03:59:08.000000000 +0400 +@@ -1,6 +1,6 @@ + select 1; + 1 + 1 +-select 2; +-2 +-2 ++select 3; ++3 ++3 |