mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -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
|
||||
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)
|
||||
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
|
||||
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
|
||||
@ -218,8 +218,8 @@ insert into t1 values (1,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;
|
||||
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
|
||||
2 0 NULL NULL NULL NULL NULL 0 0
|
||||
1 0 NULL NULL NULL NULL NULL -1 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;
|
||||
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
|
||||
@ -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);
|
||||
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)
|
||||
1 0 NULL NULL NULL NULL NULL 0 0
|
||||
2 1 1 1.0000 0.0000 1 1 0 1
|
||||
1 0 NULL NULL NULL NULL NULL -1 0
|
||||
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;
|
||||
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
|
||||
@ -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);
|
||||
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)
|
||||
1 0 NULL NULL NULL NULL NULL 0 0
|
||||
2 1 1 1.0000 0.0000 1 1 0 1
|
||||
1 0 NULL NULL NULL NULL NULL -1 0
|
||||
2 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;
|
||||
a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
|
||||
|
@ -616,8 +616,17 @@ void Item_sum_avg::reset_field()
|
||||
void Item_sum_bit::reset_field()
|
||||
{
|
||||
char *res= result_field->ptr;
|
||||
ulonglong nr=(ulonglong) args[0]->val_int();
|
||||
int8store(res,nr);
|
||||
bits= reset_bits;
|
||||
add();
|
||||
int8store(res, bits);
|
||||
}
|
||||
|
||||
void Item_sum_bit::update_field()
|
||||
{
|
||||
char *res=result_field->ptr;
|
||||
bits= uint8korr(res);
|
||||
add();
|
||||
int8store(res, bits);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -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)
|
||||
{
|
||||
name=item->name;
|
||||
@ -787,6 +774,7 @@ Item_avg_field::Item_avg_field(Item_sum_avg *item)
|
||||
maybe_null=1;
|
||||
}
|
||||
|
||||
|
||||
double Item_avg_field::val()
|
||||
{
|
||||
double nr;
|
||||
|
@ -55,7 +55,18 @@ public:
|
||||
virtual enum Sumfunctype sum_func () const=0;
|
||||
virtual void reset()=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;
|
||||
/*
|
||||
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 bool keep_field_type(void) const { return 0; }
|
||||
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
|
||||
@ -360,9 +371,8 @@ class Item_sum_bit :public Item_sum_int
|
||||
void reset();
|
||||
longlong val_int();
|
||||
void reset_field();
|
||||
void update_field();
|
||||
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; }
|
||||
};
|
||||
|
||||
|
||||
@ -371,9 +381,10 @@ class Item_sum_or :public Item_sum_bit
|
||||
public:
|
||||
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
|
||||
bool add();
|
||||
void update_field();
|
||||
const char *func_name() const { return "bit_or"; }
|
||||
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
|
||||
public:
|
||||
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
|
||||
bool add();
|
||||
void update_field();
|
||||
const char *func_name() const { return "bit_and"; }
|
||||
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; }
|
||||
};
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user