Commit 89ce81ce authored by unknown's avatar unknown
Browse files

Bug #18895: BIT values cause joins to fail

The Field::eq() considered instances of Field_bit that differ only in 
bit_ptr/bit_ofs equal. This caused equality conditions optimization 
(build_equal_items_for_cond()) to make bad field substitutions that result
in wrong predicates. 
Field_bit requires an overloaded eq() function that checks the bit_ptr/bit_ofs
in addition to Field::eq().


mysql-test/r/select.result:
  Bug #18895: BIT values cause joins to fail
  
  - test case
mysql-test/t/select.test:
  Bug #18895: BIT values cause joins to fail
  
  - test case
sql/field.h:
  Bug #18895: BIT values cause joins to fail
  
  - eq() method overloaded for Field_bit
parent 86334edf
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -3359,3 +3359,23 @@ id select_type table type possible_keys key key_len ref rows Extra
1	SIMPLE	t1	range	PRIMARY,b	b	5	NULL	3	Using where
1	SIMPLE	t2	ref	c	c	5	test.t1.a	2	Using where
DROP TABLE t1, t2;
create table t1 (
a int unsigned    not null auto_increment primary key,
b bit             not null,
c bit             not null
);
create table t2 (
a int unsigned    not null auto_increment primary key,
b bit             not null,
c int unsigned    not null,
d varchar(50)
);
insert into t1 (b,c) values (0,1), (0,1);
insert into t2 (b,c) values (0,1);
select t1.a, t1.b + 0, t1.c + 0, t2.a, t2.b + 0, t2.c, t2.d
from t1 left outer join t2 on t1.a = t2.c and t2.b <> 1
where t1.b <> 1 order by t1.a;
a	t1.b + 0	t1.c + 0	a	t2.b + 0	c	d
1	0	1	1	0	1	NULL
2	0	1	NULL	NULL	NULL	NULL
drop table t1,t2;
+26 −0
Original line number Diff line number Diff line
@@ -2840,3 +2840,29 @@ EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;

DROP TABLE t1, t2;

#
# Bug #18895: BIT values cause joins to fail
#
create table t1 (
    a int unsigned    not null auto_increment primary key,
    b bit             not null,
    c bit             not null
);

create table t2 (
    a int unsigned    not null auto_increment primary key,
    b bit             not null,
    c int unsigned    not null,
    d varchar(50)
);

insert into t1 (b,c) values (0,1), (0,1);
insert into t2 (b,c) values (0,1);

-- Row 1 should succeed.  Row 2 should fail.  Both fail.
select t1.a, t1.b + 0, t1.c + 0, t2.a, t2.b + 0, t2.c, t2.d
from t1 left outer join t2 on t1.a = t2.c and t2.b <> 1
where t1.b <> 1 order by t1.a;

drop table t1,t2;
+8 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ class Field
  static bool type_can_have_key_part(enum_field_types);
  static enum_field_types field_type_merge(enum_field_types, enum_field_types);
  static Item_result result_merge_type(enum_field_types);
  bool eq(Field *field)
  virtual bool eq(Field *field)
  {
    return (ptr == field->ptr && null_ptr == field->null_ptr &&
            null_bit == field->null_bit);
@@ -1358,6 +1358,13 @@ class Field_bit :public Field {
    bit_ptr= bit_ptr_arg;
    bit_ofs= bit_ofs_arg;
  }
  bool eq(Field *field)
  {
    return (Field::eq(field) &&
            field->type() == type() &&
            bit_ptr == ((Field_bit *)field)->bit_ptr &&
            bit_ofs == ((Field_bit *)field)->bit_ofs);
  }
};