Commit 3f355523 authored by unknown's avatar unknown

fix for bug #1790:

"BIT_AND() result in GROUP BY different when SQL_BIG_RESULT used"

return value of BIT_AND changed to BIGINT SIGNED
Also the patch fixes another bug: when temporary table is in use and one of
values in group is NULL, BIT_AND always returns zero.
Fixed it to always skip null values.


mysql-test/r/func_group.result:
  bug #1790: test results fixed
sql/item_sum.cc:
  fix for bug #1790:
  update_field() rewritten to use add() and thus was moved
  to Item_sum_bit::update_field()
  Item_sum_bit::reset_field() was rewritten to take into account
  reset_bits.
sql/item_sum.h:
  fix for bug #1790:
  Item_sum::update_field() and Item_sum::reset_field() commented
  Item_sum_and changed to return BIGINT SIGNED
  Item_sum_and::update_field() and Item_sum_or::update_field)
  were replaced with generic Item_sum_bit::update_field()
parent 24bdf956
...@@ -47,7 +47,7 @@ sum(all a) count(all a) avg(all a) std(all a) bit_or(all a) bit_and(all a) min(a ...@@ -47,7 +47,7 @@ sum(all a) count(all a) avg(all a) std(all a) bit_or(all a) bit_and(all a) min(a
21 6 3.5000 1.7078 7 0 1 6 E 21 6 3.5000 1.7078 7 0 1 6 E
select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp; select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp;
grp sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c) grp sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
NULL NULL 0 NULL NULL 0 0 NULL NULL NULL NULL 0 NULL NULL 0 -1 NULL NULL
1 1 1 1.0000 0.0000 1 1 1 1 a a 1 1 1 1.0000 0.0000 1 1 1 1 a a
2 5 2 2.5000 0.5000 3 2 2 3 b c 2 5 2 2.5000 0.5000 3 2 2 3 b c
3 15 3 5.0000 0.8165 7 4 4 6 C E 3 15 3 5.0000 0.8165 7 4 4 6 C E
...@@ -218,8 +218,8 @@ insert into t1 values (1,null); ...@@ -218,8 +218,8 @@ insert into t1 values (1,null);
insert into t1 values (2,null); insert into t1 values (2,null);
select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
1 0 NULL NULL NULL NULL NULL 0 0 1 0 NULL NULL NULL NULL NULL -1 0
2 0 NULL NULL NULL NULL NULL 0 0 2 0 NULL NULL NULL NULL NULL -1 0
select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
1 0 NULL NULL NULL NULL NULL -1 0 1 0 NULL NULL NULL NULL NULL -1 0
...@@ -227,8 +227,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) ...@@ -227,8 +227,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
insert into t1 values (2,1); insert into t1 values (2,1);
select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
1 0 NULL NULL NULL NULL NULL 0 0 1 0 NULL NULL NULL NULL NULL -1 0
2 1 1 1.0000 0.0000 1 1 0 1 2 1 1 1.0000 0.0000 1 1 1 1
select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
1 0 NULL NULL NULL NULL NULL -1 0 1 0 NULL NULL NULL NULL NULL -1 0
...@@ -236,8 +236,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) ...@@ -236,8 +236,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
insert into t1 values (3,1); insert into t1 values (3,1);
select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
1 0 NULL NULL NULL NULL NULL 0 0 1 0 NULL NULL NULL NULL NULL -1 0
2 1 1 1.0000 0.0000 1 1 0 1 2 1 1 1.0000 0.0000 1 1 1 1
3 1 1 1.0000 0.0000 1 1 1 1 3 1 1 1.0000 0.0000 1 1 1 1
select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
......
...@@ -614,10 +614,19 @@ void Item_sum_avg::reset_field() ...@@ -614,10 +614,19 @@ void Item_sum_avg::reset_field()
} }
void Item_sum_bit::reset_field() void Item_sum_bit::reset_field()
{
char *res= result_field->ptr;
bits= reset_bits;
add();
int8store(res, bits);
}
void Item_sum_bit::update_field()
{ {
char *res=result_field->ptr; char *res=result_field->ptr;
ulonglong nr=(ulonglong) args[0]->val_int(); bits= uint8korr(res);
int8store(res,nr); add();
int8store(res, bits);
} }
/* /*
...@@ -756,28 +765,6 @@ Item_sum_hybrid::min_max_update_int_field() ...@@ -756,28 +765,6 @@ Item_sum_hybrid::min_max_update_int_field()
} }
void Item_sum_or::update_field()
{
ulonglong nr;
char *res=result_field->ptr;
nr=uint8korr(res);
nr|= (ulonglong) args[0]->val_int();
int8store(res,nr);
}
void Item_sum_and::update_field()
{
ulonglong nr;
char *res=result_field->ptr;
nr=uint8korr(res);
nr&= (ulonglong) args[0]->val_int();
int8store(res,nr);
}
Item_avg_field::Item_avg_field(Item_sum_avg *item) Item_avg_field::Item_avg_field(Item_sum_avg *item)
{ {
name=item->name; name=item->name;
...@@ -787,6 +774,7 @@ Item_avg_field::Item_avg_field(Item_sum_avg *item) ...@@ -787,6 +774,7 @@ Item_avg_field::Item_avg_field(Item_sum_avg *item)
maybe_null=1; maybe_null=1;
} }
double Item_avg_field::val() double Item_avg_field::val()
{ {
double nr; double nr;
......
...@@ -55,7 +55,18 @@ public: ...@@ -55,7 +55,18 @@ public:
virtual enum Sumfunctype sum_func () const=0; virtual enum Sumfunctype sum_func () const=0;
virtual void reset()=0; virtual void reset()=0;
virtual bool add()=0; virtual bool add()=0;
/*
Called when new group is started and results are being saved in
a temporary table. Similar to reset(), but must also store value in
result_field. Like reset() it is supposed to reset start value to
default.
*/
virtual void reset_field()=0; virtual void reset_field()=0;
/*
Called for each new value in the group, when temporary table is in use.
Similar to add(), but uses temporary table field to obtain current value,
Updated value is then saved in the field.
*/
virtual void update_field()=0; virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; } virtual bool keep_field_type(void) const { return 0; }
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
...@@ -360,20 +371,20 @@ class Item_sum_bit :public Item_sum_int ...@@ -360,20 +371,20 @@ class Item_sum_bit :public Item_sum_int
void reset(); void reset();
longlong val_int(); longlong val_int();
void reset_field(); void reset_field();
void update_field();
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
void fix_length_and_dec()
{ decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; }
}; };
class Item_sum_or :public Item_sum_bit class Item_sum_or :public Item_sum_bit
{ {
public: public:
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
bool add(); bool add();
void update_field();
const char *func_name() const { return "bit_or"; } const char *func_name() const { return "bit_or"; }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
void fix_length_and_dec()
{ decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; }
}; };
...@@ -382,9 +393,10 @@ class Item_sum_and :public Item_sum_bit ...@@ -382,9 +393,10 @@ class Item_sum_and :public Item_sum_bit
public: public:
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {} Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
bool add(); bool add();
void update_field();
const char *func_name() const { return "bit_and"; } const char *func_name() const { return "bit_and"; }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
void fix_length_and_dec()
{ decimals=0; max_length=21; unsigned_flag=0; maybe_null=null_value=0; }
}; };
/* /*
......
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