Commit c3449136 authored by Georgi Kodinov's avatar Georgi Kodinov

merged 5.0-bugteam -> 5.1-bugteam

parents 0d1a56de 7fc82862
...@@ -424,3 +424,10 @@ select f1 from t1 group by f1 having max(f1)=f1; ...@@ -424,3 +424,10 @@ select f1 from t1 group by f1 having max(f1)=f1;
f1 f1
set session sql_mode=''; set session sql_mode='';
drop table t1; drop table t1;
CREATE TABLE t1 ( a INT, b INT);
INSERT INTO t1 VALUES (1, 1), (2,2), (3, NULL);
SELECT b, COUNT(DISTINCT a) FROM t1 GROUP BY b HAVING b is NULL;
b COUNT(DISTINCT a)
NULL 1
DROP TABLE t1;
End of 5.0 tests
...@@ -432,3 +432,14 @@ select f1 from t1 having max(f1)=f1; ...@@ -432,3 +432,14 @@ select f1 from t1 having max(f1)=f1;
select f1 from t1 group by f1 having max(f1)=f1; select f1 from t1 group by f1 having max(f1)=f1;
set session sql_mode=''; set session sql_mode='';
drop table t1; drop table t1;
#
# Bug #38637: COUNT DISTINCT prevents NULL testing in HAVING clause
#
CREATE TABLE t1 ( a INT, b INT);
INSERT INTO t1 VALUES (1, 1), (2,2), (3, NULL);
SELECT b, COUNT(DISTINCT a) FROM t1 GROUP BY b HAVING b is NULL;
DROP TABLE t1;
--echo End of 5.0 tests
...@@ -2090,6 +2090,12 @@ bool Item_field::val_bool_result() ...@@ -2090,6 +2090,12 @@ bool Item_field::val_bool_result()
} }
bool Item_field::is_null_result()
{
return (null_value=result_field->is_null());
}
bool Item_field::eq(const Item *item, bool binary_cmp) const bool Item_field::eq(const Item *item, bool binary_cmp) const
{ {
Item *real_item= ((Item *) item)->real_item(); Item *real_item= ((Item *) item)->real_item();
...@@ -5800,6 +5806,15 @@ double Item_ref::val_result() ...@@ -5800,6 +5806,15 @@ double Item_ref::val_result()
} }
bool Item_ref::is_null_result()
{
if (result_field)
return (null_value=result_field->is_null());
return is_null();
}
longlong Item_ref::val_int_result() longlong Item_ref::val_int_result()
{ {
if (result_field) if (result_field)
...@@ -5905,7 +5920,9 @@ String *Item_ref::val_str(String* tmp) ...@@ -5905,7 +5920,9 @@ String *Item_ref::val_str(String* tmp)
bool Item_ref::is_null() bool Item_ref::is_null()
{ {
DBUG_ASSERT(fixed); DBUG_ASSERT(fixed);
return (*ref)->is_null(); bool tmp=(*ref)->is_null_result();
null_value=(*ref)->null_value;
return tmp;
} }
......
...@@ -729,6 +729,7 @@ public: ...@@ -729,6 +729,7 @@ public:
virtual my_decimal *val_decimal_result(my_decimal *val) virtual my_decimal *val_decimal_result(my_decimal *val)
{ return val_decimal(val); } { return val_decimal(val); }
virtual bool val_bool_result() { return val_bool(); } virtual bool val_bool_result() { return val_bool(); }
virtual bool is_null_result() { return is_null(); }
/* bit map of tables used by item */ /* bit map of tables used by item */
virtual table_map used_tables() const { return (table_map) 0L; } virtual table_map used_tables() const { return (table_map) 0L; }
...@@ -1436,6 +1437,7 @@ public: ...@@ -1436,6 +1437,7 @@ public:
String *str_result(String* tmp); String *str_result(String* tmp);
my_decimal *val_decimal_result(my_decimal *); my_decimal *val_decimal_result(my_decimal *);
bool val_bool_result(); bool val_bool_result();
bool is_null_result();
bool send(Protocol *protocol, String *str_arg); bool send(Protocol *protocol, String *str_arg);
void reset_field(Field *f); void reset_field(Field *f);
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
...@@ -2178,6 +2180,7 @@ public: ...@@ -2178,6 +2180,7 @@ public:
String *str_result(String* tmp); String *str_result(String* tmp);
my_decimal *val_decimal_result(my_decimal *); my_decimal *val_decimal_result(my_decimal *);
bool val_bool_result(); bool val_bool_result();
bool is_null_result();
bool send(Protocol *prot, String *tmp); bool send(Protocol *prot, String *tmp);
void make_field(Send_field *field); void make_field(Send_field *field);
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
......
...@@ -4307,6 +4307,15 @@ my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val) ...@@ -4307,6 +4307,15 @@ my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
} }
bool Item_func_set_user_var::is_null_result()
{
DBUG_ASSERT(fixed == 1);
check(TRUE);
update(); // Store expression
return is_null();
}
void Item_func_set_user_var::print(String *str, enum_query_type query_type) void Item_func_set_user_var::print(String *str, enum_query_type query_type)
{ {
str->append(STRING_WITH_LEN("(@")); str->append(STRING_WITH_LEN("(@"));
......
...@@ -1335,6 +1335,7 @@ public: ...@@ -1335,6 +1335,7 @@ public:
longlong val_int_result(); longlong val_int_result();
String *str_result(String *str); String *str_result(String *str);
my_decimal *val_decimal_result(my_decimal *); my_decimal *val_decimal_result(my_decimal *);
bool is_null_result();
bool update_hash(void *ptr, uint length, enum Item_result type, bool update_hash(void *ptr, uint length, enum Item_result type,
CHARSET_INFO *cs, Derivation dv, bool unsigned_arg); CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
bool send(Protocol *protocol, String *str_arg); bool send(Protocol *protocol, String *str_arg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment