Merge gshchepa.loc:/home/uchum/work/bk-trees/mysql-4.1-opt-27704

into  gshchepa.loc:/home/uchum/work/bk-trees/mysql-5.0-opt-27704


mysql-test/r/subselect.result:
  Auto merged
mysql-test/t/row.test:
  Auto merged
mysql-test/r/row.result:
  Test case updated for Bug#27704 (incorrect comparison
  of rows with NULL components).
sql/item_cmpfunc.cc:
  Bug#27704: incorrect comparison of rows with NULL components.
sql/item_cmpfunc.h:
  Bug#27704: incorrect comparison of rows with NULL components.
  Cosmetic fix.
This commit is contained in:
unknown 2007-04-20 15:31:33 +05:00
commit a501fdd695
4 changed files with 157 additions and 5 deletions

View file

@ -193,6 +193,103 @@ SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0));
ERROR 21000: Operand should contain 1 column(s)
SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2));
ERROR 21000: Operand should contain 1 column(s)
CREATE TABLE t1(a int, b int, c int);
INSERT INTO t1 VALUES (1, 2, 3),
(NULL, 2, 3 ), (1, NULL, 3 ), (1, 2, NULL),
(NULL, 2, 3+1), (1, NULL, 3+1), (1, 2+1, NULL),
(NULL, 2, 3-1), (1, NULL, 3-1), (1, 2-1, NULL);
SELECT (1,2,3) = (1, NULL, 3);
(1,2,3) = (1, NULL, 3)
NULL
SELECT (1,2,3) = (1+1, NULL, 3);
(1,2,3) = (1+1, NULL, 3)
0
SELECT (1,2,3) = (1, NULL, 3+1);
(1,2,3) = (1, NULL, 3+1)
0
SELECT * FROM t1 WHERE (a,b,c) = (1,2,3);
a b c
1 2 3
SELECT (1,2,3) <> (1, NULL, 3);
(1,2,3) <> (1, NULL, 3)
NULL
SELECT (1,2,3) <> (1+1, NULL, 3);
(1,2,3) <> (1+1, NULL, 3)
1
SELECT (1,2,3) <> (1, NULL, 3+1);
(1,2,3) <> (1, NULL, 3+1)
1
SELECT * FROM t1 WHERE (a,b,c) <> (1,2,3);
a b c
NULL 2 4
1 NULL 4
1 3 NULL
NULL 2 2
1 NULL 2
1 1 NULL
SELECT (1,2,3) < (NULL, 2, 3);
(1,2,3) < (NULL, 2, 3)
NULL
SELECT (1,2,3) < (1, NULL, 3);
(1,2,3) < (1, NULL, 3)
NULL
SELECT (1,2,3) < (1-1, NULL, 3);
(1,2,3) < (1-1, NULL, 3)
0
SELECT (1,2,3) < (1+1, NULL, 3);
(1,2,3) < (1+1, NULL, 3)
1
SELECT * FROM t1 WHERE (a,b,c) < (1,2,3);
a b c
1 1 NULL
SELECT (1,2,3) <= (NULL, 2, 3);
(1,2,3) <= (NULL, 2, 3)
NULL
SELECT (1,2,3) <= (1, NULL, 3);
(1,2,3) <= (1, NULL, 3)
NULL
SELECT (1,2,3) <= (1-1, NULL, 3);
(1,2,3) <= (1-1, NULL, 3)
0
SELECT (1,2,3) <= (1+1, NULL, 3);
(1,2,3) <= (1+1, NULL, 3)
1
SELECT * FROM t1 WHERE (a,b,c) <= (1,2,3);
a b c
1 2 3
1 1 NULL
SELECT (1,2,3) > (NULL, 2, 3);
(1,2,3) > (NULL, 2, 3)
NULL
SELECT (1,2,3) > (1, NULL, 3);
(1,2,3) > (1, NULL, 3)
NULL
SELECT (1,2,3) > (1-1, NULL, 3);
(1,2,3) > (1-1, NULL, 3)
1
SELECT (1,2,3) > (1+1, NULL, 3);
(1,2,3) > (1+1, NULL, 3)
0
SELECT * FROM t1 WHERE (a,b,c) > (1,2,3);
a b c
1 3 NULL
SELECT (1,2,3) >= (NULL, 2, 3);
(1,2,3) >= (NULL, 2, 3)
NULL
SELECT (1,2,3) >= (1, NULL, 3);
(1,2,3) >= (1, NULL, 3)
NULL
SELECT (1,2,3) >= (1-1, NULL, 3);
(1,2,3) >= (1-1, NULL, 3)
1
SELECT (1,2,3) >= (1+1, NULL, 3);
(1,2,3) >= (1+1, NULL, 3)
0
SELECT * FROM t1 WHERE (a,b,c) >= (1,2,3);
a b c
1 2 3
1 3 NULL
DROP TABLE t1;
SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ;
1 0 0 0 null
1 0 0 0 NULL

View file

@ -110,6 +110,51 @@ SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0));
--error 1241
SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2));
#
# Bug#27704: erroneous comparison of rows with NULL components
#
CREATE TABLE t1(a int, b int, c int);
INSERT INTO t1 VALUES (1, 2, 3),
(NULL, 2, 3 ), (1, NULL, 3 ), (1, 2, NULL),
(NULL, 2, 3+1), (1, NULL, 3+1), (1, 2+1, NULL),
(NULL, 2, 3-1), (1, NULL, 3-1), (1, 2-1, NULL);
SELECT (1,2,3) = (1, NULL, 3);
SELECT (1,2,3) = (1+1, NULL, 3);
SELECT (1,2,3) = (1, NULL, 3+1);
SELECT * FROM t1 WHERE (a,b,c) = (1,2,3);
SELECT (1,2,3) <> (1, NULL, 3);
SELECT (1,2,3) <> (1+1, NULL, 3);
SELECT (1,2,3) <> (1, NULL, 3+1);
SELECT * FROM t1 WHERE (a,b,c) <> (1,2,3);
SELECT (1,2,3) < (NULL, 2, 3);
SELECT (1,2,3) < (1, NULL, 3);
SELECT (1,2,3) < (1-1, NULL, 3);
SELECT (1,2,3) < (1+1, NULL, 3);
SELECT * FROM t1 WHERE (a,b,c) < (1,2,3);
SELECT (1,2,3) <= (NULL, 2, 3);
SELECT (1,2,3) <= (1, NULL, 3);
SELECT (1,2,3) <= (1-1, NULL, 3);
SELECT (1,2,3) <= (1+1, NULL, 3);
SELECT * FROM t1 WHERE (a,b,c) <= (1,2,3);
SELECT (1,2,3) > (NULL, 2, 3);
SELECT (1,2,3) > (1, NULL, 3);
SELECT (1,2,3) > (1-1, NULL, 3);
SELECT (1,2,3) > (1+1, NULL, 3);
SELECT * FROM t1 WHERE (a,b,c) > (1,2,3);
SELECT (1,2,3) >= (NULL, 2, 3);
SELECT (1,2,3) >= (1, NULL, 3);
SELECT (1,2,3) >= (1-1, NULL, 3);
SELECT (1,2,3) >= (1+1, NULL, 3);
SELECT * FROM t1 WHERE (a,b,c) >= (1,2,3);
DROP TABLE t1;
# End of 4.1 tests
#

View file

@ -811,8 +811,18 @@ int Arg_comparator::compare_row()
if (owner->null_value)
{
// NULL was compared
if (owner->abort_on_null)
return -1; // We do not need correct NULL returning
switch (owner->functype()) {
case Item_func::NE_FUNC:
break; // NE never aborts on NULL even if abort_on_null is set
case Item_func::LT_FUNC:
case Item_func::LE_FUNC:
case Item_func::GT_FUNC:
case Item_func::GE_FUNC:
return -1; // <, <=, > and >= always fail on NULL
default: // EQ_FUNC
if (owner->abort_on_null)
return -1; // We do not need correct NULL returning
}
was_null= 1;
owner->null_value= 0;
res= 0; // continue comparison (maybe we will meet explicit difference)
@ -823,8 +833,8 @@ int Arg_comparator::compare_row()
if (was_null)
{
/*
There was NULL(s) in comparison in some parts, but there was not
explicit difference in other parts, so we have to return NULL
There was NULL(s) in comparison in some parts, but there was no
explicit difference in other parts, so we have to return NULL.
*/
owner->null_value= 1;
return -1;

View file

@ -333,7 +333,7 @@ public:
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
uint decimal_precision() const { return 1; }
void top_level_item() { abort_on_null=1; }
void top_level_item() { abort_on_null= TRUE; }
friend class Arg_comparator;
};