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
|
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);
|
|||||||
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)
|
|||||||
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)
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
|
|
||||||
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()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
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:
|
|||||||
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
|
|||||||
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
|
|||||||
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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user