From 108a0a1823db2036000b309e7d6bd3216742c4de Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Mar 2013 21:10:58 +0200 Subject: [PATCH 1/3] MDEV-4241 fix. Field_enum incorrectly inherited decimals() from Field_string. Field_enum should be always integer in numeric context. --- mysql-test/r/type_enum.result | 15 +++++++++++++++ mysql-test/t/type_enum.test | 15 +++++++++++++++ sql/field.h | 1 + strings/decimal.c | 4 +++- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index 813f912c5af..390f969f313 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -1854,3 +1854,18 @@ a DROP TABLE t1; End of 5.1 tests +# +# MDEV-4241: Assertion failure: scale >= 0 && precision > 0 && +# scale <= precision in decimal_bin_size +# +CREATE TABLE t1 ( +f1 enum('1','2','3','4','5') +) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +SELECT AVG(f1) FROM t1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def AVG(f1) 246 7 6 Y 128 4 63 +AVG(f1) +1.5000 +drop table t1; +End of 5.3 tests diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test index 2043342e2c8..5b0b70631a5 100644 --- a/mysql-test/t/type_enum.test +++ b/mysql-test/t/type_enum.test @@ -221,3 +221,18 @@ SELECT a FROM t1 WHERE a=0; DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # MDEV-4241: Assertion failure: scale >= 0 && precision > 0 && +--echo # scale <= precision in decimal_bin_size +--echo # +CREATE TABLE t1 ( + f1 enum('1','2','3','4','5') +) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +--enable_metadata +SELECT AVG(f1) FROM t1; +--disable_metadata +drop table t1; + +--echo End of 5.3 tests diff --git a/sql/field.h b/sql/field.h index 115a9519b7b..665b784d820 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1982,6 +1982,7 @@ public: bool has_charset(void) const { return TRUE; } /* enum and set are sorted as integers */ CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } + uint decimals() const { return 0; } private: int do_save_field_metadata(uchar *first_byte); uint is_equal(Create_field *new_field); diff --git a/strings/decimal.c b/strings/decimal.c index e4925ff5f7c..3aced9b2572 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1465,7 +1465,9 @@ int decimal_bin_size(int precision, int scale) intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1, intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1; - DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision); + DBUG_ASSERT(scale >= 0); + DBUG_ASSERT(precision > 0); + DBUG_ASSERT(scale <= precision); return intg0*sizeof(dec1)+dig2bytes[intg0x]+ frac0*sizeof(dec1)+dig2bytes[frac0x]; } From 888db0ec09c5f54b69feda2defd2e9ae49fab75c Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 6 Mar 2013 22:22:24 +0100 Subject: [PATCH 2/3] Fix typo (clang issued warning that =+ was used where += was intended) --- sql/sql_join_cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 1121c591c3b..6ffd0f20b5e 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -774,7 +774,7 @@ ulong JOIN_CACHE::get_min_join_buffer_size() tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS)) { len+= tab->get_max_used_fieldlength(); - len_last=+ tab->get_used_fieldlength(); + len_last+= tab->get_used_fieldlength(); } size_t len_addon= get_record_max_affix_length() + get_max_key_addon_space_per_record(); From 926b0f54c9b0f261460e886969dde9bbf1916852 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 8 Mar 2013 00:25:26 -0800 Subject: [PATCH 3/3] Fixed bug mdev-4250. This is a bug in the legacy code. It did not manifest itself because it was masked by other bugs that were fixed by the patches for mdev-4172 and mdev-4177. --- mysql-test/r/select.result | 20 ++++++++++++++++++++ mysql-test/r/select_jcl6.result | 20 ++++++++++++++++++++ mysql-test/r/select_pkeycache.result | 20 ++++++++++++++++++++ mysql-test/t/select.test | 19 +++++++++++++++++++ sql/item_cmpfunc.h | 9 +++++++++ sql/sql_select.cc | 7 +++++-- 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 5a234c17409..3d1dc5ec170 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -5112,4 +5112,24 @@ INSERT INTO t2 VALUES (3),(4); SELECT * FROM t1, t2 WHERE a=3 AND a=b; a b drop table t1,t2; +# +# Bug mdev-4250: wrong transformation of WHERE condition with OR +# +CREATE TABLE t1 (pk int PRIMARY KEY, a int); +INSERT INTO t1 VALUES (3,0), (2,0), (4,1), (5,0), (1,0); +SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; +pk a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0)) +DROP TABLE t1; +SELECT * FROM mysql.time_zone +WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) +AND Time_zone_id = Time_zone_id +OR Time_zone_id <> Time_zone_id ) +AND Use_leap_seconds <> 'N'; +Time_zone_id Use_leap_seconds End of 5.3 tests diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result index b7f278a327f..e2e0db128b3 100644 --- a/mysql-test/r/select_jcl6.result +++ b/mysql-test/r/select_jcl6.result @@ -5123,6 +5123,26 @@ INSERT INTO t2 VALUES (3),(4); SELECT * FROM t1, t2 WHERE a=3 AND a=b; a b drop table t1,t2; +# +# Bug mdev-4250: wrong transformation of WHERE condition with OR +# +CREATE TABLE t1 (pk int PRIMARY KEY, a int); +INSERT INTO t1 VALUES (3,0), (2,0), (4,1), (5,0), (1,0); +SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; +pk a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0)) +DROP TABLE t1; +SELECT * FROM mysql.time_zone +WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) +AND Time_zone_id = Time_zone_id +OR Time_zone_id <> Time_zone_id ) +AND Use_leap_seconds <> 'N'; +Time_zone_id Use_leap_seconds End of 5.3 tests set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index 5a234c17409..3d1dc5ec170 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -5112,4 +5112,24 @@ INSERT INTO t2 VALUES (3),(4); SELECT * FROM t1, t2 WHERE a=3 AND a=b; a b drop table t1,t2; +# +# Bug mdev-4250: wrong transformation of WHERE condition with OR +# +CREATE TABLE t1 (pk int PRIMARY KEY, a int); +INSERT INTO t1 VALUES (3,0), (2,0), (4,1), (5,0), (1,0); +SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; +pk a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0)) +DROP TABLE t1; +SELECT * FROM mysql.time_zone +WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) +AND Time_zone_id = Time_zone_id +OR Time_zone_id <> Time_zone_id ) +AND Use_leap_seconds <> 'N'; +Time_zone_id Use_leap_seconds End of 5.3 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 890da70caad..e202e013377 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -4286,4 +4286,23 @@ INSERT INTO t2 VALUES (3),(4); SELECT * FROM t1, t2 WHERE a=3 AND a=b; drop table t1,t2; +--echo # +--echo # Bug mdev-4250: wrong transformation of WHERE condition with OR +--echo # + +CREATE TABLE t1 (pk int PRIMARY KEY, a int); +INSERT INTO t1 VALUES (3,0), (2,0), (4,1), (5,0), (1,0); + +SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; + +DROP TABLE t1; + +SELECT * FROM mysql.time_zone +WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) + AND Time_zone_id = Time_zone_id + OR Time_zone_id <> Time_zone_id ) + AND Use_leap_seconds <> 'N'; + --echo End of 5.3 tests diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 33f147b7b0f..1b8687cfcfc 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1798,6 +1798,15 @@ public: { upper_levels= 0; } + void copy(COND_EQUAL &cond_equal) + { + max_members= cond_equal.max_members; + upper_levels= cond_equal.upper_levels; + if (cond_equal.current_level.is_empty()) + current_level.empty(); + else + current_level= cond_equal.current_level; + } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 75f810598cd..24b0cb952a1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11383,7 +11383,9 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, item_equal->n_field_items()); } - ((Item_cond_and*)cond)->cond_equal= cond_equal; + ((Item_cond_and*)cond)->cond_equal.copy(cond_equal); + cond_equal.current_level= + ((Item_cond_and*)cond)->cond_equal.current_level; inherited= &(((Item_cond_and*)cond)->cond_equal); } /* @@ -11461,7 +11463,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, set_if_bigger(thd->lex->current_select->max_equal_elems, item_equal->n_field_items()); } - and_cond->cond_equal= cond_equal; + and_cond->cond_equal.copy(cond_equal); + cond_equal.current_level= and_cond->cond_equal.current_level; args->concat((List *)&cond_equal.current_level); return and_cond;