summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_group_innodb.result47
-rw-r--r--mysql-test/t/func_group_innodb.test50
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/item_sum.h20
-rw-r--r--sql/opt_range.cc4
-rw-r--r--sql/opt_sum.cc2
-rw-r--r--sql/sql_select.cc2
7 files changed, 116 insertions, 11 deletions
diff --git a/mysql-test/r/func_group_innodb.result b/mysql-test/r/func_group_innodb.result
index 908e85c1652..8412317c91d 100644
--- a/mysql-test/r/func_group_innodb.result
+++ b/mysql-test/r/func_group_innodb.result
@@ -145,3 +145,50 @@ select count(*), min(7), max(7) from t2m, t1i;
count(*) min(7) max(7)
0 NULL NULL
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
diff --git a/mysql-test/t/func_group_innodb.test b/mysql-test/t/func_group_innodb.test
index 1bdfd8f54bb..bbc576b0fc7 100644
--- a/mysql-test/t/func_group_innodb.test
+++ b/mysql-test/t/func_group_innodb.test
@@ -83,3 +83,53 @@ explain select count(*), min(7), max(7) from t2m, t1i;
select count(*), min(7), max(7) from t2m, t1i;
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
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index cf95fc3969f..7aff7940c4d 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2235,7 +2235,7 @@ void Item_sum_avg::reset_field()
void Item_sum_bit::reset_field()
{
- reset();
+ reset_and_add();
int8store(result_field->ptr, bits);
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index c7159568c40..3ea79fb8cee 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -406,14 +406,22 @@ public:
Item_sum(THD *thd, Item_sum *item);
enum Type type() const { return SUM_FUNC_ITEM; }
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
- 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.
- This set of methods (reult_field(), reset_field, update_field()) of
+ a temporary table. Similarly to reset_and_add() it resets the
+ value to its default and aggregates the value of its
+ attribute(s), but must also store it in result_field.
+ This set of methods (result_item(), reset_field, update_field()) of
Item_sum is used only if quick_group is not null. Otherwise
copy_or_same() is used to obtain a copy of this item.
*/
@@ -456,7 +464,7 @@ public:
set_aggregator(with_distinct ?
Aggregator::DISTINCT_AGGREGATOR :
Aggregator::SIMPLE_AGGREGATOR);
- reset();
+ aggregator_clear();
}
virtual void make_unique() { force_copy_fields= TRUE; }
Item *get_tmp_table_item(THD *thd);
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 2ac860d25e3..f39037e9db9 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -11391,7 +11391,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
min_functions_it->rewind();
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();
while ((max_func= (*max_functions_it)++))
- max_func->reset();
+ max_func->reset_and_add();
}
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index e020c94a3bd..a2f8b9c4447 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -424,7 +424,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
item_sum->aggregator_clear();
}
else
- item_sum->reset();
+ item_sum->reset_and_add();
item_sum->make_const();
recalc_const_item= 1;
break;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ef2dd1d76e1..e4772bf3fb2 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -15850,7 +15850,7 @@ init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr)
{
for (; func_ptr != end_ptr ;func_ptr++)
{
- if ((*func_ptr)->reset())
+ if ((*func_ptr)->reset_and_add())
return 1;
}
/* If rollup, calculate the upper sum levels */