From f78a60593a8fc2d2a99f1146ce3ec95d4208bd14 Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Sat, 11 Dec 2004 19:59:09 +0300 Subject: Fix for BUG#6976: In Item_ref::Item_ref set maybe_null (and other fields fix_fields sets) to be the same as in (*ref), because Item_ref::fix_fields() will not be called. Previously maybe_null was 0 always and this produced a bogus state where maybe_null==0 && is_null() == true which broke evaluation for some upper-level Items, like AND and OR. --- mysql-test/r/group_by.result | 12 ++++++++++++ mysql-test/t/group_by.test | 9 +++++++++ sql/item.cc | 1 + sql/item.h | 14 +++++++++++++- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index dba95614052..f636692c0d9 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -626,3 +626,15 @@ explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 6 Using filesort DROP TABLE t1; +create table t1 (a int); +insert into t1 values(null); +select min(a) is null from t1; +min(a) is null +1 +select min(a) is null or null from t1; +min(a) is null or null +1 +select 1 and min(a) is null from t1; +1 and min(a) is null +1 +drop table t1; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 58bb4b3e268..5af78b924f8 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -447,3 +447,12 @@ INSERT INTO t1 VALUES (1,2),(2,3),(4,5),(3,5),(1,5),(23,5); SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; DROP TABLE t1; + +#Test for BUG#6976: Aggregate functions have incorrect NULL-ness +create table t1 (a int); +insert into t1 values(null); +select min(a) is null from t1; +select min(a) is null or null from t1; +select 1 and min(a) is null from t1; +drop table t1; + diff --git a/sql/item.cc b/sql/item.cc index 739b5385b55..8737cc06bbd 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -687,6 +687,7 @@ bool Item_null::send(THD *thd, String *packet) /* This is used for HAVING clause Find field in select list having the same name + This is not always called, see also Item_ref::Item_ref */ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables) diff --git a/sql/item.h b/sql/item.h index f6f9e1c0621..cc6a846d6c1 100644 --- a/sql/item.h +++ b/sql/item.h @@ -401,7 +401,19 @@ public: Item_ref(char *db_par,char *table_name_par,char *field_name_par) :Item_ident(db_par,table_name_par,field_name_par),ref(0) {} Item_ref(Item **item, char *table_name_par,char *field_name_par) - :Item_ident(NullS,table_name_par,field_name_par),ref(item) {} + :Item_ident(NullS,table_name_par,field_name_par),ref(item) + { + /* + This ctor is called from Item_XXX::split_sum_func, and fix_fields will + not be called for *this, so we must setup everything here. **ref is + already fixed at this point. + */ + max_length= (*ref)->max_length; + decimals= (*ref)->decimals; + binary= (*ref)->binary; + with_sum_func= (*ref)->with_sum_func; + maybe_null= (*ref)->maybe_null; + } enum Type type() const { return REF_ITEM; } bool eq(const Item *item, bool binary_cmp) const { return (*ref)->eq(item, binary_cmp); } -- cgit v1.2.1