From 4e6e122061b71f9378a161793367ae5120310ed4 Mon Sep 17 00:00:00 2001 From: unknown <igor@olga.mysql.com> Date: Sun, 5 Aug 2007 14:16:49 -0700 Subject: [PATCH] Fix bug #30219. This bug manifested itself for queries with grouping by columns of the BIT type. It led to wrong comparisons of bit-field values and wrong result sets. Bit-field values never cannot be compared as binary values. Yet the class Field_bit had an implementation of the cmp method that compared bit-fields values as binary values. Also the get_image and set_image methods of the base class Field cannot be used for objects of the Field_bit class. Now these methods are declared as virtual and specific implementations of the methods are provided for the class Field_bit. mysql-test/r/type_bit.result: Added a test case for bug #30219. mysql-test/t/type_bit.test: Added a test case for bug #30219. sql/field.h: Fix bug #30219. This bug manifested itself for queries with grouping by columns of the BIT type. It led to wrong comparisons of bit-field values and wrong result sets. Bit-field values never cannot be compared as binary values. Yet the class Field_bit had an implementation of the cmp method that compared bit-fields values as binary values. Also the get_image and set_image methods of the base class Field cannot be used for objects of the Field_bit class. Now these methods are declared as virtual and specific implementations of these methods are provided for the class Field_bit. --- mysql-test/r/type_bit.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/type_bit.test | 24 ++++++++++++++++++++++++ sql/field.h | 13 ++++++++++--- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index fad0e1f797..324dcc2775 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -618,4 +618,36 @@ bit_field int_field 2 handler t1 close; drop table t1; +CREATE TABLE t1 (b BIT(2)); +INSERT INTO t1 (b) VALUES (1), (3), (0), (3); +SELECT b+0, COUNT(DISTINCT b) FROM t1 GROUP BY b; +b+0 COUNT(DISTINCT b) +0 1 +1 1 +3 1 +DROP TABLE t1; +CREATE TABLE t1 (b BIT(2), a VARCHAR(5)); +INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z"); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +b+0 COUNT(DISTINCT a) +0 1 +1 1 +3 2 +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(5), b BIT(2)); +INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z"); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +b+0 COUNT(DISTINCT a) +0 1 +1 1 +3 2 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b BIT(2)); +INSERT INTO t1 (b, a) VALUES (1, 1), (3, 2), (0, 3), (3, 4); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +b+0 COUNT(DISTINCT a) +0 1 +1 1 +3 2 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 48ad24ff6b..2c7f87f342 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -272,4 +272,28 @@ handler t1 read a=(1); handler t1 close; drop table t1; +# +# Bug #30219: GROUP BY a column of the BIT type +# + +CREATE TABLE t1 (b BIT(2)); +INSERT INTO t1 (b) VALUES (1), (3), (0), (3); +SELECT b+0, COUNT(DISTINCT b) FROM t1 GROUP BY b; +DROP TABLE t1; + +CREATE TABLE t1 (b BIT(2), a VARCHAR(5)); +INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z"); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +DROP TABLE t1; + +CREATE TABLE t1 (a CHAR(5), b BIT(2)); +INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z"); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b BIT(2)); +INSERT INTO t1 (b, a) VALUES (1, 1), (3, 2), (0, 3), (3, 4); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/field.h b/sql/field.h index fbf402ab5c..92705b9aac 100644 --- a/sql/field.h +++ b/sql/field.h @@ -231,9 +231,9 @@ public: if (null_ptr) null_ptr=ADD_TO_PTR(null_ptr,ptr_diff,uchar*); } - inline void get_image(char *buff,uint length, CHARSET_INFO *cs) + virtual void get_image(char *buff, uint length, CHARSET_INFO *cs) { memcpy(buff,ptr,length); } - inline void set_image(char *buff,uint length, CHARSET_INFO *cs) + virtual void set_image(char *buff,uint length, CHARSET_INFO *cs) { memcpy(ptr,buff,length); } @@ -1430,13 +1430,20 @@ public: String *val_str(String*, String *); my_decimal *val_decimal(my_decimal *); int cmp(const char *a, const char *b) - { return cmp_binary(a, b); } + { + DBUG_ASSERT(ptr == a); + return Field_bit::key_cmp(b, bytes_in_rec+test(bit_len)); + } int key_cmp(const byte *a, const byte *b) { return cmp_binary((char *) a, (char *) b); } int key_cmp(const byte *str, uint length); int cmp_offset(uint row_offset); int cmp_binary_offset(uint row_offset) { return cmp_offset(row_offset); } + void get_image(char *buff, uint length, CHARSET_INFO *cs) + { get_key_image(buff, length, itRAW); } + void set_image(char *buff,uint length, CHARSET_INFO *cs) + { Field_bit::store(buff, length, cs); } uint get_key_image(char *buff, uint length, imagetype type); void set_key_image(char *buff, uint length) { Field_bit::store(buff, length, &my_charset_bin); } -- 2.30.9