summaryrefslogtreecommitdiff
path: root/mysql-test
diff options
context:
space:
mode:
authorGleb Shchepa <gshchepa@mysql.com>2008-08-28 02:10:37 +0500
committerGleb Shchepa <gshchepa@mysql.com>2008-08-28 02:10:37 +0500
commit54a59681d68d9e2edd1354443d35e54bd8373090 (patch)
treed22df32f27a2cd41a8c2f949fe7d25b968b838ae /mysql-test
parent06bf25e4d429682a518bea5a1b67392fe51756da (diff)
downloadmariadb-git-54a59681d68d9e2edd1354443d35e54bd8373090.tar.gz
Bug #37799: SELECT with a BIT column in WHERE clause
returns unexpected result If: 1. a table has a not nullable BIT column c1 with a length shorter than 8 bits and some additional not nullable columns c2 etc, and 2. the WHERE clause is like: (c1 = constant) AND c2 ..., the SELECT query returns unexpected result set. The server stores BIT columns in a tricky way to save disk space: if column's bit length is not divisible by 8, the server places reminder bits among the null bits at the start of a record. The rest bytes are stored in the record itself, and Field::ptr points to these rest bytes. However if a bit length of the whole column is less than 8, there are no remaining bytes, and there is nothing to store in the record at its regular place. In this case Field::ptr points to bytes actually occupied by the next column in a record. If both columns (BIT and the next column) are NOT NULL, the Field::eq function incorrectly deduces that this is the same column, so query transformation/equal item elimination code (see build_equal_items_for_cond) may mix these columns and damage conditions containing references to them. mysql-test/r/type_bit.result: Added test case for bug #37799. mysql-test/t/type_bit.test: Added test case for bug #37799. sql/field.h: 1. The Field::eq function has been modified to take types of comparing columns into account to distinguish between BIT and not BIT columns referencing the same bytes in a record. 2. Unnecessary type comparison has been removed from the Field_bit::eq function (moved to Field::eq).
Diffstat (limited to 'mysql-test')
-rw-r--r--mysql-test/r/type_bit.result24
-rw-r--r--mysql-test/t/type_bit.test19
2 files changed, 43 insertions, 0 deletions
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index 4c4fcb9a9ae..68c0e1635a3 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -684,4 +684,28 @@ SELECT 1 FROM t1 GROUP BY a;
1
1
DROP TABLE t1;
+CREATE TABLE t1 (b BIT NOT NULL, i2 INTEGER NOT NULL, s VARCHAR(255) NOT NULL);
+INSERT INTO t1 VALUES(0x01,100,''), (0x00,300,''), (0x01,200,''), (0x00,100,'');
+SELECT HEX(b), i2 FROM t1 WHERE (i2>=100 AND i2<201) AND b=TRUE;
+HEX(b) i2
+1 100
+1 200
+CREATE TABLE t2 (b1 BIT NOT NULL, b2 BIT NOT NULL, i2 INTEGER NOT NULL,
+s VARCHAR(255) NOT NULL);
+INSERT INTO t2 VALUES (0x01,0x00,100,''), (0x00,0x01,300,''),
+(0x01,0x00,200,''), (0x00,0x01,100,'');
+SELECT HEX(b1), i2 FROM t2 WHERE (i2>=100 AND i2<201) AND b1=TRUE;
+HEX(b1) i2
+1 100
+1 200
+SELECT HEX(b2), i2 FROM t2 WHERE (i2>=100 AND i2<201) AND b2=FALSE;
+HEX(b2) i2
+0 100
+0 200
+SELECT HEX(b1), HEX(b2), i2 FROM t2
+WHERE (i2>=100 AND i2<201) AND b1=TRUE AND b2=FALSE;
+HEX(b1) HEX(b2) i2
+1 0 100
+1 0 200
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index 3095311bfbc..6a6b29deda4 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -333,4 +333,23 @@ SELECT 1 FROM t1 GROUP BY a;
DROP TABLE t1;
+#
+# Bug#37799 SELECT with a BIT column in WHERE clause returns unexpected result
+#
+
+CREATE TABLE t1 (b BIT NOT NULL, i2 INTEGER NOT NULL, s VARCHAR(255) NOT NULL);
+INSERT INTO t1 VALUES(0x01,100,''), (0x00,300,''), (0x01,200,''), (0x00,100,'');
+SELECT HEX(b), i2 FROM t1 WHERE (i2>=100 AND i2<201) AND b=TRUE;
+
+CREATE TABLE t2 (b1 BIT NOT NULL, b2 BIT NOT NULL, i2 INTEGER NOT NULL,
+ s VARCHAR(255) NOT NULL);
+INSERT INTO t2 VALUES (0x01,0x00,100,''), (0x00,0x01,300,''),
+ (0x01,0x00,200,''), (0x00,0x01,100,'');
+SELECT HEX(b1), i2 FROM t2 WHERE (i2>=100 AND i2<201) AND b1=TRUE;
+SELECT HEX(b2), i2 FROM t2 WHERE (i2>=100 AND i2<201) AND b2=FALSE;
+SELECT HEX(b1), HEX(b2), i2 FROM t2
+ WHERE (i2>=100 AND i2<201) AND b1=TRUE AND b2=FALSE;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests