From d03c7d2d28fe86d88c30f8799b78cf966e5a3ab7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Apr 2007 15:01:19 +0500 Subject: [PATCH 1/6] Bug#27069 set with identical elements are created added the check for unique elements count in SET mysql-test/r/type_set.result: test result mysql-test/t/type_set.test: test case sql/field.cc: removed the check for elements count in SET sql/sql_table.cc: added the check for unique elements count in SET --- mysql-test/r/type_set.result | 19 +++++++++++++++++++ mysql-test/t/type_set.test | 17 +++++++++++++++++ sql/field.cc | 5 ----- sql/sql_table.cc | 16 +++++++++++++--- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result index fdda4aca25c..03de20baef2 100644 --- a/mysql-test/r/type_set.result +++ b/mysql-test/r/type_set.result @@ -66,3 +66,22 @@ ss ue ue DROP TABLE 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','128')); +ERROR HY000: Too many strings for column f1 and SET +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')); +Warnings: +Note 1291 Column 'f1' has duplicated value '1' in SET +show create table t1; +Table Create Table +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; diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test index 56df3328246..b1c816f3371 100644 --- a/mysql-test/t/type_set.test +++ b/mysql-test/t/type_set.test @@ -39,3 +39,20 @@ SELECT c FROM t1 ORDER BY concat(c); DROP TABLE t1; # End of 4.1 tests + +# +# Bug#27069 set with identical elements are created +# +--error 1097 +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','128')); +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')); +show create table t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index 152c1bdc364..24cec4e1c74 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8676,11 +8676,6 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, break; case FIELD_TYPE_SET: { - if (fld_interval_list->elements > sizeof(longlong)*8) - { - my_error(ER_TOO_BIG_SET, MYF(0), fld_name); /* purecov: inspected */ - DBUG_RETURN(TRUE); - } pack_length= get_set_pack_length(fld_interval_list->elements); List_iterator it(*fld_interval_list); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8b3028f5370..a71579fb74f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -407,6 +407,7 @@ static int sort_keys(KEY *a, KEY *b) set_or_name "SET" or "ENUM" string for warning message name name of the checked column typelib list of values for the column + dup_val_count returns count of duplicate elements DESCRIPTION This function prints an warning for each value in list @@ -418,11 +419,12 @@ static int sort_keys(KEY *a, KEY *b) void check_duplicates_in_interval(const char *set_or_name, const char *name, TYPELIB *typelib, - CHARSET_INFO *cs) + CHARSET_INFO *cs, unsigned int *dup_val_count) { TYPELIB tmp= *typelib; const char **cur_value= typelib->type_names; unsigned int *cur_length= typelib->type_lengths; + *dup_val_count= 0; for ( ; tmp.count > 1; cur_value++, cur_length++) { @@ -435,6 +437,7 @@ void check_duplicates_in_interval(const char *set_or_name, ER_DUPLICATED_VALUE_IN_TYPE, ER(ER_DUPLICATED_VALUE_IN_TYPE), name,*cur_value,set_or_name); + (*dup_val_count)++; } } } @@ -498,6 +501,7 @@ int prepare_create_field(create_field *sql_field, int *timestamps, int *timestamps_with_niladic, uint table_flags) { + unsigned int dup_val_count; DBUG_ENTER("prepare_field"); /* @@ -573,7 +577,7 @@ int prepare_create_field(create_field *sql_field, sql_field->unireg_check=Field::INTERVAL_FIELD; check_duplicates_in_interval("ENUM",sql_field->field_name, sql_field->interval, - sql_field->charset); + sql_field->charset, &dup_val_count); break; case FIELD_TYPE_SET: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | @@ -583,7 +587,13 @@ int prepare_create_field(create_field *sql_field, sql_field->unireg_check=Field::BIT_FIELD; check_duplicates_in_interval("SET",sql_field->field_name, sql_field->interval, - sql_field->charset); + sql_field->charset, &dup_val_count); + /* Check that count of unique members is not more then 64 */ + if (sql_field->interval->count - dup_val_count > sizeof(longlong)*8) + { + my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name); + DBUG_RETURN(1); + } break; case FIELD_TYPE_DATE: // Rest of string types case FIELD_TYPE_NEWDATE: From 7bf304a6bd85c6fdfdf2c6ff8c4a7a2d0ce3c681 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Apr 2007 18:00:57 +0300 Subject: [PATCH 2/6] Bug #27513: test case added to make sure this crash bug doesn't reappear. mysql-test/r/errors.result: Bug #27513: test case mysql-test/t/errors.test: Bug #27513: test case --- mysql-test/r/errors.result | 18 ++++++++++++++++++ mysql-test/t/errors.test | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index 0c84f24a2e4..0b12853ab80 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -28,3 +28,21 @@ ERROR 42000: Display width out of range for column 'a' (max = 255) set sql_mode='traditional'; create table t1 (a varchar(66000)); ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead +CREATE TABLE t1 (a INT); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +a +Warnings: +Error 1365 Division by 0 +INSERT INTO t1 VALUES(1); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +a +1 +Warnings: +Error 1365 Division by 0 +INSERT INTO t1 VALUES(2),(3); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +a +1 +Warnings: +Error 1365 Division by 0 +DROP TABLE t1; diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index f5647a293e8..6ddef2a8c08 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -41,4 +41,15 @@ set sql_mode='traditional'; --error 1074 create table t1 (a varchar(66000)); +# +# Bug #27513: mysql 5.0.x + NULL pointer DoS +# +CREATE TABLE t1 (a INT); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +INSERT INTO t1 VALUES(1); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +INSERT INTO t1 VALUES(2),(3); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +DROP TABLE t1; + # End of 5.0 tests From 0ee34b1ca25aa757f373857513d51d58fd7aea80 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Apr 2007 14:32:16 -0700 Subject: [PATCH 3/6] Fixed bug #27532: wrong results with ORDER/GROUP BY queries containing IN/BETWEEN predicates in sorting expressions. Wrong results may occur when the select list contains an expression with IN/BETWEEN predicate that differs from a sorting expression by an additional NOT only. Added the method Item_func_opt_neg::eq to compare correctly expressions containing [NOT] IN/BETWEEN. The eq method inherited from the Item_func returns TRUE when comparing 'a IN (1,2)' with 'a NOT IN (1,2)' that is not, of course, correct. mysql-test/r/order_by.result: Added a test case for bug #27532. mysql-test/t/order_by.test: Added a test case for bug #27532. sql/item_cmpfunc.cc: Fixed bug #27532. Added the method Item_func_opt_neg::eq to compare correctly expressions containing [NOT] IN/BETWEEN. The eq method inherited from the Item_func returns TRUE when comparing 'a IN (1,2)' with 'a NOT IN (1,2)' that is not, of course, correct. sql/item_cmpfunc.h: Added the method Item_func_opt_neg::eq to compare correctly expressions containing [NOT] IN/BETWEEN. The eq method inherited from the Item_func returns TRUE when comparing 'a IN (1,2)' with 'a NOT IN (1,2)' that is not, of course, correct. --- mysql-test/r/order_by.result | 59 ++++++++++++++++++++++++++++++++++++ mysql-test/t/order_by.test | 29 ++++++++++++++++++ sql/item_cmpfunc.cc | 20 ++++++++++++ sql/item_cmpfunc.h | 1 + 4 files changed, 109 insertions(+) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index f5601ba0e43..2d6a4a922bc 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -879,3 +879,62 @@ ERROR 23000: Column 'val' in order clause is ambiguous SELECT p.a AS val, q.a AS val FROM t1 p, t1 q ORDER BY val > 1; ERROR 23000: Column 'val' in order clause is ambiguous DROP TABLE t1; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (3), (2), (4), (1); +SELECT a, IF(a IN (2,3), a, a+10) FROM t1 +ORDER BY IF(a IN (2,3), a, a+10); +a IF(a IN (2,3), a, a+10) +2 2 +3 3 +1 11 +4 14 +SELECT a, IF(a NOT IN (2,3), a, a+10) FROM t1 +ORDER BY IF(a NOT IN (2,3), a, a+10); +a IF(a NOT IN (2,3), a, a+10) +1 1 +4 4 +2 12 +3 13 +SELECT a, IF(a IN (2,3), a, a+10) FROM t1 +ORDER BY IF(a NOT IN (2,3), a, a+10); +a IF(a IN (2,3), a, a+10) +1 11 +4 14 +2 2 +3 3 +SELECT a, IF(a BETWEEN 2 AND 3, a, a+10) FROM t1 +ORDER BY IF(a BETWEEN 2 AND 3, a, a+10); +a IF(a BETWEEN 2 AND 3, a, a+10) +2 2 +3 3 +1 11 +4 14 +SELECT a, IF(a NOT BETWEEN 2 AND 3, a, a+10) FROM t1 +ORDER BY IF(a NOT BETWEEN 2 AND 3, a, a+10); +a IF(a NOT BETWEEN 2 AND 3, a, a+10) +1 1 +4 4 +2 12 +3 13 +SELECT a, IF(a BETWEEN 2 AND 3, a, a+10) FROM t1 +ORDER BY IF(a NOT BETWEEN 2 AND 3, a, a+10); +a IF(a BETWEEN 2 AND 3, a, a+10) +1 11 +4 14 +2 2 +3 3 +SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 +FROM t1 GROUP BY x1, x2; +x1 x2 + 3 + 4 +1 +2 +SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 +FROM t1 GROUP BY x1, IF(a NOT IN (1,2), a, ''); +x1 x2 + 3 + 4 +1 +2 +DROP TABLE t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index d781bd6c6ba..af5811fb4a2 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -617,6 +617,35 @@ SELECT p.a AS val, q.a AS val FROM t1 p, t1 q ORDER BY val; --error 1052 SELECT p.a AS val, q.a AS val FROM t1 p, t1 q ORDER BY val > 1; +DROP TABLE t1; + +# +# Bug #27532: ORDER/GROUP BY expressions with IN/BETWEEN and NOT IN/BETWEEN +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (3), (2), (4), (1); + +SELECT a, IF(a IN (2,3), a, a+10) FROM t1 + ORDER BY IF(a IN (2,3), a, a+10); +SELECT a, IF(a NOT IN (2,3), a, a+10) FROM t1 + ORDER BY IF(a NOT IN (2,3), a, a+10); +SELECT a, IF(a IN (2,3), a, a+10) FROM t1 + ORDER BY IF(a NOT IN (2,3), a, a+10); + +SELECT a, IF(a BETWEEN 2 AND 3, a, a+10) FROM t1 + ORDER BY IF(a BETWEEN 2 AND 3, a, a+10); +SELECT a, IF(a NOT BETWEEN 2 AND 3, a, a+10) FROM t1 + ORDER BY IF(a NOT BETWEEN 2 AND 3, a, a+10); +SELECT a, IF(a BETWEEN 2 AND 3, a, a+10) FROM t1 + ORDER BY IF(a NOT BETWEEN 2 AND 3, a, a+10); + +SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 + FROM t1 GROUP BY x1, x2; +SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 + FROM t1 GROUP BY x1, IF(a NOT IN (1,2), a, ''); + + DROP TABLE t1; # End of 4.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index ffb60754381..4d54dfc2b39 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -838,6 +838,26 @@ longlong Item_func_strcmp::val_int() } +bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const +{ + /* Assume we don't have rtti */ + if (this == item) + return 1; + if (item->type() != FUNC_ITEM) + return 0; + Item_func *item_func=(Item_func*) item; + if (arg_count != item_func->arg_count || + functype() != item_func->functype()) + return 0; + if (negated != ((Item_func_opt_neg *) item_func)->negated) + return 0; + for (uint i=0; i < arg_count ; i++) + if (!args[i]->eq(item_func->arguments()[i], binary_cmp)) + return 0; + return 1; +} + + void Item_func_interval::fix_length_and_dec() { if (row->cols() > 8) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index a13be83e093..132e019b4a3 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -405,6 +405,7 @@ public: negated= !negated; return this; } + bool eq(const Item *item, bool binary_cmp) const; }; From da037917b22ad522062ddcb15f96bc6249084fd3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Apr 2007 17:09:41 -0700 Subject: [PATCH 4/6] Fix after manual merge --- mysql-test/r/order_by.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 918a6b2e3d1..5eeb9bd6190 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -963,8 +963,8 @@ x1 x2 3 4 1 -2 -DROP TABLE t1; +2 +DROP TABLE t1; create table t1 (a int not null, b int not null, c int not null); insert t1 values (1,1,1),(1,1,2),(1,2,1); select a, b from t1 group by a, b order by sum(c); From e488e6f23a14490b619d5bbbf2fc4db65dc4b9ef Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Apr 2007 19:45:37 -0700 Subject: [PATCH 5/6] Improved coverage for the code added to fix bug 27532. --- mysql-test/r/order_by.result | 25 +++++++++++++++++++++++++ mysql-test/t/order_by.test | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 2d6a4a922bc..79b163dc1ee 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -937,4 +937,29 @@ x1 x2 4 1 2 +SELECT a, a IN (1,2) FROM t1 ORDER BY a IN (1,2); +a a IN (1,2) +3 0 +4 0 +2 1 +1 1 +SELECT a FROM t1 ORDER BY a IN (1,2); +a +3 +4 +2 +1 +SELECT a+10 FROM t1 ORDER BY a IN (1,2); +a+10 +13 +14 +12 +11 +SELECT a, IF(a IN (1,2), a, a+10) FROM t1 +ORDER BY IF(a IN (3,4), a, a+10); +a IF(a IN (1,2), a, a+10) +3 13 +4 14 +1 1 +2 2 DROP TABLE t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index af5811fb4a2..5c607608462 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -645,6 +645,12 @@ SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 FROM t1 GROUP BY x1, IF(a NOT IN (1,2), a, ''); +# The remaining queries are for better coverage +SELECT a, a IN (1,2) FROM t1 ORDER BY a IN (1,2); +SELECT a FROM t1 ORDER BY a IN (1,2); +SELECT a+10 FROM t1 ORDER BY a IN (1,2); +SELECT a, IF(a IN (1,2), a, a+10) FROM t1 + ORDER BY IF(a IN (3,4), a, a+10); DROP TABLE t1; From dbd125fd909c531b2296a7bd90283d259a62fb59 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Apr 2007 13:38:19 +0300 Subject: [PATCH 6/6] BUG 27513: fixed left-over sql mode from a test case. --- mysql-test/r/errors.result | 7 +------ mysql-test/t/errors.test | 1 + 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index 0b12853ab80..94debb1785f 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -28,21 +28,16 @@ ERROR 42000: Display width out of range for column 'a' (max = 255) set sql_mode='traditional'; create table t1 (a varchar(66000)); ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead +set sql_mode=default; CREATE TABLE t1 (a INT); SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); a -Warnings: -Error 1365 Division by 0 INSERT INTO t1 VALUES(1); SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); a 1 -Warnings: -Error 1365 Division by 0 INSERT INTO t1 VALUES(2),(3); SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); a 1 -Warnings: -Error 1365 Division by 0 DROP TABLE t1; diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index 6ddef2a8c08..4fbdcba635f 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -40,6 +40,7 @@ create table t1 (a int(256)); set sql_mode='traditional'; --error 1074 create table t1 (a varchar(66000)); +set sql_mode=default; # # Bug #27513: mysql 5.0.x + NULL pointer DoS