From e44024d47383a7e94b9ad54f0f058a16040837e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Sep 2006 19:47:24 +0500 Subject: [PATCH 01/15] bug #12620 (UTF-8 indexing causes ER_NO_KEYFILE error) The problem is that on some Mac OS X-es the file writing/reading call with zero bytes to read/write returns error. So here i try to eliminate that kinds of calls. myisam/mi_check.c: zero length copying avoided mysys/my_chsize.c: no file operations if it's not necessary --- myisam/mi_check.c | 9 ++++++--- mysys/my_chsize.c | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 1e62e5e641d..65ce70a97df 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1366,7 +1366,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, param->temp_filename); goto err; } - if (filecopy(param,new_file,info->dfile,0L,new_header_length, + if (new_header_length && + filecopy(param,new_file,info->dfile,0L,new_header_length, "datafile-header")) goto err; info->s->state.dellink= HA_OFFSET_ERROR; @@ -2063,7 +2064,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, param->temp_filename); goto err; } - if (filecopy(param, new_file,info->dfile,0L,new_header_length, + if (new_header_length && + filecopy(param, new_file,info->dfile,0L,new_header_length, "datafile-header")) goto err; if (param->testflag & T_UNPACK) @@ -2431,7 +2433,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, param->temp_filename); goto err; } - if (filecopy(param, new_file,info->dfile,0L,new_header_length, + if (new_header_length && + filecopy(param, new_file,info->dfile,0L,new_header_length, "datafile-header")) goto err; if (param->testflag & T_UNPACK) diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c index cf26428d65f..efc19927183 100644 --- a/mysys/my_chsize.c +++ b/mysys/my_chsize.c @@ -44,7 +44,9 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength, MyFlags)); - oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE)); + if ((oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength) + DBUG_RETURN(0); + DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize)); if (oldsize > newlength) From 032de81438179ebfc047e6eb6e3c505400f3bb18 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Sep 2006 19:56:19 +0500 Subject: [PATCH 02/15] bug #12991 (compile error --without-geometry) myisam/mi_check.c: proper #ifdef-s added --- myisam/mi_check.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 1e62e5e641d..1374cb05094 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1153,9 +1153,12 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) /* We don't need to lock the key tree here as we don't allow concurrent threads when running myisamchk */ - int search_result= (keyinfo->flag & HA_SPATIAL) ? + int search_result= +#ifdef HAVE_RTREE_KEYS + (keyinfo->flag & HA_SPATIAL) ? rtree_find_first(info, key, info->lastkey, key_length, MBR_EQUAL | MBR_DATA) : +#endif _mi_search(info,keyinfo,info->lastkey,key_length, SEARCH_SAME, info->s->state.key_root[key]); if (search_result) From 2a00a073c2c07f2d73d60a6c74c538874f05158b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Sep 2006 19:04:46 +0300 Subject: [PATCH 03/15] Bug #21540: Subqueries with no from and aggregate functions return wrong results Mark the containing Item(s) (Item_subselect descendant usually) of a subselect as containing aggregate functions if it has references to aggregates functions that are calculated outside its context. This tels end_send_group() not to make an Item_subselect descendant in select list a copy and causes the correct value being returned. mysql-test/r/func_group.result: Bug #21540: Subqueries with no from and aggregate functions return wrong results - test cases mysql-test/r/subselect.result: Bug #21540: Subqueries with no from and aggregate functions return wrong results - fixed the result of an existing testcase. mysql-test/t/subselect.test: Bug #21540: Subqueries with no from and aggregate functions return wrong results - test cases sql/item_sum.cc: Bug #21540: Subqueries with no from and aggregate functions return wrong results Mark the containing Item (Item_subselect descendant usually) of a subselect as containing aggregate functions if it has references to aggregates functions that are calculated outside its context. This tels end_send_group() not to make an Item_subselect descendant in select list a copy and causes the correct value being returned. --- mysql-test/r/func_group.result | 2 +- mysql-test/r/subselect.result | 61 ++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 31 +++++++++++++++++ sql/item_sum.cc | 22 +++++++++++- 4 files changed, 114 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index f57b4ad6ce9..da2a7518c86 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -997,7 +997,7 @@ SELECT SQL_NO_CACHE WHERE ttt.a = ccc.b AND ttt.a = t.a GROUP BY ttt.a) AS minid FROM t1 t, t2 c WHERE t.a = c.b; minid -NULL +1 DROP TABLE t1,t2; create table t1 select variance(0); show create table t1; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 4ee6d3088a5..a6fb9a3eb61 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3368,3 +3368,64 @@ ORDER BY t1.t DESC LIMIT 1); i1 i2 t i1 i2 t 24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40 DROP TABLE t1, t2; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +INSERT INTO t2 values (1); +INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4); +SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a; +(SELECT COUNT(DISTINCT t1.b) from t2) +2 +1 +1 +SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3) +FROM t1 GROUP BY t1.a; +(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3) +2 +1 +1 +SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a; +COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b)) +2 2 +1 1 +1 1 +SELECT COUNT(DISTINCT t1.b), +(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3) +FROM t1 GROUP BY t1.a; +COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3) +2 2 +1 1 +1 1 +SELECT ( +SELECT ( +SELECT COUNT(DISTINCT t1.b) +) +) +FROM t1 GROUP BY t1.a; +( +SELECT ( +SELECT COUNT(DISTINCT t1.b) +) +) +2 +1 +1 +SELECT ( +SELECT ( +SELECT ( +SELECT COUNT(DISTINCT t1.b) +) +) +FROM t1 GROUP BY t1.a LIMIT 1) +FROM t1 t2 +GROUP BY t2.a; +( +SELECT ( +SELECT ( +SELECT COUNT(DISTINCT t1.b) +) +) +FROM t1 GROUP BY t1.a LIMIT 1) +2 +2 +2 +DROP TABLE t1,t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index ed122e9ff5a..4d0bb9fd6c6 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2280,3 +2280,34 @@ SELECT * FROM t1,t2 ORDER BY t1.t DESC LIMIT 1); DROP TABLE t1, t2; + +# +# Bug #21540: Subqueries with no from and aggregate functions return +# wrong results +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +INSERT INTO t2 values (1); +INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4); +SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a; +SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3) + FROM t1 GROUP BY t1.a; +SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a; +SELECT COUNT(DISTINCT t1.b), + (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3) + FROM t1 GROUP BY t1.a; +SELECT ( + SELECT ( + SELECT COUNT(DISTINCT t1.b) + ) +) +FROM t1 GROUP BY t1.a; +SELECT ( + SELECT ( + SELECT ( + SELECT COUNT(DISTINCT t1.b) + ) + ) + FROM t1 GROUP BY t1.a LIMIT 1) +FROM t1 t2 +GROUP BY t2.a; +DROP TABLE t1,t2; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 0d2a5b3b080..7dc90b11771 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -246,7 +246,27 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) aggr_sl->inner_sum_func_list->next= this; } aggr_sl->inner_sum_func_list= this; - + aggr_sl->with_sum_func= 1; + + /* + Mark Item_subselect(s) as containing aggregate function all the way up + to aggregate function's calculation context. + Note that we must not mark the Item of calculation context itself + because with_sum_func on the calculation context st_select_lex is + already set above. + + with_sum_func being set for an Item means that this Item refers + (somewhere in it, e.g. one of its arguments if it's a function) directly + or through intermediate items to an aggregate function that is calculated + in a context "outside" of the Item (e.g. in the current or outer select). + + with_sum_func being set for an st_select_lex means that this st_select_lex + has aggregate functions directly referenced (i.e. not through a sub-select). + */ + for (sl= thd->lex->current_select; + sl && sl != aggr_sl && sl->master_unit()->item; + sl= sl->master_unit()->outer_select() ) + sl->master_unit()->item->with_sum_func= 1; } return FALSE; } From c46151d96128a374ef286d6ff83d57b1f53bb2dc Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Sep 2006 11:50:00 -0700 Subject: [PATCH 04/15] Fixed bug #22085: Crash on the execution of a prepared statement that uses an aggregating IN subquery with HAVING clause. A wrong order of the call of split_sum_func2 for the HAVING clause of the subquery and the transformation for the subquery resulted in the creation of a andor structure that could not be restored at an execution of the prepared statement. mysql-test/r/ps.result: Added a test cases for bug #22085. mysql-test/t/ps.test: Added a test cases for bug #22085. --- mysql-test/r/ps.result | 47 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/ps.test | 52 ++++++++++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 5 ++-- 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 01aa4ddf859..78752622db7 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -889,3 +889,50 @@ create temporary table if not exists t1 (a1 int); execute stmt; drop temporary table t1; deallocate prepare stmt; +CREATE TABLE t1( +ID int(10) unsigned NOT NULL auto_increment, +Member_ID varchar(15) NOT NULL default '', +Action varchar(12) NOT NULL, +Action_Date datetime NOT NULL, +Track varchar(15) default NULL, +User varchar(12) default NULL, +Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update +CURRENT_TIMESTAMP, +PRIMARY KEY (ID), +KEY Action (Action), +KEY Action_Date (Action_Date) +); +INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES +('111111', 'Disenrolled', '2006-03-01', 'CAD' ), +('111111', 'Enrolled', '2006-03-01', 'CAD' ), +('111111', 'Disenrolled', '2006-07-03', 'CAD' ), +('222222', 'Enrolled', '2006-03-07', 'CAD' ), +('222222', 'Enrolled', '2006-03-07', 'CHF' ), +('222222', 'Disenrolled', '2006-08-02', 'CHF' ), +('333333', 'Enrolled', '2006-03-01', 'CAD' ), +('333333', 'Disenrolled', '2006-03-01', 'CAD' ), +('444444', 'Enrolled', '2006-03-01', 'CAD' ), +('555555', 'Disenrolled', '2006-03-01', 'CAD' ), +('555555', 'Enrolled', '2006-07-21', 'CAD' ), +('555555', 'Disenrolled', '2006-03-01', 'CHF' ), +('666666', 'Enrolled', '2006-02-09', 'CAD' ), +('666666', 'Enrolled', '2006-05-12', 'CHF' ), +('666666', 'Disenrolled', '2006-06-01', 'CAD' ); +PREPARE STMT FROM +"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1 + WHERE Member_ID=? AND Action='Enrolled' AND + (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1 + WHERE Member_ID=? + GROUP BY Track + HAVING Track>='CAD' AND + MAX(Action_Date)>'2006-03-01')"; +SET @id='111111'; +EXECUTE STMT USING @id,@id; +GROUP_CONCAT(Track SEPARATOR ', ') +NULL +SET @id='222222'; +EXECUTE STMT USING @id,@id; +GROUP_CONCAT(Track SEPARATOR ', ') +CAD +DEALLOCATE PREPARE STMT; +DROP TABLE t1; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 0ca293eb1ba..7c2a42404ad 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -951,4 +951,56 @@ execute stmt; drop temporary table t1; deallocate prepare stmt; +# +# BUG#22085: Crash on the execution of a prepared statement that +# uses an IN subquery with aggregate functions in HAVING +# + +CREATE TABLE t1( + ID int(10) unsigned NOT NULL auto_increment, + Member_ID varchar(15) NOT NULL default '', + Action varchar(12) NOT NULL, + Action_Date datetime NOT NULL, + Track varchar(15) default NULL, + User varchar(12) default NULL, + Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update + CURRENT_TIMESTAMP, + PRIMARY KEY (ID), + KEY Action (Action), + KEY Action_Date (Action_Date) +); + +INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES + ('111111', 'Disenrolled', '2006-03-01', 'CAD' ), + ('111111', 'Enrolled', '2006-03-01', 'CAD' ), + ('111111', 'Disenrolled', '2006-07-03', 'CAD' ), + ('222222', 'Enrolled', '2006-03-07', 'CAD' ), + ('222222', 'Enrolled', '2006-03-07', 'CHF' ), + ('222222', 'Disenrolled', '2006-08-02', 'CHF' ), + ('333333', 'Enrolled', '2006-03-01', 'CAD' ), + ('333333', 'Disenrolled', '2006-03-01', 'CAD' ), + ('444444', 'Enrolled', '2006-03-01', 'CAD' ), + ('555555', 'Disenrolled', '2006-03-01', 'CAD' ), + ('555555', 'Enrolled', '2006-07-21', 'CAD' ), + ('555555', 'Disenrolled', '2006-03-01', 'CHF' ), + ('666666', 'Enrolled', '2006-02-09', 'CAD' ), + ('666666', 'Enrolled', '2006-05-12', 'CHF' ), + ('666666', 'Disenrolled', '2006-06-01', 'CAD' ); + +PREPARE STMT FROM +"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1 + WHERE Member_ID=? AND Action='Enrolled' AND + (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1 + WHERE Member_ID=? + GROUP BY Track + HAVING Track>='CAD' AND + MAX(Action_Date)>'2006-03-01')"; +SET @id='111111'; +EXECUTE STMT USING @id,@id; +SET @id='222222'; +EXECUTE STMT USING @id,@id; + +DEALLOCATE PREPARE STMT; +DROP TABLE t1; + # End of 4.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5154bff78dd..62eb5235d70 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -290,8 +290,6 @@ JOIN::prepare(Item ***rref_pointer_array, select_lex->having_fix_field= 0; if (having_fix_rc || thd->net.report_error) DBUG_RETURN(-1); /* purecov: inspected */ - if (having->with_sum_func) - having->split_sum_func2(thd, ref_pointer_array, all_fields, &having); } // Is it subselect @@ -306,6 +304,9 @@ JOIN::prepare(Item ***rref_pointer_array, } } + if (having && having->with_sum_func) + having->split_sum_func2(thd, ref_pointer_array, all_fields, &having); + if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ DBUG_RETURN(-1); From 76b354dcf73d87de3abb2bf482954c261e4d995b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Sep 2006 12:18:24 -0700 Subject: [PATCH 05/15] Post-merge corrections. --- mysql-test/r/ps.result | 98 ++++++++++++++++++------------------- mysql-test/t/ps.test | 108 ++++++++++++++++++++--------------------- 2 files changed, 103 insertions(+), 103 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 888ba5bdb5b..1727c4ddfbe 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -253,10 +253,10 @@ execute `ü` ; 1234 1234 set names latin1; -execute `ü`; +execute ``; 1234 1234 -deallocate prepare `ü`; +deallocate prepare ``; set names default; create table t1 (a varchar(10)) charset=utf8; insert into t1 (a) values ('yahoo'); @@ -820,53 +820,6 @@ ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should set local max_prepared_stmt_count=1; ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL set local prepared_stmt_count=0; -CREATE TABLE t1( -ID int(10) unsigned NOT NULL auto_increment, -Member_ID varchar(15) NOT NULL default '', -Action varchar(12) NOT NULL, -Action_Date datetime NOT NULL, -Track varchar(15) default NULL, -User varchar(12) default NULL, -Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update -CURRENT_TIMESTAMP, -PRIMARY KEY (ID), -KEY Action (Action), -KEY Action_Date (Action_Date) -); -INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES -('111111', 'Disenrolled', '2006-03-01', 'CAD' ), -('111111', 'Enrolled', '2006-03-01', 'CAD' ), -('111111', 'Disenrolled', '2006-07-03', 'CAD' ), -('222222', 'Enrolled', '2006-03-07', 'CAD' ), -('222222', 'Enrolled', '2006-03-07', 'CHF' ), -('222222', 'Disenrolled', '2006-08-02', 'CHF' ), -('333333', 'Enrolled', '2006-03-01', 'CAD' ), -('333333', 'Disenrolled', '2006-03-01', 'CAD' ), -('444444', 'Enrolled', '2006-03-01', 'CAD' ), -('555555', 'Disenrolled', '2006-03-01', 'CAD' ), -('555555', 'Enrolled', '2006-07-21', 'CAD' ), -('555555', 'Disenrolled', '2006-03-01', 'CHF' ), -('666666', 'Enrolled', '2006-02-09', 'CAD' ), -('666666', 'Enrolled', '2006-05-12', 'CHF' ), -('666666', 'Disenrolled', '2006-06-01', 'CAD' ); -PREPARE STMT FROM -"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1 - WHERE Member_ID=? AND Action='Enrolled' AND - (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1 - WHERE Member_ID=? - GROUP BY Track - HAVING Track>='CAD' AND - MAX(Action_Date)>'2006-03-01')"; -SET @id='111111'; -EXECUTE STMT USING @id,@id; -GROUP_CONCAT(Track SEPARATOR ', ') -NULL -SET @id='222222'; -EXECUTE STMT USING @id,@id; -GROUP_CONCAT(Track SEPARATOR ', ') -CAD -DEALLOCATE PREPARE STMT; -DROP TABLE t1; ERROR HY000: Variable 'prepared_stmt_count' is a read only variable set @@prepared_stmt_count=0; ERROR HY000: Variable 'prepared_stmt_count' is a read only variable @@ -956,6 +909,53 @@ create temporary table if not exists t1 (a1 int); execute stmt; drop temporary table t1; deallocate prepare stmt; +CREATE TABLE t1( +ID int(10) unsigned NOT NULL auto_increment, +Member_ID varchar(15) NOT NULL default '', +Action varchar(12) NOT NULL, +Action_Date datetime NOT NULL, +Track varchar(15) default NULL, +User varchar(12) default NULL, +Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update +CURRENT_TIMESTAMP, +PRIMARY KEY (ID), +KEY Action (Action), +KEY Action_Date (Action_Date) +); +INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES +('111111', 'Disenrolled', '2006-03-01', 'CAD' ), +('111111', 'Enrolled', '2006-03-01', 'CAD' ), +('111111', 'Disenrolled', '2006-07-03', 'CAD' ), +('222222', 'Enrolled', '2006-03-07', 'CAD' ), +('222222', 'Enrolled', '2006-03-07', 'CHF' ), +('222222', 'Disenrolled', '2006-08-02', 'CHF' ), +('333333', 'Enrolled', '2006-03-01', 'CAD' ), +('333333', 'Disenrolled', '2006-03-01', 'CAD' ), +('444444', 'Enrolled', '2006-03-01', 'CAD' ), +('555555', 'Disenrolled', '2006-03-01', 'CAD' ), +('555555', 'Enrolled', '2006-07-21', 'CAD' ), +('555555', 'Disenrolled', '2006-03-01', 'CHF' ), +('666666', 'Enrolled', '2006-02-09', 'CAD' ), +('666666', 'Enrolled', '2006-05-12', 'CHF' ), +('666666', 'Disenrolled', '2006-06-01', 'CAD' ); +PREPARE STMT FROM +"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1 + WHERE Member_ID=? AND Action='Enrolled' AND + (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1 + WHERE Member_ID=? + GROUP BY Track + HAVING Track>='CAD' AND + MAX(Action_Date)>'2006-03-01')"; +SET @id='111111'; +EXECUTE STMT USING @id,@id; +GROUP_CONCAT(Track SEPARATOR ', ') +NULL +SET @id='222222'; +EXECUTE STMT USING @id,@id; +GROUP_CONCAT(Track SEPARATOR ', ') +CAD +DEALLOCATE PREPARE STMT; +DROP TABLE t1; End of 4.1 tests create table t1 (a varchar(20)); insert into t1 values ('foo'); diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index ea9e98e1b1e..cc239306558 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -259,8 +259,8 @@ set names utf8; prepare `ü` from 'select 1234'; execute `ü` ; set names latin1; -execute `ü`; -deallocate prepare `ü`; +execute ``; +deallocate prepare ``; set names default; @@ -563,58 +563,6 @@ set @a=200887, @b=860; # this query did not return all matching rows execute stmt using @a, @b; deallocate prepare stmt; -# -# BUG#22085: Crash on the execution of a prepared statement that -# uses an IN subquery with aggregate functions in HAVING -# - -CREATE TABLE t1( - ID int(10) unsigned NOT NULL auto_increment, - Member_ID varchar(15) NOT NULL default '', - Action varchar(12) NOT NULL, - Action_Date datetime NOT NULL, - Track varchar(15) default NULL, - User varchar(12) default NULL, - Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update - CURRENT_TIMESTAMP, - PRIMARY KEY (ID), - KEY Action (Action), - KEY Action_Date (Action_Date) -); - -INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES - ('111111', 'Disenrolled', '2006-03-01', 'CAD' ), - ('111111', 'Enrolled', '2006-03-01', 'CAD' ), - ('111111', 'Disenrolled', '2006-07-03', 'CAD' ), - ('222222', 'Enrolled', '2006-03-07', 'CAD' ), - ('222222', 'Enrolled', '2006-03-07', 'CHF' ), - ('222222', 'Disenrolled', '2006-08-02', 'CHF' ), - ('333333', 'Enrolled', '2006-03-01', 'CAD' ), - ('333333', 'Disenrolled', '2006-03-01', 'CAD' ), - ('444444', 'Enrolled', '2006-03-01', 'CAD' ), - ('555555', 'Disenrolled', '2006-03-01', 'CAD' ), - ('555555', 'Enrolled', '2006-07-21', 'CAD' ), - ('555555', 'Disenrolled', '2006-03-01', 'CHF' ), - ('666666', 'Enrolled', '2006-02-09', 'CAD' ), - ('666666', 'Enrolled', '2006-05-12', 'CHF' ), - ('666666', 'Disenrolled', '2006-06-01', 'CAD' ); - -PREPARE STMT FROM -"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1 - WHERE Member_ID=? AND Action='Enrolled' AND - (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1 - WHERE Member_ID=? - GROUP BY Track - HAVING Track>='CAD' AND - MAX(Action_Date)>'2006-03-01')"; -SET @id='111111'; -EXECUTE STMT USING @id,@id; -SET @id='222222'; -EXECUTE STMT USING @id,@id; - -DEALLOCATE PREPARE STMT; -DROP TABLE t1; - drop table t1; @@ -1040,6 +988,58 @@ execute stmt; drop temporary table t1; deallocate prepare stmt; +# +# BUG#22085: Crash on the execution of a prepared statement that +# uses an IN subquery with aggregate functions in HAVING +# + +CREATE TABLE t1( + ID int(10) unsigned NOT NULL auto_increment, + Member_ID varchar(15) NOT NULL default '', + Action varchar(12) NOT NULL, + Action_Date datetime NOT NULL, + Track varchar(15) default NULL, + User varchar(12) default NULL, + Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update + CURRENT_TIMESTAMP, + PRIMARY KEY (ID), + KEY Action (Action), + KEY Action_Date (Action_Date) +); + +INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES + ('111111', 'Disenrolled', '2006-03-01', 'CAD' ), + ('111111', 'Enrolled', '2006-03-01', 'CAD' ), + ('111111', 'Disenrolled', '2006-07-03', 'CAD' ), + ('222222', 'Enrolled', '2006-03-07', 'CAD' ), + ('222222', 'Enrolled', '2006-03-07', 'CHF' ), + ('222222', 'Disenrolled', '2006-08-02', 'CHF' ), + ('333333', 'Enrolled', '2006-03-01', 'CAD' ), + ('333333', 'Disenrolled', '2006-03-01', 'CAD' ), + ('444444', 'Enrolled', '2006-03-01', 'CAD' ), + ('555555', 'Disenrolled', '2006-03-01', 'CAD' ), + ('555555', 'Enrolled', '2006-07-21', 'CAD' ), + ('555555', 'Disenrolled', '2006-03-01', 'CHF' ), + ('666666', 'Enrolled', '2006-02-09', 'CAD' ), + ('666666', 'Enrolled', '2006-05-12', 'CHF' ), + ('666666', 'Disenrolled', '2006-06-01', 'CAD' ); + +PREPARE STMT FROM +"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1 + WHERE Member_ID=? AND Action='Enrolled' AND + (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1 + WHERE Member_ID=? + GROUP BY Track + HAVING Track>='CAD' AND + MAX(Action_Date)>'2006-03-01')"; +SET @id='111111'; +EXECUTE STMT USING @id,@id; +SET @id='222222'; +EXECUTE STMT USING @id,@id; + +DEALLOCATE PREPARE STMT; +DROP TABLE t1; + --echo End of 4.1 tests ############################# 5.0 tests start ################################ # From a952b3fcb21cd09ab00775d10d440cf8df0c48dd Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Sep 2006 12:02:58 +0300 Subject: [PATCH 06/15] fixed merge --- mysql-test/r/func_group.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 32d6931c334..c6117053a60 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -860,8 +860,8 @@ CREATE TABLE t1 (a INT, b INT); INSERT INTO t1 VALUES (1,1),(1,2),(2,3); SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a; (SELECT COUNT(DISTINCT t1.b)) -0 2 +1 SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a; (SELECT COUNT(DISTINCT 12)) 1 From 1b5bd18dc6b34d3dc50b7495bae8c05e5125c0dc Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Sep 2006 08:08:57 -0700 Subject: [PATCH 07/15] Fixed bug #22015: crash with GROUP_CONCAT over a derived table that returns the results of aggregation by GROUP_CONCAT. The crash was due to an overflow happened for the field sortoder->length. The fix prevents this overflow exploiting the fact that the value of sortoder->length cannot be greater than the value of thd->variables.max_sort_length. mysql-test/r/func_gconcat.result: Added a test case for bug #22015. mysql-test/t/func_gconcat.test: Added a test case for bug #22015. --- mysql-test/r/func_gconcat.result | 9 +++++++++ mysql-test/t/func_gconcat.test | 15 +++++++++++++++ sql/filesort.cc | 1 + 3 files changed, 25 insertions(+) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 6617ccc671e..93925670d01 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -654,3 +654,12 @@ CHAR_LENGTH( GROUP_CONCAT(b) ) 240001 SET GROUP_CONCAT_MAX_LEN = 1024; DROP TABLE t1; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (2,1), (1,2), (2,2), (1,3); +SELECT GROUP_CONCAT(a), x +FROM (SELECT a, GROUP_CONCAT(b) x FROM t1 GROUP BY a) AS s +GROUP BY x; +GROUP_CONCAT(a) x +2 1,2 +1 2,3 +DROP TABLE t1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 98c21986aa9..b5c468e1638 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -447,3 +447,18 @@ SELECT a, CHAR_LENGTH(b) FROM t1; SELECT CHAR_LENGTH( GROUP_CONCAT(b) ) FROM t1; SET GROUP_CONCAT_MAX_LEN = 1024; DROP TABLE t1; + +# +# Bug #22015: crash with GROUP_CONCAT over a derived table that +# returns the results of aggregation by GROUP_CONCAT +# + +CREATE TABLE t1 (a int, b int); + +INSERT INTO t1 VALUES (2,1), (1,2), (2,2), (1,3); + +SELECT GROUP_CONCAT(a), x + FROM (SELECT a, GROUP_CONCAT(b) x FROM t1 GROUP BY a) AS s + GROUP BY x; + +DROP TABLE t1; diff --git a/sql/filesort.cc b/sql/filesort.cc index 42d25dbbaee..f13354d5c72 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1268,6 +1268,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, switch ((sortorder->result_type=sortorder->item->result_type())) { case STRING_RESULT: sortorder->length=sortorder->item->max_length; + set_if_smaller(sortorder->length, thd->variables.max_sort_length); if (use_strnxfrm((cs=sortorder->item->collation.collation))) { sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length); From 0f50a8a7fea053127f236ca4956bba58370a8d81 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Sep 2006 09:46:12 -0700 Subject: [PATCH 08/15] Fixed bug #20108. Any default value for a enum fields over UCS2 charsets was corrupted when we put it into the frm file, as it had been overwritten by its HEX representation. To fix it now we save a copy of structure that represents the enum type and when putting the default values we use this copy. mysql-test/r/ctype_ucs.result: Added a test case for bug #20108. mysql-test/t/ctype_ucs.test: Added a test case for bug #20108. --- mysql-test/r/ctype_ucs.result | 21 +++++++++++++++++++ mysql-test/t/ctype_ucs.test | 21 +++++++++++++++++++ sql/field.h | 2 ++ sql/unireg.cc | 39 ++++++++++++++++++++++++++++------- 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 24a4ca9a85f..642a0fc13b5 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -747,6 +747,27 @@ select export_set(5, name, upper(name), ",", 5) from bug20536; export_set(5, name, upper(name), ",", 5) test1,TEST1,test1,TEST1,TEST1 'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2' +CREATE TABLE t1 ( +status enum('active','passive') collate latin1_general_ci +NOT NULL default 'passive' +); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `status` enum('active','passive') character set latin1 collate latin1_general_ci NOT NULL default 'passive' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 ADD a int NOT NULL AFTER status; +CREATE TABLE t2 ( +status enum('active','passive') collate ucs2_turkish_ci +NOT NULL default 'passive' +); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `status` enum('active','passive') character set ucs2 collate ucs2_turkish_ci NOT NULL default 'passive' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t2 ADD a int NOT NULL AFTER status; +DROP TABLE t1,t2; select password(name) from bug20536; password(name) ???????????????????? diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index d96b9938f1b..641080f48ab 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -482,6 +482,27 @@ select make_set(3, name, upper(name)) from bug20536; select export_set(5, name, upper(name)) from bug20536; select export_set(5, name, upper(name), ",", 5) from bug20536; +# +# Bug #20108: corrupted default enum value for a ucs2 field +# + +CREATE TABLE t1 ( + status enum('active','passive') collate latin1_general_ci + NOT NULL default 'passive' +); +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD a int NOT NULL AFTER status; + +CREATE TABLE t2 ( + status enum('active','passive') collate ucs2_turkish_ci + NOT NULL default 'passive' +); +SHOW CREATE TABLE t2; +ALTER TABLE t2 ADD a int NOT NULL AFTER status; + +DROP TABLE t1,t2; + + # Some broken functions: add these tests just to document current behavior. # PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would diff --git a/sql/field.h b/sql/field.h index a33cb0a93aa..79fb7ff76d1 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1192,6 +1192,8 @@ public: uint decimals,flags,pack_length; Field::utype unireg_check; TYPELIB *interval; // Which interval to use + TYPELIB *save_interval; // Temporary copy for the above + // Used only for UCS2 intervals List interval_list; CHARSET_INFO *charset; Field::geometry_type geom_type; diff --git a/sql/unireg.cc b/sql/unireg.cc index e3bf763f700..e4fdc77912c 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -190,13 +190,19 @@ bool mysql_create_frm(THD *thd, my_string file_name, goto err3; { - /* Unescape all UCS2 intervals: were escaped in pack_headers */ + /* + Restore all UCS2 intervals. + HEX representation of them is not needed anymore. + */ List_iterator it(create_fields); create_field *field; while ((field=it++)) { - if (field->interval && field->charset->mbminlen > 1) - unhex_type2(field->interval); + if (field->save_interval) + { + field->interval= field->save_interval; + field->save_interval= 0; + } } } DBUG_RETURN(0); @@ -452,18 +458,36 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, reclength=(uint) (field->offset+ data_offset + length); n_length+= (ulong) strlen(field->field_name)+1; field->interval_id=0; + field->save_interval= 0; if (field->interval) { uint old_int_count=int_count; if (field->charset->mbminlen > 1) { - /* Escape UCS2 intervals using HEX notation */ + /* + Escape UCS2 intervals using HEX notation to avoid + problems with delimiters between enum elements. + As the original representation is still needed in + the function make_empty_rec to create a record of + filled with default values it is saved in save_interval + The HEX representation is created from this copy. + */ + field->save_interval= field->interval; + field->interval= (TYPELIB*) sql_alloc(sizeof(TYPELIB)); + *field->interval= *field->save_interval; + field->interval->type_names= + (const char **) sql_alloc(sizeof(char*) * + (field->interval->count+1)); + field->interval->type_names[field->interval->count]= 0; + field->interval->type_lengths= + (uint *) sql_alloc(sizeof(uint) * field->interval->count); + for (uint pos= 0; pos < field->interval->count; pos++) { char *dst; - uint length= field->interval->type_lengths[pos], hex_length; - const char *src= field->interval->type_names[pos]; + uint length= field->save_interval->type_lengths[pos], hex_length; + const char *src= field->save_interval->type_names[pos]; const char *srcend= src + length; hex_length= length * 2; field->interval->type_lengths[pos]= hex_length; @@ -715,7 +739,8 @@ static bool make_empty_rec(File file,enum db_type table_type, field->charset, field->geom_type, field->unireg_check, - field->interval, + field->save_interval ? field->save_interval : + field->interval, field->field_name, &table); From 9bf2ed95539220b6da3452eecbab56ae33af2126 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 25 Sep 2006 05:24:07 -0700 Subject: [PATCH 09/15] Fixed bug #21853: assert failure for a grouping query with an ALL/ANY quantified subquery in HAVING. The Item::split_sum_func2 method should not create Item_ref for objects of any class derived from Item_subselect. mysql-test/r/subselect.result: Added a test case for bug #21853. mysql-test/t/subselect.test: Added a test case for bug #21853. --- mysql-test/r/subselect.result | 36 ++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 37 +++++++++++++++++++++++++++++++++++ sql/item.cc | 1 + 3 files changed, 74 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index ba4de7f6406..ad847b5f156 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -2946,3 +2946,39 @@ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; a a b 10 1 359 drop table t1,t2; +CREATE TABLE t1 ( +field1 int NOT NULL, +field2 int NOT NULL, +field3 int NOT NULL, +PRIMARY KEY (field1,field2,field3) +); +CREATE TABLE t2 ( +fieldA int NOT NULL, +fieldB int NOT NULL, +PRIMARY KEY (fieldA,fieldB) +); +INSERT INTO t1 VALUES +(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1); +INSERT INTO t2 VALUES (1,1), (1,2), (1,3); +SELECT field1, field2, COUNT(*) +FROM t1 GROUP BY field1, field2; +field1 field2 COUNT(*) +1 1 2 +1 2 3 +1 3 1 +SELECT field1, field2 +FROM t1 +GROUP BY field1, field2 +HAVING COUNT(*) >= ALL (SELECT fieldB +FROM t2 WHERE fieldA = field1); +field1 field2 +1 2 +SELECT field1, field2 +FROM t1 +GROUP BY field1, field2 +HAVING COUNT(*) < ANY (SELECT fieldB +FROM t2 WHERE fieldA = field1); +field1 field2 +1 1 +1 3 +DROP TABLE t1, t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1018b5de005..6defa8b16a5 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1911,4 +1911,41 @@ SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r drop table t1,t2; +# +# Bug #21853: assert failure for a grouping query with +# an ALL/ANY quantified subquery in HAVING +# + +CREATE TABLE t1 ( + field1 int NOT NULL, + field2 int NOT NULL, + field3 int NOT NULL, + PRIMARY KEY (field1,field2,field3) +); +CREATE TABLE t2 ( + fieldA int NOT NULL, + fieldB int NOT NULL, + PRIMARY KEY (fieldA,fieldB) +); + +INSERT INTO t1 VALUES + (1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1); +INSERT INTO t2 VALUES (1,1), (1,2), (1,3); + +SELECT field1, field2, COUNT(*) + FROM t1 GROUP BY field1, field2; + +SELECT field1, field2 + FROM t1 + GROUP BY field1, field2 + HAVING COUNT(*) >= ALL (SELECT fieldB + FROM t2 WHERE fieldA = field1); +SELECT field1, field2 + FROM t1 + GROUP BY field1, field2 + HAVING COUNT(*) < ANY (SELECT fieldB + FROM t2 WHERE fieldA = field1); + +DROP TABLE t1, t2; + # End of 4.1 tests diff --git a/sql/item.cc b/sql/item.cc index 7c9f6ec77fb..94f0a24fcc3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -387,6 +387,7 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array, } else if ((type() == SUM_FUNC_ITEM || (used_tables() & ~PARAM_TABLE_BIT)) && + type() != SUBSELECT_ITEM && type() != REF_ITEM) { /* From f0bd502ac8037341c49ff2d4e753407ccc6486ce Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 25 Sep 2006 06:15:14 -0700 Subject: [PATCH 10/15] Fixed bug #21646. Presence of a subquery in the ON expression of a join should not block merging the view that contains this join. Before this patch the such views were converted into into temporary table views. mysql-test/r/view.result: Added a test case for bug #21646. mysql-test/t/view.test: Added a test case for bug #21646. sql/mysql_priv.h: Fixed bug #21646. Added a new parsing state 'IN_ON', true when the parser is in an ON expression of a join. sql/sql_lex.cc: Fixed bug #21646. Presence of a subquery in the ON expression of a join should not block merging the view that contains this join. sql/sql_yacc.yy: Fixed bug #21646. Added a new parsing state 'IN_ON', true when the parser is in an ON expression of a join. --- mysql-test/r/view.result | 14 ++++++++++++++ mysql-test/t/view.test | 18 ++++++++++++++++++ sql/mysql_priv.h | 3 ++- sql/sql_lex.cc | 3 ++- sql/sql_yacc.yy | 8 ++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 9c05aba168c..7b81072cfd7 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2935,4 +2935,18 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 DROP VIEW v1; DROP TABLE t1; +CREATE TABLE t1(pk int PRIMARY KEY); +CREATE TABLE t2(pk int PRIMARY KEY, fk int, ver int, org int); +CREATE ALGORITHM=MERGE VIEW v1 AS +SELECT t1.* +FROM t1 JOIN t2 +ON t2.fk = t1.pk AND +t2.ver = (SELECT MAX(t.ver) FROM t2 t WHERE t.org = t2.org); +SHOW WARNINGS; +Level Code Message +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`)))))) +DROP VIEW v1; +DROP TABLE t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 4745804e847..b8cbb491832 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2850,4 +2850,22 @@ EXPLAIN SELECT * FROM v1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1); DROP VIEW v1; DROP TABLE t1; + +# +# Bug #21646: view qith a subquery in ON expression +# + +CREATE TABLE t1(pk int PRIMARY KEY); +CREATE TABLE t2(pk int PRIMARY KEY, fk int, ver int, org int); + +CREATE ALGORITHM=MERGE VIEW v1 AS +SELECT t1.* + FROM t1 JOIN t2 + ON t2.fk = t1.pk AND + t2.ver = (SELECT MAX(t.ver) FROM t2 t WHERE t.org = t2.org); +SHOW WARNINGS; +SHOW CREATE VIEW v1; + +DROP VIEW v1; +DROP TABLE t1, t2; --echo End of 5.0 tests. diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f293c769d75..f011aa42437 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -446,7 +446,8 @@ enum enum_parsing_place NO_MATTER, IN_HAVING, SELECT_LIST, - IN_WHERE + IN_WHERE, + IN_ON }; struct st_table; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index d0087b14d6a..788276ac654 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1710,7 +1710,8 @@ bool st_lex::can_be_merged() unit= unit->next_unit()) { if (unit->first_select()->parent_lex == this && - (unit->item == 0 || unit->item->place() != IN_WHERE)) + (unit->item == 0 || + (unit->item->place() != IN_WHERE && unit->item->place() != IN_ON))) { selects_allow_merge= 0; break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e39deadbf12..d027af8941b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5212,11 +5212,13 @@ join_table: /* Change the current name resolution context to a local context. */ if (push_new_name_resolution_context(YYTHD, $1, $3)) YYABORT; + Select->parsing_place= IN_ON; } expr { add_join_on($3,$6); Lex->pop_context(); + Select->parsing_place= NO_MATTER; } | table_ref STRAIGHT_JOIN table_factor ON @@ -5225,12 +5227,14 @@ join_table: /* Change the current name resolution context to a local context. */ if (push_new_name_resolution_context(YYTHD, $1, $3)) YYABORT; + Select->parsing_place= IN_ON; } expr { $3->straight=1; add_join_on($3,$6); Lex->pop_context(); + Select->parsing_place= NO_MATTER; } | table_ref normal_join table_ref USING @@ -5254,6 +5258,7 @@ join_table: /* Change the current name resolution context to a local context. */ if (push_new_name_resolution_context(YYTHD, $1, $5)) YYABORT; + Select->parsing_place= IN_ON; } expr { @@ -5261,6 +5266,7 @@ join_table: Lex->pop_context(); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; + Select->parsing_place= NO_MATTER; } | table_ref LEFT opt_outer JOIN_SYM table_factor { @@ -5285,6 +5291,7 @@ join_table: /* Change the current name resolution context to a local context. */ if (push_new_name_resolution_context(YYTHD, $1, $5)) YYABORT; + Select->parsing_place= IN_ON; } expr { @@ -5293,6 +5300,7 @@ join_table: YYABORT; add_join_on($$, $8); Lex->pop_context(); + Select->parsing_place= NO_MATTER; } | table_ref RIGHT opt_outer JOIN_SYM table_factor { From ca5e29475c8ae52035214c710be04bcb1ed13177 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Sep 2006 12:53:53 +0300 Subject: [PATCH 11/15] Bug #21174: Index degrades sort performance and optimizer does not honor IGNORE INDEX - reversed the patch for 5.0 and moved to 5.1 mysql-test/r/group_by.result: Bug #21174: Index degrades sort performance and optimizer does not honor IGNORE INDEX - reversed the patch for 5.0 mysql-test/t/group_by.test: Bug #21174: Index degrades sort performance and optimizer does not honor IGNORE INDEX - reversed the patch for 5.0 sql/sql_select.cc: Bug #21174: Index degrades sort performance and optimizer does not honor IGNORE INDEX - reversed the patch for 5.0 --- mysql-test/r/group_by.result | 9 --------- mysql-test/t/group_by.test | 12 ------------ sql/sql_select.cc | 2 -- 3 files changed, 23 deletions(-) diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index ef057e04d1a..5eb2e5744c1 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -821,12 +821,3 @@ a b real_b 68 France France DROP VIEW v1; DROP TABLE t1,t2; -CREATE TABLE t1 (a INT, b INT, KEY(a)); -INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4); -EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 5 NULL 4 -EXPLAIN SELECT a, SUM(b) FROM t1 IGNORE INDEX (a) GROUP BY a LIMIT 2; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort -DROP TABLE t1; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 8a514108dc3..ce1e4e59600 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -655,15 +655,3 @@ where t2.b=v1.a GROUP BY t2.b; DROP VIEW v1; DROP TABLE t1,t2; - -# -# Bug #21174: Index degrades sort performance and -# optimizer does not honor IGNORE INDEX -# -CREATE TABLE t1 (a INT, b INT, KEY(a)); -INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4); - -EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2; -EXPLAIN SELECT a, SUM(b) FROM t1 IGNORE INDEX (a) GROUP BY a LIMIT 2; - -DROP TABLE t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c38a9f4e637..d43f9fa214f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11735,8 +11735,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, We must not try to use disabled keys. */ usable_keys= table->s->keys_in_use; - /* we must not consider keys that are disabled by IGNORE INDEX */ - usable_keys.intersect(table->keys_in_use_for_query); for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next) { From 0b199a5103593a8e3dfff0c59d8aaec7a4616b4d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Sep 2006 15:45:17 -0400 Subject: [PATCH 12/15] Fixed incorrect merge of gluh's reversion of B-g#21432. mysql-test/r/ctype_utf8.result: Removed test that should have been reverted with gluh's reversion of B-g#21432. mysql-test/t/ctype_utf8.test: Removed test that should have been reverted with gluh's reversion of B-g#21432. --- mysql-test/r/ctype_utf8.result | 12 ------------ mysql-test/t/ctype_utf8.test | 18 ------------------ 2 files changed, 30 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index c6a60b0cea0..9c37c688d1e 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1340,18 +1340,6 @@ select a from t1 group by a; a e drop table t1; -set names utf8; -grant select on test.* to юзер_юзер@localhost; -user() -юзер_юзер@localhost -revoke all on test.* from юзер_юзер@localhost; -drop user юзер_юзер@localhost; -create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -select database(); -database() -имя_базы_в_кодировке_утф8_длиной_больше_чем_45 -drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; use test; create table t1(a char(10)) default charset utf8; insert into t1 values ('123'), ('456'); diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index daee215f593..bf906464481 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1069,24 +1069,6 @@ explain select a from t1 group by a; select a from t1 group by a; drop table t1; - -# -# Bug#20393: User name truncation in mysql client -# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte -# -set names utf8; -#create user юзер_юзер@localhost; -grant select on test.* to юзер_юзер@localhost; ---exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()" -revoke all on test.* from юзер_юзер@localhost; -drop user юзер_юзер@localhost; - -create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -select database(); -drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -use test; - # # Bug #20204: "order by" changes the results returned # From d332c37c584e294aa22e570808d8c3ac44f743ba Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Sep 2006 01:00:18 +0400 Subject: [PATCH 13/15] Fixed bug#5505: Wrong error message on INSERT into a view On an INSERT into an updatable but non-insertable view an error message was issued stating the view being not updatable. This can lead to a confusion of a user. A new error message is introduced. Is is showed when a user tries to insert into a non-insertable view. sql/sql_base.cc: Fixed bug#5505: Wrong error message on INSERT into a view The update_non_unique_table_error() function now issues proper error for an INSERT. sql/sql_insert.cc: Fixed bug#5505: Wrong error message on INSERT into a view Issue the ER_NON_INSERTABLE_TABLE error instead of the ER_NON_UPDATABLE_TABLE on insert into a view. sql/sql_view.cc: Fixed bug#5505: Wrong error message on INSERT into a view Issue the ER_NON_INSERTABLE_TABLE error instead of the ER_NON_UPDATABLE_TABLE on insert into a view. mysql-test/r/view.result: Added the test case for bug#5505: Wrong error message on INSERT into a view Corrected a few test cases after fixing bug#5505 mysql-test/t/view.test: Added the test case for bug#5505: Wrong error message on INSERT into a view Corrected a few test cases after fixing bug#5505 sql/share/errmsg.txt: Fixed bug#5505: Wrong error message on INSERT into a view Added the ER_NON_INSERTABLE_TABLE error definition. --- mysql-test/r/view.result | 27 +++++++++++++++++---------- mysql-test/t/view.test | 32 ++++++++++++++++++++++---------- sql/share/errmsg.txt | 3 +++ sql/sql_base.cc | 5 ++++- sql/sql_insert.cc | 4 ++-- sql/sql_view.cc | 2 +- 6 files changed, 49 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 9c05aba168c..262ed48a0c4 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -472,11 +472,11 @@ create view v3 (x,y,z) as select b, a, b from t1; create view v4 (x,y,z) as select c+1, b, a from t1; create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1; insert into v3 values (-60,4,30); -ERROR HY000: The target table v3 of the INSERT is not updatable +ERROR HY000: The target table v3 of the INSERT is not insertable-into insert into v4 values (-60,4,30); -ERROR HY000: The target table v4 of the INSERT is not updatable +ERROR HY000: The target table v4 of the INSERT is not insertable-into insert into v5 values (-60,4,30); -ERROR HY000: The target table v5 of the INSERT is not updatable +ERROR HY000: The target table v5 of the INSERT is not insertable-into insert into v1 values (-60,4,30); insert into v1 (z,y,x) values (50,6,-100); insert into v2 values (5,40); @@ -499,11 +499,11 @@ create view v3 (x,y,z) as select b, a, b from t1; create view v4 (x,y,z) as select c+1, b, a from t1; create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1; insert into v3 select c, b, a from t2; -ERROR HY000: The target table v3 of the INSERT is not updatable +ERROR HY000: The target table v3 of the INSERT is not insertable-into insert into v4 select c, b, a from t2; -ERROR HY000: The target table v4 of the INSERT is not updatable +ERROR HY000: The target table v4 of the INSERT is not insertable-into insert into v5 select c, b, a from t2; -ERROR HY000: The target table v5 of the INSERT is not updatable +ERROR HY000: The target table v5 of the INSERT is not insertable-into insert into v1 select c, b, a from t2; insert into v1 (z,y,x) select a+20,b+2,-100 from t2; insert into v2 select b+1, a+10 from t2; @@ -1352,14 +1352,14 @@ drop table t1; create table t1 (s1 smallint); create view v1 as select * from t1 where 20 < (select (s1) from t1); insert into v1 values (30); -ERROR HY000: The target table v1 of the INSERT is not updatable +ERROR HY000: The target table v1 of the INSERT is not insertable-into create view v2 as select * from t1; create view v3 as select * from t1 where 20 < (select (s1) from v2); insert into v3 values (30); -ERROR HY000: The target table v3 of the INSERT is not updatable +ERROR HY000: The target table v3 of the INSERT is not insertable-into create view v4 as select * from v2 where 20 < (select (s1) from t1); insert into v4 values (30); -ERROR HY000: The target table v4 of the INSERT is not updatable +ERROR HY000: The target table v4 of the INSERT is not insertable-into drop view v4, v3, v2, v1; drop table t1; create table t1 (a int); @@ -2911,7 +2911,7 @@ INSERT INTO v2 VALUES (0); RETURN 0; END | SELECT f2(); -ERROR HY000: The target table v2 of the INSERT is not updatable +ERROR HY000: The target table v2 of the INSERT is not insertable-into DROP FUNCTION f1; DROP FUNCTION f2; DROP VIEW v1, v2; @@ -2935,4 +2935,11 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 DROP VIEW v1; DROP TABLE t1; +create table t1 (s1 int); +create view v1 as select s1 as a, s1 as b from t1; +insert into v1 values (1,1); +ERROR HY000: The target table v1 of the INSERT is not insertable-into +update v1 set a = 5; +drop view v1; +drop table t1; End of 5.0 tests. diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 4745804e847..1a022cdbf66 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -347,13 +347,13 @@ create view v3 (x,y,z) as select b, a, b from t1; create view v4 (x,y,z) as select c+1, b, a from t1; create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1; # try insert to VIEW with fields duplicate --- error 1288 +-- error 1470 insert into v3 values (-60,4,30); # try insert to VIEW with expression in SELECT list --- error 1288 +-- error 1470 insert into v4 values (-60,4,30); # try insert to VIEW using temporary table algorithm --- error 1288 +-- error 1470 insert into v5 values (-60,4,30); insert into v1 values (-60,4,30); insert into v1 (z,y,x) values (50,6,-100); @@ -375,13 +375,13 @@ create view v3 (x,y,z) as select b, a, b from t1; create view v4 (x,y,z) as select c+1, b, a from t1; create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1; # try insert to VIEW with fields duplicate --- error 1288 +-- error 1470 insert into v3 select c, b, a from t2; # try insert to VIEW with expression in SELECT list --- error 1288 +-- error 1470 insert into v4 select c, b, a from t2; # try insert to VIEW using temporary table algorithm --- error 1288 +-- error 1470 insert into v5 select c, b, a from t2; insert into v1 select c, b, a from t2; insert into v1 (z,y,x) select a+20,b+2,-100 from t2; @@ -1249,14 +1249,14 @@ drop table t1; # create table t1 (s1 smallint); create view v1 as select * from t1 where 20 < (select (s1) from t1); --- error 1288 +-- error 1470 insert into v1 values (30); create view v2 as select * from t1; create view v3 as select * from t1 where 20 < (select (s1) from v2); --- error 1288 +-- error 1470 insert into v3 values (30); create view v4 as select * from v2 where 20 < (select (s1) from t1); --- error 1288 +-- error 1470 insert into v4 values (30); drop view v4, v3, v2, v1; drop table t1; @@ -2825,7 +2825,7 @@ BEGIN END | delimiter ;| ---error ER_NON_UPDATABLE_TABLE +--error ER_NON_INSERTABLE_TABLE SELECT f2(); DROP FUNCTION f1; @@ -2850,4 +2850,16 @@ EXPLAIN SELECT * FROM v1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1); DROP VIEW v1; DROP TABLE t1; + +# +# Bug #5505: Wrong error message on INSERT into a view +# +create table t1 (s1 int); +create view v1 as select s1 as a, s1 as b from t1; +--error 1470 +insert into v1 values (1,1); +update v1 set a = 5; +drop view v1; +drop table t1; + --echo End of 5.0 tests. diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index d10f66e3878..151e73460ba 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5629,3 +5629,6 @@ ER_HOSTNAME eng "host name" ER_WRONG_STRING_LENGTH eng "String '%-.70s' is too long for %s (should be no longer than %d)" +ER_NON_INSERTABLE_TABLE + eng "The target table %-.100s of the %s is not insertable-into" + diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c29c610b200..85be84d1270 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -902,8 +902,11 @@ void update_non_unique_table_error(TABLE_LIST *update, */ if (update->view) { + /* Issue the ER_NON_INSERTABLE_TABLE error for an INSERT */ if (update->view == duplicate->view) - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), update->alias, operation); + my_error(!strncmp(operation, "INSERT", 6) ? + ER_NON_INSERTABLE_TABLE : ER_NON_UPDATABLE_TABLE, MYF(0), + update->alias, operation); else my_error(ER_VIEW_PREVENT_UPDATE, MYF(0), (duplicate->view ? duplicate->alias : update->alias), diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b5dab814d08..3db6eae8695 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -111,7 +111,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, if (!table_list->updatable) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT"); + my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT"); return -1; } @@ -214,7 +214,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, (table_list->view && check_view_insertability(thd, table_list))) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT"); + my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT"); return -1; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 4e2b48d9faf..94c5ad331dd 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1574,7 +1574,7 @@ bool insert_view_fields(THD *thd, List *list, TABLE_LIST *view) list->push_back(fld); else { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "INSERT"); + my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT"); DBUG_RETURN(TRUE); } } From 04bf9cc7c6f17d9c6ab14a7521c1ab1708f50993 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Sep 2006 01:35:11 +0400 Subject: [PATCH 14/15] view.test: After merge fix mysql-test/t/view.test: After merge fix --- mysql-test/t/view.test | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index c732a019048..b631d2032c4 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -347,13 +347,13 @@ create view v3 (x,y,z) as select b, a, b from t1; create view v4 (x,y,z) as select c+1, b, a from t1; create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1; # try insert to VIEW with fields duplicate --- error 1470 +-- error 1471 insert into v3 values (-60,4,30); # try insert to VIEW with expression in SELECT list --- error 1470 +-- error 1471 insert into v4 values (-60,4,30); # try insert to VIEW using temporary table algorithm --- error 1470 +-- error 1471 insert into v5 values (-60,4,30); insert into v1 values (-60,4,30); insert into v1 (z,y,x) values (50,6,-100); @@ -375,13 +375,13 @@ create view v3 (x,y,z) as select b, a, b from t1; create view v4 (x,y,z) as select c+1, b, a from t1; create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1; # try insert to VIEW with fields duplicate --- error 1470 +-- error 1471 insert into v3 select c, b, a from t2; # try insert to VIEW with expression in SELECT list --- error 1470 +-- error 1471 insert into v4 select c, b, a from t2; # try insert to VIEW using temporary table algorithm --- error 1470 +-- error 1471 insert into v5 select c, b, a from t2; insert into v1 select c, b, a from t2; insert into v1 (z,y,x) select a+20,b+2,-100 from t2; @@ -1249,14 +1249,14 @@ drop table t1; # create table t1 (s1 smallint); create view v1 as select * from t1 where 20 < (select (s1) from t1); --- error 1470 +-- error 1471 insert into v1 values (30); create view v2 as select * from t1; create view v3 as select * from t1 where 20 < (select (s1) from v2); --- error 1470 +-- error 1471 insert into v3 values (30); create view v4 as select * from v2 where 20 < (select (s1) from t1); --- error 1470 +-- error 1471 insert into v4 values (30); drop view v4, v3, v2, v1; drop table t1; @@ -2856,7 +2856,7 @@ DROP TABLE t1; # create table t1 (s1 int); create view v1 as select s1 as a, s1 as b from t1; ---error 1470 +--error 1471 insert into v1 values (1,1); update v1 set a = 5; drop view v1; From cb0a8b546c5df9bf639cd3ed90744a5e97ac3005 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Sep 2006 21:40:43 -0400 Subject: [PATCH 15/15] Fixed bad fix for a bad merge. --- mysql-test/r/ctype_utf8.result | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 9c37c688d1e..92f4cb53889 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1340,7 +1340,6 @@ select a from t1 group by a; a e drop table t1; -use test; create table t1(a char(10)) default charset utf8; insert into t1 values ('123'), ('456'); explain