mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Bug #57954: BIT_AND function returns incorrect results
when semijoin=on When setting the aggregate function as having no rows to report the function no_rows_in_result() was calling Item_sum::reset(). However this function in addition to cleaning up the aggregate value by calling aggregator_clear() was also adding the current value to the aggregate value by calling aggregator_add(). Fixed by making no_rows_in_result() to call aggregator_clear() directly. Renamed Item_sum::reset to Item_sum::reset_and_add() to and added a comment to avoid misinterpretation of what the function does.
This commit is contained in:
@ -145,3 +145,50 @@ select count(*), min(7), max(7) from t2m, t1i;
|
|||||||
count(*) min(7) max(7)
|
count(*) min(7) max(7)
|
||||||
0 NULL NULL
|
0 NULL NULL
|
||||||
drop table t1m, t1i, t2m, t2i;
|
drop table t1m, t1i, t2m, t2i;
|
||||||
|
#
|
||||||
|
# Bug #57954: BIT_AND function returns incorrect results when
|
||||||
|
# semijoin=on
|
||||||
|
CREATE TABLE c (
|
||||||
|
pk INT,
|
||||||
|
col_varchar_key VARCHAR(1),
|
||||||
|
PRIMARY KEY (pk),
|
||||||
|
KEY col_varchar_key (col_varchar_key)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
INSERT INTO c VALUES (11,NULL);
|
||||||
|
INSERT INTO c VALUES (16,'c');
|
||||||
|
CREATE TABLE bb (
|
||||||
|
pk INT,
|
||||||
|
col_varchar_key VARCHAR(1),
|
||||||
|
PRIMARY KEY (pk),
|
||||||
|
KEY col_varchar_key (col_varchar_key)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
INSERT INTO bb VALUES (10,NULL);
|
||||||
|
SELECT straight_join BIT_AND(c.pk)
|
||||||
|
FROM
|
||||||
|
bb, c
|
||||||
|
WHERE c.col_varchar_key='ABC'
|
||||||
|
ORDER BY c.pk;
|
||||||
|
BIT_AND(c.pk)
|
||||||
|
18446744073709551615
|
||||||
|
DROP TABLE c,bb;
|
||||||
|
#
|
||||||
|
# Bug #58050: BIT_OR and BIT_XOR return incorrect results when
|
||||||
|
# semijoin=on
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (pk INT PRIMARY KEY, b INT, c INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES(1, 1, 1);
|
||||||
|
CREATE TABLE t2 (pk INT PRIMARY KEY, b INT, c INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t2 VALUES (1, 1, NULL);
|
||||||
|
SELECT t1.* FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1;
|
||||||
|
pk b c
|
||||||
|
SELECT BIT_OR(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1;
|
||||||
|
BIT_OR(t1.b)
|
||||||
|
0
|
||||||
|
SELECT BIT_AND(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1;
|
||||||
|
BIT_AND(t1.b)
|
||||||
|
18446744073709551615
|
||||||
|
SELECT BIT_XOR(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1;
|
||||||
|
BIT_XOR(t1.b)
|
||||||
|
0
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
End of 5.5 tests
|
||||||
|
@ -83,3 +83,53 @@ explain select count(*), min(7), max(7) from t2m, t1i;
|
|||||||
select count(*), min(7), max(7) from t2m, t1i;
|
select count(*), min(7), max(7) from t2m, t1i;
|
||||||
|
|
||||||
drop table t1m, t1i, t2m, t2i;
|
drop table t1m, t1i, t2m, t2i;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #57954: BIT_AND function returns incorrect results when
|
||||||
|
--echo # semijoin=on
|
||||||
|
|
||||||
|
CREATE TABLE c (
|
||||||
|
pk INT,
|
||||||
|
col_varchar_key VARCHAR(1),
|
||||||
|
PRIMARY KEY (pk),
|
||||||
|
KEY col_varchar_key (col_varchar_key)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
INSERT INTO c VALUES (11,NULL);
|
||||||
|
INSERT INTO c VALUES (16,'c');
|
||||||
|
CREATE TABLE bb (
|
||||||
|
pk INT,
|
||||||
|
col_varchar_key VARCHAR(1),
|
||||||
|
PRIMARY KEY (pk),
|
||||||
|
KEY col_varchar_key (col_varchar_key)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
INSERT INTO bb VALUES (10,NULL);
|
||||||
|
|
||||||
|
SELECT straight_join BIT_AND(c.pk)
|
||||||
|
FROM
|
||||||
|
bb, c
|
||||||
|
WHERE c.col_varchar_key='ABC'
|
||||||
|
ORDER BY c.pk;
|
||||||
|
|
||||||
|
DROP TABLE c,bb;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #58050: BIT_OR and BIT_XOR return incorrect results when
|
||||||
|
--echo # semijoin=on
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (pk INT PRIMARY KEY, b INT, c INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES(1, 1, 1);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (pk INT PRIMARY KEY, b INT, c INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t2 VALUES (1, 1, NULL);
|
||||||
|
|
||||||
|
SELECT t1.* FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1;
|
||||||
|
SELECT BIT_OR(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1;
|
||||||
|
SELECT BIT_AND(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1;
|
||||||
|
SELECT BIT_XOR(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
|
--echo End of 5.5 tests
|
||||||
|
@ -2235,7 +2235,7 @@ void Item_sum_avg::reset_field()
|
|||||||
|
|
||||||
void Item_sum_bit::reset_field()
|
void Item_sum_bit::reset_field()
|
||||||
{
|
{
|
||||||
reset();
|
reset_and_add();
|
||||||
int8store(result_field->ptr, bits);
|
int8store(result_field->ptr, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,14 +406,22 @@ public:
|
|||||||
Item_sum(THD *thd, Item_sum *item);
|
Item_sum(THD *thd, Item_sum *item);
|
||||||
enum Type type() const { return SUM_FUNC_ITEM; }
|
enum Type type() const { return SUM_FUNC_ITEM; }
|
||||||
virtual enum Sumfunctype sum_func () const=0;
|
virtual enum Sumfunctype sum_func () const=0;
|
||||||
inline bool reset() { aggregator_clear(); return aggregator_add(); };
|
/**
|
||||||
|
Resets the aggregate value to its default and aggregates the current
|
||||||
|
value of its attribute(s).
|
||||||
|
*/
|
||||||
|
inline bool reset_and_add()
|
||||||
|
{
|
||||||
|
aggregator_clear();
|
||||||
|
return aggregator_add();
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Called when new group is started and results are being saved in
|
Called when new group is started and results are being saved in
|
||||||
a temporary table. Similar to reset(), but must also store value in
|
a temporary table. Similarly to reset_and_add() it resets the
|
||||||
result_field. Like reset() it is supposed to reset start value to
|
value to its default and aggregates the value of its
|
||||||
default.
|
attribute(s), but must also store it in result_field.
|
||||||
This set of methods (reult_field(), reset_field, update_field()) of
|
This set of methods (result_item(), reset_field, update_field()) of
|
||||||
Item_sum is used only if quick_group is not null. Otherwise
|
Item_sum is used only if quick_group is not null. Otherwise
|
||||||
copy_or_same() is used to obtain a copy of this item.
|
copy_or_same() is used to obtain a copy of this item.
|
||||||
*/
|
*/
|
||||||
@ -456,7 +464,7 @@ public:
|
|||||||
set_aggregator(with_distinct ?
|
set_aggregator(with_distinct ?
|
||||||
Aggregator::DISTINCT_AGGREGATOR :
|
Aggregator::DISTINCT_AGGREGATOR :
|
||||||
Aggregator::SIMPLE_AGGREGATOR);
|
Aggregator::SIMPLE_AGGREGATOR);
|
||||||
reset();
|
aggregator_clear();
|
||||||
}
|
}
|
||||||
virtual void make_unique() { force_copy_fields= TRUE; }
|
virtual void make_unique() { force_copy_fields= TRUE; }
|
||||||
Item *get_tmp_table_item(THD *thd);
|
Item *get_tmp_table_item(THD *thd);
|
||||||
|
@ -11391,7 +11391,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
|
|||||||
|
|
||||||
min_functions_it->rewind();
|
min_functions_it->rewind();
|
||||||
while ((min_func= (*min_functions_it)++))
|
while ((min_func= (*min_functions_it)++))
|
||||||
min_func->reset();
|
min_func->reset_and_add();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -11423,7 +11423,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
|
|||||||
|
|
||||||
max_functions_it->rewind();
|
max_functions_it->rewind();
|
||||||
while ((max_func= (*max_functions_it)++))
|
while ((max_func= (*max_functions_it)++))
|
||||||
max_func->reset();
|
max_func->reset_and_add();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -424,7 +424,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
|||||||
item_sum->aggregator_clear();
|
item_sum->aggregator_clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
item_sum->reset();
|
item_sum->reset_and_add();
|
||||||
item_sum->make_const();
|
item_sum->make_const();
|
||||||
recalc_const_item= 1;
|
recalc_const_item= 1;
|
||||||
break;
|
break;
|
||||||
|
@ -15850,7 +15850,7 @@ init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr)
|
|||||||
{
|
{
|
||||||
for (; func_ptr != end_ptr ;func_ptr++)
|
for (; func_ptr != end_ptr ;func_ptr++)
|
||||||
{
|
{
|
||||||
if ((*func_ptr)->reset())
|
if ((*func_ptr)->reset_and_add())
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* If rollup, calculate the upper sum levels */
|
/* If rollup, calculate the upper sum levels */
|
||||||
|
Reference in New Issue
Block a user