diff options
-rw-r--r-- | mysql-test/r/func_group_innodb.result | 47 | ||||
-rw-r--r-- | mysql-test/t/func_group_innodb.test | 50 | ||||
-rw-r--r-- | sql/item_sum.cc | 2 | ||||
-rw-r--r-- | sql/item_sum.h | 20 | ||||
-rw-r--r-- | sql/opt_range.cc | 4 | ||||
-rw-r--r-- | sql/opt_sum.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 |
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 */ |