Commit 5f6df1b2 authored by igor@olga.mysql.com's avatar igor@olga.mysql.com
Browse files

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.
parent 2bfbe2cd
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -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
+24 −0
Original line number Diff line number Diff line
@@ -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
+10 −3
Original line number Diff line number Diff line
@@ -231,9 +231,9 @@ class Field
    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 @@ class Field_bit :public Field {
  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); }