From 7dc4e4a5f96fbec05df739f6562d39bcc5bbf28b Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 26 Jan 2008 21:45:35 -0800 Subject: Fixed bug #33833. Two disjuncts containing equalities of the form key=const1 and key=const2 can be merged into one if const1 is equal to const2. To check it the common collation of the constants were used rather than the collation of the field key. For example when the default collation of the constants was cases insensitive while the collation of the field was case sensitive, then two or-ed equality predicates key='b' and key='B' incorrectly were merged into one f='b'. As a result ref access was used instead of range access and wrong result sets were returned in many cases. Fixed the problem by comparing constant in the or-ed predicate with collation of the key field. mysql-test/r/range.result: Added a test case for bug #33833. mysql-test/t/range.test: Added a test case for bug #33833. sql/item.cc: Fixed bug #33833. Added the method eq_by_collation that compares two items almost as the method Item::eq, but it rather enforces a given collation for the comparison. sql/item.h: Fixed bug #33833. Added the method eq_by_collation that compares two items almost as the method Item::eq, but it rather enforces a given collation for the comparison. --- mysql-test/r/range.result | 13 +++++++++++++ mysql-test/t/range.test | 17 +++++++++++++++++ sql/item.cc | 43 +++++++++++++++++++++++++++++++++++++++++++ sql/item.h | 1 + sql/sql_select.cc | 4 +++- 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index e0084b53320..9b1da4ffc48 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1153,3 +1153,16 @@ explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= ' id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range dateval dateval 4 NULL 2 Using where drop table t1; +CREATE TABLE t1 ( +a varchar(32), index (a) +) DEFAULT CHARSET=latin1 COLLATE=latin1_bin; +INSERT INTO t1 VALUES +('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A'); +SELECT a FROM t1 WHERE a='b' OR a='B'; +a +B +B +EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 35 NULL 3 Using where; Using index +DROP TABLE t1; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 87ba3510326..1352b366508 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -955,4 +955,21 @@ explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= ' drop table t1; +# +# Bug #33833: different or-ed predicates were erroneously merged into one that +# resulted in ref access instead of range access and a wrong result set +# + +CREATE TABLE t1 ( + a varchar(32), index (a) +) DEFAULT CHARSET=latin1 COLLATE=latin1_bin; + +INSERT INTO t1 VALUES + ('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A'); + +SELECT a FROM t1 WHERE a='b' OR a='B'; +EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B'; + +DROP TABLE t1; + # End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 713e7709bcb..182632bb40f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4302,6 +4302,49 @@ String *Item::check_well_formed_result(String *str, bool send_error) return str; } +/* + Compare two items using a given collation + + SYNOPSIS + eq_by_collation() + item item to compare with + binary_cmp TRUE <-> compare as binaries + cs collation to use when comparing strings + + DESCRIPTION + This method works exactly as Item::eq if the collation cs coincides with + the collation of the compared objects. Otherwise, first the collations that + differ from cs are replaced for cs and then the items are compared by + Item::eq. After the comparison the original collations of items are + restored. + + RETURN + 1 compared items has been detected as equal + 0 otherwise +*/ + +bool Item::eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs) +{ + CHARSET_INFO *save_cs= 0; + CHARSET_INFO *save_item_cs= 0; + if (collation.collation != cs) + { + save_cs= collation.collation; + collation.collation= cs; + } + if (item->collation.collation != cs) + { + save_item_cs= item->collation.collation; + item->collation.collation= cs; + } + bool res= eq(item, binary_cmp); + if (save_cs) + collation.collation= save_cs; + if (save_item_cs) + item->collation.collation= save_item_cs; + return res; +} + /* Create a field to hold a string value from an item diff --git a/sql/item.h b/sql/item.h index 5f511557f47..f87499f23e3 100644 --- a/sql/item.h +++ b/sql/item.h @@ -873,6 +873,7 @@ public: virtual Field::geometry_type get_geometry_type() const { return Field::GEOM_GEOMETRY; }; String *check_well_formed_result(String *str, bool send_error= 0); + bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs); }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 87935b5548f..bdea25ab99d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2887,7 +2887,9 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, } } else if (old->eq_func && new_fields->eq_func && - old->val->eq(new_fields->val, old->field->binary())) + old->val->eq_by_collation(new_fields->val, + old->field->binary(), + old->field->charset())) { old->level= and_level; -- cgit v1.2.1 From b46bc4a05b8763897d961853fce21ab7eb142e34 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Jan 2008 23:46:26 +0300 Subject: Bug#30787: Stored function ignores user defined alias. Simple subselects are pulled into upper selects. This operation substitutes the pulled subselect for the first item from the select list of the subselect. If an alias is defined for a subselect it is inherited by the replacement item. As this is done after fix_fields phase this alias isn't showed if the replacement item is a stored function. This happens because the Item_func_sp::make_field function makes send field from its result_field and ignores the defined alias. Now when an alias is defined the Item_func_sp::make_field function sets it for the returned field. mysql-test/t/sp.test: Added a test case for the bug#30787: Stored function ignores user defined alias. mysql-test/r/sp.result: Added a test case for the bug#30787: Stored function ignores user defined alias. sql/item_func.cc: Bug#30787: Stored function ignores user defined alias. Now when an alias is defined the Item_func_sp::make_field function sets it for the returned field. --- mysql-test/r/sp.result | 17 +++++++++++++++++ mysql-test/t/sp.test | 19 +++++++++++++++++++ sql/item_func.cc | 2 ++ 3 files changed, 38 insertions(+) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 061bbafd9a1..d93bc858cc3 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6578,6 +6578,23 @@ DROP PROCEDURE db28318_a.t1; DROP PROCEDURE db28318_b.t2; DROP DATABASE db28318_a; DROP DATABASE db28318_b; +# +# Bug#30787: Stored function ignores user defined alias. +# +use test; +drop function if exists func30787; +create table t1(f1 int); +insert into t1 values(1),(2); +create function func30787(p1 int) returns int +begin +return p1; +end | +select (select func30787(f1)) as ttt from t1; +ttt +1 +2 +drop function func30787; +drop table t1; # ------------------------------------------------------------------ # -- End of 5.0 tests # ------------------------------------------------------------------ diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 785e7e3793c..b9cba0f489f 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -7699,6 +7699,25 @@ DROP PROCEDURE db28318_b.t2; DROP DATABASE db28318_a; DROP DATABASE db28318_b; +--echo # +--echo # Bug#30787: Stored function ignores user defined alias. +--echo # +use test; +--disable_warnings +drop function if exists func30787; +--enable_warnings +create table t1(f1 int); +insert into t1 values(1),(2); +delimiter |; +create function func30787(p1 int) returns int +begin + return p1; +end | +delimiter ;| +select (select func30787(f1)) as ttt from t1; +drop function func30787; +drop table t1; + --echo # ------------------------------------------------------------------ --echo # -- End of 5.0 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index 639e069d24e..dbde4237511 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5515,6 +5515,8 @@ Item_func_sp::make_field(Send_field *tmp_field) DBUG_ENTER("Item_func_sp::make_field"); DBUG_ASSERT(sp_result_field); sp_result_field->make_field(tmp_field); + if (name) + tmp_field->col_name= name; DBUG_VOID_RETURN; } -- cgit v1.2.1 From 653ab4eeaab60e7eb239c53ec8125683ba1ed697 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Feb 2008 13:00:40 +0500 Subject: Fix for bug #25162: Backing up DB from 5.1 adds 'USING BTREE' to KEYs on table creates The problem was in incompatible syntax for key definition in CREATE TABLE. 5.0 supports only the following syntax for key definition (see "CREATE TABLE syntax" in the manual): {INDEX|KEY} [index_name] [index_type] (index_col_name,...) While 5.1 parser supports the above syntax, the "preferred" syntax was changed to: {INDEX|KEY} [index_name] (index_col_name,...) [index_type] The above syntax is used in 5.1 for the SHOW CREATE TABLE output, which led to dumps generated by 5.1 being incompatible with 5.0. Fixed by changing the parser in 5.0 to support both 5.0 and 5.1 syntax for key definition. mysql-test/r/create.result: Added a test case for bug #25162. mysql-test/t/create.test: Added a test case for bug #25162. sql/sql_yacc.yy: Changed the parser to support both 5.0 and 5.1 syntax for index type specification in CREATE TABLE. --- mysql-test/r/create.result | 14 ++++++++++++++ mysql-test/t/create.test | 24 ++++++++++++++++++++++++ sql/sql_yacc.yy | 6 +++--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 3d7486b6ba2..53c2058f3ec 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1532,4 +1532,18 @@ Handler_read_prev 0 Handler_read_rnd 0 Handler_read_rnd_next 7 drop table t1,t2; +CREATE TABLE t1(c1 VARCHAR(33), KEY USING BTREE (c1)); +DROP TABLE t1; +CREATE TABLE t1(c1 VARCHAR(33), KEY (c1) USING BTREE); +DROP TABLE t1; +CREATE TABLE t1(c1 VARCHAR(33), KEY USING BTREE (c1) USING HASH) ENGINE=MEMORY; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 c1 1 c1 NULL 0 NULL NULL YES HASH +DROP TABLE t1; +CREATE TABLE t1(c1 VARCHAR(33), KEY USING HASH (c1) USING BTREE) ENGINE=MEMORY; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 c1 1 c1 A NULL NULL NULL YES BTREE +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 64081c0248a..97a7ea71b29 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1148,4 +1148,28 @@ create table t2 select sql_big_result f1,count(f2) from t1 group by f1; show status like 'handler_read%'; drop table t1,t2; +# +# Bug #25162: Backing up DB from 5.1 adds 'USING BTREE' to KEYs on table creates +# + +# Show that the old syntax for index type is supported +CREATE TABLE t1(c1 VARCHAR(33), KEY USING BTREE (c1)); +DROP TABLE t1; + +# Show that the new syntax for index type is supported +CREATE TABLE t1(c1 VARCHAR(33), KEY (c1) USING BTREE); +DROP TABLE t1; + +# Show that in case of multiple index type definitions, the last one takes +# precedence + +CREATE TABLE t1(c1 VARCHAR(33), KEY USING BTREE (c1) USING HASH) ENGINE=MEMORY; +SHOW INDEX FROM t1; +DROP TABLE t1; + +CREATE TABLE t1(c1 VARCHAR(33), KEY USING HASH (c1) USING BTREE) ENGINE=MEMORY; +SHOW INDEX FROM t1; +DROP TABLE t1; + + --echo End of 5.0 tests diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c4aca1df7ec..af57fbdb108 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2982,15 +2982,15 @@ column_def: ; key_def: - key_type opt_ident key_alg '(' key_list ')' + key_type opt_ident key_alg '(' key_list ')' key_alg { LEX *lex=Lex; - Key *key= new Key($1, $2, $3, 0, lex->col_list); + Key *key= new Key($1, $2, $7 ? $7 : $3, 0, lex->col_list); lex->alter_info.key_list.push_back(key); lex->col_list.empty(); /* Alloced by sql_alloc */ } - | opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')' + | opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')' key_alg { LEX *lex=Lex; const char *key_name= $3 ? $3:$1; -- cgit v1.2.1 From ddf8644edcd089b215e783202859aa636090be77 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Feb 2008 12:56:49 +0100 Subject: Bug#21567: mysqld doesn't react to Ctrl-C when run under GDB even with the --gdb option Don't block SIGINT (Control-C) when --gdb is passed to mysqld. Was broken at least on OS X. (kudos to Mattias Jonsson) sql/mysqld.cc: Don't block SIGINT when TEST_SIGINT (--gdb) is used, even if thr_kill_signal is some other signal (SIGUSR2) and pthread_sigmask() in signal_hand() isn't good enough. --- sql/mysqld.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 08c2b60fa79..2f65597e2b7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2211,10 +2211,6 @@ static void init_signals(void) struct sigaction sa; DBUG_ENTER("init_signals"); - if (test_flags & TEST_SIGINT) - { - my_sigset(thr_kill_signal, end_thread_signal); - } my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called! if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL)) @@ -2251,7 +2247,6 @@ static void init_signals(void) (void) sigemptyset(&set); my_sigset(SIGPIPE,SIG_IGN); sigaddset(&set,SIGPIPE); - sigaddset(&set,SIGINT); #ifndef IGNORE_SIGHUP_SIGQUIT sigaddset(&set,SIGQUIT); sigaddset(&set,SIGHUP); @@ -2273,9 +2268,12 @@ static void init_signals(void) sigaddset(&set,THR_SERVER_ALARM); if (test_flags & TEST_SIGINT) { + my_sigset(thr_kill_signal, end_thread_signal); // May be SIGINT sigdelset(&set, thr_kill_signal); } + else + sigaddset(&set,SIGINT); sigprocmask(SIG_SETMASK,&set,NULL); pthread_sigmask(SIG_SETMASK,&set,NULL); DBUG_VOID_RETURN; -- cgit v1.2.1 From f54528b9931310057377555ca8bde1fd99bfb160 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 02:33:21 +0400 Subject: Fixed bug#30059. Server handles truncation for assignment of too-long values into CHAR/VARCHAR/TEXT columns in a different ways when the truncated characters are spaces: 1. CHAR(N) columns silently ignore end-space truncation; 2. TEXT columns post a truncation warning/error in the non-strict/strict mode. 3. VARCHAR columns always post a truncation note in any mode. Space truncation processing has been synchronised over CHAR/VARCHAR/TEXT columns: current behavior of VARCHAR columns has been propagated as standard. Binary-encoded string/BLOB columns are not affected. mysql-test/r/heap.result: Updated test case for bug#30059. mysql-test/r/innodb.result: Updated test case for bug#30059. mysql-test/r/myisam.result: Updated test case for bug#30059. mysql-test/r/strict.result: Updated test case for bug#30059. mysql-test/r/type_binary.result: Updated test case for bug#30059. mysql-test/r/warnings.result: Added test case for bug#30059. mysql-test/t/warnings.test: Added test case for bug#30059. sql/field.cc: Fixed bug#30059. The report_data_too_long function was replaced with the Field_longstr::report_if_important_data method. The Field_string::store and the Field_blob::store methods was synchronized with the Field_varstring::store method. Changes: 1. to CHAR(N): posting of space truncation note has been added in both (strict and non-strict) modes; 2. to BLOBs: a check for space truncation has been added, a warning in the non-strict mode and an error message in the strict mode have been replaced with a truncation note. Similar parts of Field_string::store, Field_blob::store and Field_varstring::store have been moved to the Field_longstr::report_if_important_data method. sql/field.h: Fixed bug#30059. The Field_longstr::report_if_important_data method has been declared. --- mysql-test/r/heap.result | 1 + mysql-test/r/innodb.result | 1 + mysql-test/r/myisam.result | 1 + mysql-test/r/strict.result | 2 ++ mysql-test/r/type_binary.result | 1 + mysql-test/r/warnings.result | 38 +++++++++++++++++++++ mysql-test/t/warnings.test | 33 ++++++++++++++++++ sql/field.cc | 74 +++++++++++++++++------------------------ sql/field.h | 2 ++ 9 files changed, 110 insertions(+), 43 deletions(-) diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index 906c431b834..adfcc00174f 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -256,6 +256,7 @@ set @a=repeat(' ',20); insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); Warnings: Note 1265 Data truncated for column 'v' at row 1 +Note 1265 Data truncated for column 'c' at row 1 select concat('*',v,'*',c,'*',t,'*') from t1; concat('*',v,'*',c,'*',t,'*') *+ *+*+ * diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 854712fdb1d..774e0bd167b 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1901,6 +1901,7 @@ set @a=repeat(' ',20); insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); Warnings: Note 1265 Data truncated for column 'v' at row 1 +Note 1265 Data truncated for column 'c' at row 1 select concat('*',v,'*',c,'*',t,'*') from t1; concat('*',v,'*',c,'*',t,'*') *+ *+*+ * diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 33f64d600bb..24c1cecfb4f 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1104,6 +1104,7 @@ set @a=repeat(' ',20); insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); Warnings: Note 1265 Data truncated for column 'v' at row 1 +Note 1265 Data truncated for column 'c' at row 1 select concat('*',v,'*',c,'*',t,'*') from t1; concat('*',v,'*',c,'*',t,'*') *+ *+*+ * diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 34869862a63..0a714635f70 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -934,6 +934,8 @@ NULL NULL DROP TABLE t1; CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6)); INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello '); +Warnings: +Note 1265 Data truncated for column 'col1' at row 3 INSERT INTO t1 (col1) VALUES ('hellobob'); ERROR 22001: Data too long for column 'col1' at row 1 INSERT INTO t1 (col2) VALUES ('hellobob'); diff --git a/mysql-test/r/type_binary.result b/mysql-test/r/type_binary.result index debf4ff8fb8..aaa46ab415e 100644 --- a/mysql-test/r/type_binary.result +++ b/mysql-test/r/type_binary.result @@ -125,6 +125,7 @@ create table t1 (c char(2), vc varchar(2)); insert into t1 values(0x4120, 0x4120); insert into t1 values(0x412020, 0x412020); Warnings: +Note 1265 Data truncated for column 'c' at row 1 Note 1265 Data truncated for column 'vc' at row 1 drop table t1; set @old_sql_mode= @@sql_mode, sql_mode= 'traditional'; diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 9ce1f9c825d..e74f92205aa 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -298,4 +298,42 @@ DROP TABLE t3; DROP PROCEDURE sp1; DROP PROCEDURE sp2; DROP PROCEDURE sp3; +create table t1 (c_char char(255), c_varchar varchar(255), c_tinytext tinytext); +create table t2 (c_tinyblob tinyblob); +set @c = repeat(' ', 256); +set @q = repeat('q', 256); +set sql_mode = ''; +insert into t1 values(@c, @c, @c); +Warnings: +Note 1265 Data truncated for column 'c_char' at row 1 +Note 1265 Data truncated for column 'c_varchar' at row 1 +Note 1265 Data truncated for column 'c_tinytext' at row 1 +insert into t2 values(@c); +Warnings: +Warning 1265 Data truncated for column 'c_tinyblob' at row 1 +insert into t1 values(@q, @q, @q); +Warnings: +Warning 1265 Data truncated for column 'c_char' at row 1 +Warning 1265 Data truncated for column 'c_varchar' at row 1 +Warning 1265 Data truncated for column 'c_tinytext' at row 1 +insert into t2 values(@q); +Warnings: +Warning 1265 Data truncated for column 'c_tinyblob' at row 1 +set sql_mode = 'traditional'; +insert into t1 values(@c, @c, @c); +Warnings: +Note 1265 Data truncated for column 'c_char' at row 1 +Note 1265 Data truncated for column 'c_varchar' at row 1 +Note 1265 Data truncated for column 'c_tinytext' at row 1 +insert into t2 values(@c); +ERROR 22001: Data too long for column 'c_tinyblob' at row 1 +insert into t1 values(@q, NULL, NULL); +ERROR 22001: Data too long for column 'c_char' at row 1 +insert into t1 values(NULL, @q, NULL); +ERROR 22001: Data too long for column 'c_varchar' at row 1 +insert into t1 values(NULL, NULL, @q); +ERROR 22001: Data too long for column 'c_tinytext' at row 1 +insert into t2 values(@q); +ERROR 22001: Data too long for column 'c_tinyblob' at row 1 +drop table t1, t2; End of 5.0 tests diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index 5e9d25aa09b..c42dd22024c 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -212,4 +212,37 @@ DROP PROCEDURE sp1; DROP PROCEDURE sp2; DROP PROCEDURE sp3; + +# +# Bug#30059: End-space truncation warnings are inconsistent or incorrect +# + +create table t1 (c_char char(255), c_varchar varchar(255), c_tinytext tinytext); +create table t2 (c_tinyblob tinyblob); # not affected by bug, for regression testing +set @c = repeat(' ', 256); +set @q = repeat('q', 256); + +set sql_mode = ''; + +insert into t1 values(@c, @c, @c); +insert into t2 values(@c); +insert into t1 values(@q, @q, @q); +insert into t2 values(@q); + +set sql_mode = 'traditional'; + +insert into t1 values(@c, @c, @c); +--error 1406 +insert into t2 values(@c); +--error 1406 +insert into t1 values(@q, NULL, NULL); +--error 1406 +insert into t1 values(NULL, @q, NULL); +--error 1406 +insert into t1 values(NULL, NULL, @q); +--error 1406 +insert into t2 values(@q); + +drop table t1, t2; + --echo End of 5.0 tests diff --git a/sql/field.cc b/sql/field.cc index f1e2b6a4f27..3753318b8fa 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5861,26 +5861,41 @@ check_string_copy_error(Field_str *field, } - /* - Send a truncation warning or a truncation error - after storing a too long character string info a field. + Check if we lost any important data and send a truncation error/warning SYNOPSIS - report_data_too_long() - field - Field + Field_longstr::report_if_important_data() + ptr - Truncated rest of string + end - End of truncated string - RETURN - N/A + RETURN VALUES + 0 - None was truncated (or we don't count cut fields) + 2 - Some bytes was truncated + + NOTE + Check if we lost any important data (anything in a binary string, + or any non-space in others). If only trailing spaces was lost, + send a truncation note, otherwise send a truncation error. */ -inline void -report_data_too_long(Field_str *field) +int +Field_longstr::report_if_important_data(const char *ptr, const char *end) { - if (field->table->in_use->abort_on_warning) - field->set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); - else - field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); + if ((ptr < end) && table->in_use->count_cuted_fields) + { + if (test_if_important_data(field_charset, ptr, end)) + { + if (table->in_use->abort_on_warning) + set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); + else + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); + } + else /* If we lost only spaces then produce a NOTE, not a WARNING */ + set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1); + return 2; + } + return 0; } @@ -5914,19 +5929,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) cannot_convert_error_pos, from + length)) return 2; - /* - Check if we lost any important data (anything in a binary string, - or any non-space in others). - */ - if ((from_end_pos < from + length) && table->in_use->count_cuted_fields) - { - if (test_if_important_data(field_charset, from_end_pos, from + length)) - { - report_data_too_long(this); - return 2; - } - } - return 0; + return report_if_important_data(from_end_pos, from + length); } @@ -6385,16 +6388,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) cannot_convert_error_pos, from + length)) return 2; - // Check if we lost something other than just trailing spaces - if ((from_end_pos < from + length) && table->in_use->count_cuted_fields) - { - if (test_if_important_data(field_charset, from_end_pos, from + length)) - report_data_too_long(this); - else /* If we lost only spaces then produce a NOTE, not a WARNING */ - set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1); - return 2; - } - return 0; + return report_if_important_data(from_end_pos, from + length); } @@ -7030,13 +7024,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) cannot_convert_error_pos, from + length)) return 2; - if (from_end_pos < from + length) - { - report_data_too_long(this); - return 2; - } - - return 0; + return report_if_important_data(from_end_pos, from + length); oom_error: /* Fatal OOM error */ diff --git a/sql/field.h b/sql/field.h index d681229a9fd..c82d65147ac 100644 --- a/sql/field.h +++ b/sql/field.h @@ -454,6 +454,8 @@ public: class Field_longstr :public Field_str { +protected: + int report_if_important_data(const char *ptr, const char *end); public: Field_longstr(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, -- cgit v1.2.1 From 6023a58e05431ce697e0f2acb77274c8ca1a2e03 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 04:14:50 +0400 Subject: Fixed bug#34223: Failure on assignment to my_innodb_autoextend_increment and my_innodb_commit_concurrency global variables. Type of the my_innodb_autoextend_increment and the my_innodb_commit_concurrency variables has been changed to GET_ULONG. mysql-test/r/variables.result: Added test case for bug#34223. mysql-test/t/variables.test: Added test case for bug#34223. sql/mysqld.cc: Fixed bug#34223. Last update of the getopt_ull_limit_value function introduced a sanity check for a variable type (only GET_UINT or GET_ULONG are valid types). However, my_innodb_autoextend_increment and my_innodb_commit_concurrency are declared as GET_LONG. Call stack is: sys_var_long_ptr_global::update() fix_unsigned() getopt_ull_limit_value() Type of the my_innodb_autoextend_increment and the my_innodb_commit_concurrency variables has been changed to GET_ULONG. --- mysql-test/r/variables.result | 6 ++++++ mysql-test/t/variables.test | 13 +++++++++++++ sql/mysqld.cc | 4 ++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 9c360ef4ab3..35f8a5bf6cb 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -838,6 +838,12 @@ SELECT @@log_slow_queries; 1 SET GLOBAL log_slow_queries=0; ERROR HY000: Variable 'log_slow_queries' is a read only variable +set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; +set global innodb_autoextend_increment=8; +set global innodb_autoextend_increment=@my_innodb_autoextend_increment; +set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency; +set global innodb_commit_concurrency=0; +set global innodb_commit_concurrency=@my_innodb_commit_concurrency; End of 5.0 tests set global binlog_cache_size =@my_binlog_cache_size; set global connect_timeout =@my_connect_timeout; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index c86e7dfa7f3..191022f44fb 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -696,6 +696,19 @@ SELECT @@log_slow_queries; --error 1238 SET GLOBAL log_slow_queries=0; +# +# Bug #34223: Assertion failed: (optp->var_type & 127) == 8, +# file .\my_getopt.c, line 830 +# + +set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; +set global innodb_autoextend_increment=8; +set global innodb_autoextend_increment=@my_innodb_autoextend_increment; + +set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency; +set global innodb_commit_concurrency=0; +set global innodb_commit_concurrency=@my_innodb_commit_concurrency; + --echo End of 5.0 tests # This is at the very after the versioned tests, since it involves doing diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 693b72f5c98..f98b09f4ef6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5798,7 +5798,7 @@ log and this option does nothing anymore.", "Data file autoextend increment in megabytes", (gptr*) &srv_auto_extend_increment, (gptr*) &srv_auto_extend_increment, - 0, GET_LONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0}, + 0, GET_ULONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0}, {"innodb_buffer_pool_awe_mem_mb", OPT_INNODB_BUFFER_POOL_AWE_MEM_MB, "If Windows AWE is used, the size of InnoDB buffer pool allocated from the AWE memory.", (gptr*) &innobase_buffer_pool_awe_mem_mb, (gptr*) &innobase_buffer_pool_awe_mem_mb, 0, @@ -5811,7 +5811,7 @@ log and this option does nothing anymore.", {"innodb_commit_concurrency", OPT_INNODB_COMMIT_CONCURRENCY, "Helps in performance tuning in heavily concurrent environments.", (gptr*) &srv_commit_concurrency, (gptr*) &srv_commit_concurrency, - 0, GET_LONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0}, + 0, GET_ULONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0}, {"innodb_concurrency_tickets", OPT_INNODB_CONCURRENCY_TICKETS, "Number of times a thread is allowed to enter InnoDB within the same \ SQL query after it has once got the ticket", -- cgit v1.2.1 From 4fa754433d68e90a1f1c46f6e95106b124a42cd3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 04:54:58 +0400 Subject: bdb.result: Minor post-fix for bug#30059. mysql-test/r/bdb.result: Minor post-fix for bug#30059. --- mysql-test/r/bdb.result | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index 3356d23053f..fefeeb405c5 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1325,6 +1325,7 @@ set @a=repeat(' ',20); insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); Warnings: Note 1265 Data truncated for column 'v' at row 1 +Note 1265 Data truncated for column 'c' at row 1 select concat('*',v,'*',c,'*',t,'*') from t1; concat('*',v,'*',c,'*',t,'*') *+ *+*+ * -- cgit v1.2.1 From 82f2459706887581b0017647be7db25aad026220 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 05:10:04 +0300 Subject: BUG#27732 "Possible memory leak with index_merge" The bug was that handler::clone/handler::ha_open() call caused allocation of cloned_copy->ref on the handler->table->mem_root. The allocated memory could not be reclaimed until the table is flushed, so it was possible to exhaust memory by repeatedly running index_merge queries without doing table flushes. The fix: - make handler::clone() allocate new_handler->ref on the passed mem_root - make handler::ha_open() not allocate this->ref if it has already been allocated There is no testcase as it is not possible to check small leaks from testsuite. sql/handler.cc: BUG#27732 "Possible memory leak with index_merge" - make handler::clone() allocate new_handler->ref on the passed mem_root - make handler::ha_open() not allocate this->ref if it has already been allocated --- sql/handler.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 27204ae725b..bfad10f986f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1381,6 +1381,13 @@ int ha_delete_table(THD *thd, enum db_type table_type, const char *path, handler *handler::clone(MEM_ROOT *mem_root) { handler *new_handler= get_new_handler(table, mem_root, table->s->db_type); + /* + Allocate handler->ref here because otherwise ha_open will allocate it + on this->table->mem_root and we will not be able to reclaim that memory + when the clone handler object is destroyed. + */ + if (!(new_handler->ref= (byte*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2))) + return NULL; if (new_handler && !new_handler->ha_open(table->s->path, table->db_stat, HA_OPEN_IGNORE_IF_LOCKED)) return new_handler; @@ -1420,8 +1427,9 @@ int handler::ha_open(const char *name, int mode, int test_if_locked) (void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL DBUG_ASSERT(alloc_root_inited(&table->mem_root)); - - if (!(ref= (byte*) alloc_root(&table->mem_root, ALIGN_SIZE(ref_length)*2))) + /* ref is already allocated for us if we're called from handler::clone() */ + if (!ref && !(ref= (byte*) alloc_root(&table->mem_root, + ALIGN_SIZE(ref_length)*2))) { close(); error=HA_ERR_OUT_OF_MEM; -- cgit v1.2.1 From 9c4bbbe2425ff7086332d6fe4b1630293cf99101 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 11:12:49 +0400 Subject: innodb_mysql.test, variables.result, variables.test, innodb_mysql.result: Minor post-fix for bug#34223. mysql-test/r/innodb_mysql.result: Minor post-fix for bug#34223. mysql-test/r/variables.result: Minor post-fix for bug#34223. mysql-test/t/innodb_mysql.test: Minor post-fix for bug#34223. mysql-test/t/variables.test: Minor post-fix for bug#34223. --- mysql-test/r/innodb_mysql.result | 6 ++++++ mysql-test/r/variables.result | 6 ------ mysql-test/t/innodb_mysql.test | 14 ++++++++++++++ mysql-test/t/variables.test | 13 ------------- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 2ab463e7f85..b487cfd9a4b 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1240,4 +1240,10 @@ t1 CREATE TABLE `t1` ( UNIQUE KEY `aa` (`a`(1)) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t1; +set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; +set global innodb_autoextend_increment=8; +set global innodb_autoextend_increment=@my_innodb_autoextend_increment; +set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency; +set global innodb_commit_concurrency=0; +set global innodb_commit_concurrency=@my_innodb_commit_concurrency; End of 5.0 tests diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 35f8a5bf6cb..9c360ef4ab3 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -838,12 +838,6 @@ SELECT @@log_slow_queries; 1 SET GLOBAL log_slow_queries=0; ERROR HY000: Variable 'log_slow_queries' is a read only variable -set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; -set global innodb_autoextend_increment=8; -set global innodb_autoextend_increment=@my_innodb_autoextend_increment; -set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency; -set global innodb_commit_concurrency=0; -set global innodb_commit_concurrency=@my_innodb_commit_concurrency; End of 5.0 tests set global binlog_cache_size =@my_binlog_cache_size; set global connect_timeout =@my_connect_timeout; diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 020295684b0..59ee7c274bb 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -982,4 +982,18 @@ desc t1; show create table t1; drop table t1; + +# +# Bug #34223: Assertion failed: (optp->var_type & 127) == 8, +# file .\my_getopt.c, line 830 +# + +set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; +set global innodb_autoextend_increment=8; +set global innodb_autoextend_increment=@my_innodb_autoextend_increment; + +set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency; +set global innodb_commit_concurrency=0; +set global innodb_commit_concurrency=@my_innodb_commit_concurrency; + --echo End of 5.0 tests diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 191022f44fb..c86e7dfa7f3 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -696,19 +696,6 @@ SELECT @@log_slow_queries; --error 1238 SET GLOBAL log_slow_queries=0; -# -# Bug #34223: Assertion failed: (optp->var_type & 127) == 8, -# file .\my_getopt.c, line 830 -# - -set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; -set global innodb_autoextend_increment=8; -set global innodb_autoextend_increment=@my_innodb_autoextend_increment; - -set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency; -set global innodb_commit_concurrency=0; -set global innodb_commit_concurrency=@my_innodb_commit_concurrency; - --echo End of 5.0 tests # This is at the very after the versioned tests, since it involves doing -- cgit v1.2.1 From 2c4681276e6b939850dfe64df08293769ede0a15 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 13:35:00 +0300 Subject: Bug#31590: Wrong error message on sort buffer being too small. The out of memory error was thrown when the sort buffer size were too small. This led to a user confusion. Now filesort throws the error message about sort buffer being too small. mysql-test/t/order_by.test: Added a test case for the bug#31590: Wrong error message on sort buffer being too small. mysql-test/r/order_by.result: Added a test case for the bug#31590: Wrong error message on sort buffer being too small. sql/filesort.cc: Bug#31590: Wrong error message on sort buffer being too small. Now filesort throws the error message about sort buffer being too small instead of out of memory error. --- mysql-test/r/order_by.result | 12 ++++++++++++ mysql-test/t/order_by.test | 12 ++++++++++++ sql/filesort.cc | 3 +-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index eedc2fa476b..9f6a1b3932c 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1064,3 +1064,15 @@ a b 10 00:00:10 0 00:00:00 DROP TABLE t1; +# +# Bug#31590: Wrong error message on sort buffer being too small. +# +create table t1(a int, b tinytext); +insert into t1 values (1,2),(3,2); +set session sort_buffer_size= 30000; +Warnings: +Warning 1292 Truncated incorrect sort_buffer_size value: '30000' +set session max_sort_length= 2180; +select * from t1 order by b; +ERROR HY001: Out of sort memory; increase server sort buffer size +drop table t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 29a290c7fbf..9a55c27df99 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -726,3 +726,15 @@ SELECT a, b FROM t1 ORDER BY b DESC; SELECT a, b FROM t1 ORDER BY SEC_TO_TIME(a) DESC; DROP TABLE t1; + +--echo # +--echo # Bug#31590: Wrong error message on sort buffer being too small. +--echo # +create table t1(a int, b tinytext); +insert into t1 values (1,2),(3,2); +set session sort_buffer_size= 30000; +set session max_sort_length= 2180; +--error 1038 +select * from t1 order by b; +drop table t1; + diff --git a/sql/filesort.cc b/sql/filesort.cc index 43b079e83d5..a85f9caefbe 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -215,8 +215,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, sort_keys= table_sort.sort_keys; if (memavl < min_sort_memory) { - my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG), - thd->variables.sortbuff_size); + my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG)); goto err; } if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX, -- cgit v1.2.1 From 1dbe6997bb9d5dc31d1701a3d95ae0e9118269f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 16:04:01 +0400 Subject: Fixed bug#15409: Columns with 64-element SET may not be updated with integers. SET column storing procedure has been modified to be 64bit-clean. mysql-test/r/type_set.result: Added test case for bug#15409. mysql-test/t/type_set.test: Added test case for bug#15409. sql/field.cc: Fixed bug#15409. The Field_set::store(longlong nr,...) method incompletely calculates a bit mask for the comparison with a given number: if that number is greater than 0x7F00 0000 0000 0000 (LONGLONG_MAX), it uses zero bit mask instead of 0xFFFF FFFF FFFF FFFF (ULONGLONG_MAX). Incomplete expression has been replaced with a set_bits macro call. --- mysql-test/r/type_set.result | 8 ++++++++ mysql-test/t/type_set.test | 20 ++++++++++++++++++++ sql/field.cc | 6 +++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result index 03de20baef2..9829d4951c9 100644 --- a/mysql-test/r/type_set.result +++ b/mysql-test/r/type_set.result @@ -85,3 +85,11 @@ t1 CREATE TABLE `t1` ( `f1` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1') default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +CREATE TABLE t1(c set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64')); +INSERT INTO t1 VALUES(7); +INSERT INTO t1 VALUES(9223372036854775808); +SELECT * FROM t1; +c +1,2,3 +64 +DROP TABLE t1; diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test index b1c816f3371..c7f8c59de28 100644 --- a/mysql-test/t/type_set.test +++ b/mysql-test/t/type_set.test @@ -56,3 +56,23 @@ set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17', '50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1')); show create table t1; drop table t1; + +# +# Bug#15409: Columns with SET datatype with 64-element sets +# may not be updated with integers +# + +let $i=64; +let $s='$i'; +dec $i; +while ($i) { + let $s='$i',$s; + dec $i; +} +--eval CREATE TABLE t1(c set($s)) +INSERT INTO t1 VALUES(7); +INSERT INTO t1 VALUES(9223372036854775808); +SELECT * FROM t1; +DROP TABLE t1; + +--# echo End of 5.0 tests diff --git a/sql/field.cc b/sql/field.cc index 3753318b8fa..53eafcaf2cc 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7871,10 +7871,10 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) int Field_set::store(longlong nr, bool unsigned_val) { int error= 0; - if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) - - (longlong) 1)) + ulonglong max_nr= set_bits(ulonglong, typelib->count); + if ((ulonglong) nr > max_nr) { - nr&= (longlong) (((longlong) 1 << typelib->count) - (longlong) 1); + nr&= max_nr; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); error=1; } -- cgit v1.2.1 From 075e022047983829c5dd33a90e374650d06b161b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 10 Feb 2008 23:41:57 +0400 Subject: Bug #33796 Memory leak for prepared statements in embedded server. Field data for a query was stored to the stmt->alloc that is emptied with mysql_stmt_close statement only. That means a lot of memory can be occupied without a reason if used doesn't call mysql_stmt_close often. libmysql/libmysql.c: Bug #33796 Memory leak for prepared statements in embedded server. Clean up result->alloc even if there's no 'data' created libmysqld/lib_sql.cc: Bug #33796 Memory leak for prepared statements in embedded server. alloc 'fields' in the 'result.alloc' as the 'mem_root' is only cleaned with mysql_stmt_close' --- libmysql/libmysql.c | 13 +++++-------- libmysqld/lib_sql.cc | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index e963c0e429c..6916c643f6c 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4522,14 +4522,11 @@ my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt) { MYSQL *mysql= stmt->mysql; - if (result->data) - { - /* Result buffered */ - free_root(&result->alloc, MYF(MY_KEEP_PREALLOC)); - result->data= NULL; - result->rows= 0; - stmt->data_cursor= NULL; - } + /* Result buffered */ + free_root(&result->alloc, MYF(MY_KEEP_PREALLOC)); + result->data= NULL; + result->rows= 0; + stmt->data_cursor= NULL; if (mysql && stmt->field_count && (int) stmt->state > (int) MYSQL_STMT_PREPARE_DONE) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 7f2059db7cd..0665641d3b6 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -668,7 +668,7 @@ bool Protocol::send_fields(List *list, uint flag) DBUG_RETURN(0); field_count= list->elements; - field_alloc= thd->current_stmt ? &thd->current_stmt->mem_root : + field_alloc= thd->current_stmt ? &thd->current_stmt->result.alloc : &mysql->field_alloc; if (!(client_field= mysql->fields= (MYSQL_FIELD *)alloc_root(field_alloc, -- cgit v1.2.1 From eee4d8cc869771302d944b824077040876cee5bb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Feb 2008 12:43:55 +0300 Subject: Fix for bug #33389: Selecting from a view into a table from within SP or trigger crashes server Under some circumstances a combination of VIEWs, subselects with outer references and PS/SP/triggers could lead to use of uninitialized memory and server crash as a result. Fixed by changing the code in Item_field::fix_fields() so that in cases when the field is a VIEW reference, we first check whether the field is also an outer reference, and mark it appropriately before returning. mysql-test/r/view.result: Added a test case for bug #33389. mysql-test/t/view.test: Added a test case for bug #33389. sql/item.cc: In cases when in Item_field::fix_fields() from_field is a view reference, do not return too early, i.e. before marking the reference as an outer one when needed. --- mysql-test/r/view.result | 16 ++++++++++++++++ mysql-test/t/view.test | 22 ++++++++++++++++++++++ sql/item.cc | 24 ++++++++++++------------ 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index fb36304e562..f7f6debee6e 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3618,4 +3618,20 @@ ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default val set @@sql_mode=@old_mode; drop view v1; drop table t1; +create table t1 (a int, key(a)); +create table t2 (c int); +create view v1 as select a b from t1; +create view v2 as select 1 a from t2, v1 where c in +(select 1 from t1 where b = a); +insert into t1 values (1), (1); +insert into t2 values (1), (1); +prepare stmt from "select * from v2 where a = 1"; +execute stmt; +a +1 +1 +1 +1 +drop view v1, v2; +drop table t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 340a34db5a1..b321f8604f7 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3470,5 +3470,27 @@ insert into v1 values(1); set @@sql_mode=@old_mode; drop view v1; drop table t1; + +# +# Bug #33389: Selecting from a view into a table from within SP or trigger +# crashes server +# + +create table t1 (a int, key(a)); +create table t2 (c int); + +create view v1 as select a b from t1; +create view v2 as select 1 a from t2, v1 where c in + (select 1 from t1 where b = a); + +insert into t1 values (1), (1); +insert into t2 values (1), (1); + +prepare stmt from "select * from v2 where a = 1"; +execute stmt; + +drop view v1, v2; +drop table t1, t2; + --echo End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 713e7709bcb..8283e1a13d3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3903,6 +3903,18 @@ bool Item_field::fix_fields(THD *thd, Item **reference) else if (!from_field) goto error; + if (!outer_fixed && cached_table && cached_table->select_lex && + context->select_lex && + cached_table->select_lex != context->select_lex) + { + int ret; + if ((ret= fix_outer_field(thd, &from_field, reference)) < 0) + goto error; + else if (!ret) + return FALSE; + outer_fixed= 1; + } + /* if it is not expression from merged VIEW we will set this field. @@ -3918,18 +3930,6 @@ bool Item_field::fix_fields(THD *thd, Item **reference) if (from_field == view_ref_found) return FALSE; - if (!outer_fixed && cached_table && cached_table->select_lex && - context->select_lex && - cached_table->select_lex != context->select_lex) - { - int ret; - if ((ret= fix_outer_field(thd, &from_field, reference)) < 0) - goto error; - else if (!ret) - return FALSE; - outer_fixed= 1; - } - set_field(from_field); if (thd->lex->in_sum_func && thd->lex->in_sum_func->nest_level == -- cgit v1.2.1 From cb5c4940bb7bdc49e0a291df46890185c647ecf2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Feb 2008 19:32:19 +0400 Subject: Fixed bug#33764: Wrong result with IN(), CONCAT() and implicit type conversion. Instead of copying of whole character string from a temporary buffer, the server copied a short-living pointer to that string into a long-living structure. That has been fixed. mysql-test/r/select.result: Added test case for bug#33764. mysql-test/t/select.test: Added test case for bug#33764. sql/item_cmpfunc.cc: Fixed bug#33764. Copying of a pointer has been replaced with an optional copying of a whole array to a newly allocated memory space in case of a functional source item. --- mysql-test/r/select.result | 6 ++++++ mysql-test/t/select.test | 11 +++++++++++ sql/item_cmpfunc.cc | 5 ++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 3ca84bcf34b..180da5cd7d7 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4328,4 +4328,10 @@ SELECT * FROM t1 WHERE c1 > NULL + 1; c1 DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) NOT NULL PRIMARY KEY); +INSERT INTO t1 (a) VALUES ('foo0'), ('bar0'), ('baz0'); +SELECT * FROM t1 WHERE a IN (CONCAT('foo', 0), 'bar'); +a +foo0 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index c48f2771aa8..4b52dac680c 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3672,4 +3672,15 @@ DROP TABLE t1; --echo +########################################################################### + +# +# Bug #33764: Wrong result with IN(), CONCAT() and implicit type conversion +# + +CREATE TABLE t1 (a VARCHAR(10) NOT NULL PRIMARY KEY); +INSERT INTO t1 (a) VALUES ('foo0'), ('bar0'), ('baz0'); +SELECT * FROM t1 WHERE a IN (CONCAT('foo', 0), 'bar'); +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 98bcb256138..17345e76bba 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2995,7 +2995,10 @@ void in_string::set(uint pos,Item *item) { if (res->uses_buffer_owned_by(str)) res->copy(); - *str= *res; + if (item->type() == Item::FUNC_ITEM) + str->copy(*res); + else + *str= *res; } if (!str->charset()) { -- cgit v1.2.1 From 6ffb9eafd483c2a2211f9612633ac2adc13002f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Feb 2008 19:34:12 +0400 Subject: Fixed bug#31194: Privilege ordering does not order properly for wildcard values. The server ignored escape character before wildcards during the calculation of priority values for sorting of a privilege list. (Actually the server counted an escape character as an ordinary wildcard like % or _). I.e. the table name template with a wildcard character like 'tbl_1' had higher priority in a privilege list than concrete table name without wildcards like 'tbl\_1', and some privileges of 'tbl\_1' was hidden by privileges for 'tbl_1'. The get_sort function has been modified to ignore escaped wildcards as usual. mysql-test/r/grant3.result: Added test case for bug#31194. mysql-test/t/grant3.test: Added test case for bug#31194. sql/sql_acl.cc: Fixed bug#31194. The server used the wild_prefix escape character (usually \-character) like % and _ wildcards in the get_sort function for sorting weights calculation. The get_sort function has been modified to ignore escaped wildcards and alone escapes like in the wild_case_compare function. --- mysql-test/r/grant3.result | 17 +++++++++++++++++ mysql-test/t/grant3.test | 26 ++++++++++++++++++++++++++ sql/sql_acl.cc | 4 +++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result index cc7f46855b2..f38848111ad 100644 --- a/mysql-test/r/grant3.result +++ b/mysql-test/r/grant3.result @@ -138,3 +138,20 @@ SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by user host db select_priv DROP USER CUser2@localhost; DROP USER CUser2@LOCALHOST; +CREATE DATABASE mysqltest_1; +CREATE TABLE mysqltest_1.t1 (a INT); +CREATE USER 'mysqltest1'@'%'; +GRANT SELECT, UPDATE ON `mysqltest_1`.* TO 'mysqltest1'@'%'; +REVOKE SELECT ON `mysqltest_1`.* FROM 'mysqltest1'@'%'; +GRANT SELECT, UPDATE ON `mysqltest\_1`.* TO 'mysqltest1'@'%'; +FLUSH PRIVILEGES; +SHOW GRANTS; +Grants for mysqltest1@% +GRANT USAGE ON *.* TO 'mysqltest1'@'%' +GRANT SELECT, UPDATE ON `mysqltest\_1`.* TO 'mysqltest1'@'%' +GRANT UPDATE ON `mysqltest_1`.* TO 'mysqltest1'@'%' +SELECT * FROM mysqltest_1.t1; +a +DROP USER 'mysqltest1'@'%'; +DROP DATABASE mysqltest_1; +End of 5.0 tests diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test index fac577ef0ff..8eceb851c29 100644 --- a/mysql-test/t/grant3.test +++ b/mysql-test/t/grant3.test @@ -134,3 +134,29 @@ SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by DROP USER CUser2@localhost; DROP USER CUser2@LOCALHOST; + + +# +# Bug#31194: Privilege ordering does not order properly for wildcard values +# + +CREATE DATABASE mysqltest_1; +CREATE TABLE mysqltest_1.t1 (a INT); +CREATE USER 'mysqltest1'@'%'; +GRANT SELECT, UPDATE ON `mysqltest_1`.* TO 'mysqltest1'@'%'; +REVOKE SELECT ON `mysqltest_1`.* FROM 'mysqltest1'@'%'; +GRANT SELECT, UPDATE ON `mysqltest\_1`.* TO 'mysqltest1'@'%'; +FLUSH PRIVILEGES; + +connect (conn1,localhost,mysqltest1,,); +connection conn1; +SHOW GRANTS; +SELECT * FROM mysqltest_1.t1; +disconnect conn1; + +connection default; +DROP USER 'mysqltest1'@'%'; +DROP DATABASE mysqltest_1; + + +--echo End of 5.0 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 134541368e9..851af35da32 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -668,7 +668,9 @@ static ulong get_sort(uint count,...) { for (; *str ; str++) { - if (*str == wild_many || *str == wild_one || *str == wild_prefix) + if (*str == wild_prefix && str[1]) + str++; + else if (*str == wild_many || *str == wild_one) { wild_pos= (uint) (str - start) + 1; break; -- cgit v1.2.1