Commit 03acb815 authored by sergefp@mysql.com's avatar sergefp@mysql.com

Merged (will need a post-merge fix)

parents 4864dce0 9ed8cd70
...@@ -638,3 +638,15 @@ alias ...@@ -638,3 +638,15 @@ alias
1,2 1,2
1 1
drop table t1; 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;
...@@ -465,3 +465,12 @@ select group_concat( distinct col1 ) as alias from t1 ...@@ -465,3 +465,12 @@ select group_concat( distinct col1 ) as alias from t1
drop table t1; 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;
...@@ -1488,14 +1488,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -1488,14 +1488,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
"forward reference in item list"); "forward reference in item list");
return -1; return -1;
} }
Item_ref *rf= (place == IN_HAVING ? Item_ref *rf= (place == IN_HAVING ?
new Item_ref(last->ref_pointer_array + counter, new Item_ref(last->ref_pointer_array + counter,
(char *)table_name, (char *)table_name,
(char *)field_name) : (char *)field_name, this) :
new Item_direct_ref(last->ref_pointer_array + counter, new Item_direct_ref(last->ref_pointer_array + counter,
(char *)table_name, (char *)table_name,
(char *)field_name)); (char *)field_name, this));
if (!rf) if (!rf)
return 1; return 1;
thd->change_item_tree(ref, rf); thd->change_item_tree(ref, rf);
......
...@@ -835,6 +835,26 @@ public: ...@@ -835,6 +835,26 @@ public:
:Item_ident(db_par, table_name_par, field_name_par), ref(0) {} :Item_ident(db_par, table_name_par, field_name_par), ref(0) {}
Item_ref(Item **item, const char *table_name_par, const char *field_name_par) Item_ref(Item **item, const char *table_name_par, const 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 constructor is used when processing GROUP BY and referred Item is
available. We set all properties here because fix_fields() will not be
called for the created Item_ref. (see BUG#6976)
TODO check if we could get rid of *_name_par parameters and if we need to
perform similar initialization for other ctors.
TODO we probably fix a superset of problems like in BUG#6658. Check this
with Bar, and if we have a more broader set of problems like this.
*/
Item_ref(Item **item, const char *table_name_par,
const char *field_name_par, Item *src)
: Item_ident(NullS, table_name_par, field_name_par), ref(item)
{
collation.set(src->collation);
max_length= src->max_length;
decimals= src->decimals;
with_sum_func= src->with_sum_func;
maybe_null= src->maybe_null;
}
/* Constructor need to process subselect with temporary tables (see Item) */ /* Constructor need to process subselect with temporary tables (see Item) */
Item_ref(THD *thd, Item_ref *item) :Item_ident(thd, item), ref(item->ref) {} Item_ref(THD *thd, Item_ref *item) :Item_ident(thd, item), ref(item->ref) {}
enum Type type() const { return REF_ITEM; } enum Type type() const { return REF_ITEM; }
...@@ -933,6 +953,7 @@ public: ...@@ -933,6 +953,7 @@ public:
class Item_in_subselect; class Item_in_subselect;
class Item_ref_null_helper: public Item_ref class Item_ref_null_helper: public Item_ref
{ {
protected: protected:
......
...@@ -2022,7 +2022,8 @@ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array, ...@@ -2022,7 +2022,8 @@ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
{ {
Item **ref= li.ref(); Item **ref= li.ref();
uint el= fields.elements; uint el= fields.elements;
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name); Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name,
item);
fields.push_front(item); fields.push_front(item);
ref_pointer_array[el]= item; ref_pointer_array[el]= item;
thd->change_item_tree(ref, new_item); thd->change_item_tree(ref, new_item);
......
...@@ -349,7 +349,7 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array, ...@@ -349,7 +349,7 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
else if (item->used_tables() || item->type() == SUM_FUNC_ITEM) else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
{ {
uint el= fields.elements; uint el= fields.elements;
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name); Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name, item);
new_item->collation.set(item->collation); new_item->collation.set(item->collation);
fields.push_front(item); fields.push_front(item);
ref_pointer_array[el]= item; ref_pointer_array[el]= item;
......
...@@ -95,7 +95,8 @@ void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array, ...@@ -95,7 +95,8 @@ void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array,
else if ((*arg)->used_tables() || (*arg)->type() == SUM_FUNC_ITEM) else if ((*arg)->used_tables() || (*arg)->type() == SUM_FUNC_ITEM)
{ {
uint el= fields.elements; uint el= fields.elements;
Item *new_item= new Item_ref(ref_pointer_array + el, 0, (*arg)->name); Item *new_item= new Item_ref(ref_pointer_array + el, 0, (*arg)->name,
*arg);
fields.push_front(*arg); fields.push_front(*arg);
ref_pointer_array[el]= *arg; ref_pointer_array[el]= *arg;
thd->change_item_tree(arg, new_item); thd->change_item_tree(arg, new_item);
......
...@@ -1748,7 +1748,7 @@ void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array, ...@@ -1748,7 +1748,7 @@ void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
else if (item->used_tables() || item->type() == SUM_FUNC_ITEM) else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
{ {
uint el= fields.elements; uint el= fields.elements;
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name); Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name,item);
fields.push_front(item); fields.push_front(item);
ref_pointer_array[el]= item; ref_pointer_array[el]= item;
thd->change_item_tree(&item, new_item); thd->change_item_tree(&item, new_item);
......
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