summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <holyfoot/hf@hfmain.(none)>2007-04-06 12:45:07 +0500
committerunknown <holyfoot/hf@hfmain.(none)>2007-04-06 12:45:07 +0500
commit3bed20c39c63f17debc4234197a6ebc537462e9a (patch)
tree178834696621d65b27803c92e9122967e3b312e5
parenta127d582591c0a8e238e9c6f3fd813c48cc11477 (diff)
parent89aa5548cea2c107049e40ef5e50696ac0194a23 (diff)
downloadmariadb-git-3bed20c39c63f17debc4234197a6ebc537462e9a.tar.gz
Merge mysql.com:/d2/hf/mrg/mysql-5.0-opt
into mysql.com:/d2/hf/mrg/mysql-5.1-opt mysql-test/r/order_by.result: Auto merged mysql-test/r/type_set.result: Auto merged mysql-test/t/order_by.test: Auto merged sql/field.cc: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/sql_select.cc: Auto merged sql/sql_table.cc: Auto merged
-rw-r--r--mysql-test/r/errors.result13
-rw-r--r--mysql-test/r/order_by.result84
-rw-r--r--mysql-test/r/type_set.result19
-rw-r--r--mysql-test/t/errors.test12
-rw-r--r--mysql-test/t/order_by.test36
-rw-r--r--mysql-test/t/type_set.test17
-rw-r--r--sql/field.cc5
-rw-r--r--sql/item_cmpfunc.cc20
-rw-r--r--sql/item_cmpfunc.h1
-rw-r--r--sql/sql_table.cc16
10 files changed, 214 insertions, 9 deletions
diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result
index 0c84f24a2e4..94debb1785f 100644
--- a/mysql-test/r/errors.result
+++ b/mysql-test/r/errors.result
@@ -28,3 +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
+INSERT INTO t1 VALUES(1);
+SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0)));
+a
+1
+INSERT INTO t1 VALUES(2),(3);
+SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0)));
+a
+1
+DROP TABLE t1;
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index c7adfb784de..25fbeadf21b 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -906,6 +906,90 @@ 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
+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;
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);
diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result
index 36022383f1b..a75438293f6 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/errors.test b/mysql-test/t/errors.test
index f5647a293e8..4fbdcba635f 100644
--- a/mysql-test/t/errors.test
+++ b/mysql-test/t/errors.test
@@ -40,5 +40,17 @@ 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
+#
+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
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 5093263b864..c2669856bf4 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -617,7 +617,6 @@ UPDATE bug25126 SET MissingCol = val ORDER BY MissingCol;
UPDATE bug25126 SET MissingCol = MissingCol ORDER BY MissingCol;
DROP TABLE bug25126;
-
#
# Bug #25427: crash when order by expression contains a name
# that cannot be resolved unambiguously
@@ -633,6 +632,41 @@ 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, '');
+
+# 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;
+
+# End of 4.1
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);
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 250a9e3c1b9..d92fb5f949c 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8981,11 +8981,6 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
break;
case MYSQL_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<String> it(*fld_interval_list);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ffa6b4caf2a..36326b46be6 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1127,6 +1127,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()
{
use_decimal_comparison= ((row->element_index(0)->result_type() ==
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index edc905d50ff..d6fc1e3dda0 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -563,6 +563,7 @@ public:
negated= !negated;
return this;
}
+ bool eq(const Item *item, bool binary_cmp) const;
bool subst_argument_checker(byte **arg) { return TRUE; }
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index a753cc9e8e0..06b6dca5feb 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1922,6 +1922,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
@@ -1933,11 +1934,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++)
{
@@ -1950,6 +1952,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)++;
}
}
}
@@ -2013,6 +2016,7 @@ int prepare_create_field(create_field *sql_field,
int *timestamps, int *timestamps_with_niladic,
longlong table_flags)
{
+ unsigned int dup_val_count;
DBUG_ENTER("prepare_field");
/*
@@ -2088,7 +2092,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 MYSQL_TYPE_SET:
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
@@ -2098,7 +2102,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 MYSQL_TYPE_DATE: // Rest of string types
case MYSQL_TYPE_NEWDATE: