Commit 9066714c authored by Alexey Kopytov's avatar Alexey Kopytov

Bug #54190: Comparison to row subquery produces incorrect

            result

Row subqueries producing no rows were not handled as UNKNOWN
values in row comparison expressions.

That was a result of the following two problems:

1. Item_singlerow_subselect did not mark the resulting row
value as NULL/UNKNOWN when no rows were produced.

2. Arg_comparator::compare_row() did not take into account that
a whole argument may be NULL rather than just individual scalar
values.

Before bug#34384 was fixed, the above problems were hidden
because an uninitialized (i.e. without any stored value) cached
object would appear as NULL for scalar values in a row subquery
returning an empty result. After the fix
Arg_comparator::compare_row() would try to evaluate
uninitialized cached objects.

Fixed by removing the aforementioned problems.
parent a73b7349
...@@ -466,3 +466,26 @@ SELECT 1 FROM t1 WHERE ROW(a, b) >= ...@@ -466,3 +466,26 @@ SELECT 1 FROM t1 WHERE ROW(a, b) >=
ROW('1', (SELECT 1 FROM t1 WHERE a > 1234)); ROW('1', (SELECT 1 FROM t1 WHERE a > 1234));
1 1
DROP TABLE t1; DROP TABLE t1;
#
# Bug #54190: Comparison to row subquery produces incorrect result
#
SELECT ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0);
ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0)
NULL
SELECT ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0);
ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0)
NULL
CREATE TABLE t1 (i INT);
INSERT INTO t1 () VALUES (1), (2), (3);
SELECT ROW(1,2) = (SELECT 1,2 FROM t1 WHERE 1 = 0);
ROW(1,2) = (SELECT 1,2 FROM t1 WHERE 1 = 0)
NULL
SELECT ROW(1,2) = (SELECT 1,3 FROM t1 WHERE 1 = 0);
ROW(1,2) = (SELECT 1,3 FROM t1 WHERE 1 = 0)
NULL
SELECT i FROM t1 WHERE ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0);
i
SELECT i FROM t1 WHERE ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0);
i
DROP TABLE t1;
End of 5.1 tests
...@@ -922,7 +922,7 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t ...@@ -922,7 +922,7 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t
a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a) a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
1 1 a 1 1 a
2 0 b 2 0 b
NULL 0 NULL NULL NULL NULL
select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2; select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a) a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
1 0 a 1 0 a
...@@ -932,7 +932,7 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t ...@@ -932,7 +932,7 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t
a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a) a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
1 0 a 1 0 a
2 0 b 2 0 b
NULL 0 NULL NULL NULL NULL
drop table t1,t2; drop table t1,t2;
create table t1 (a int, b real, c varchar(10)); create table t1 (a int, b real, c varchar(10));
insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b'); insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
......
...@@ -266,3 +266,22 @@ SELECT 1 FROM t1 WHERE ROW(a, b) >= ...@@ -266,3 +266,22 @@ SELECT 1 FROM t1 WHERE ROW(a, b) >=
ROW('1', (SELECT 1 FROM t1 WHERE a > 1234)); ROW('1', (SELECT 1 FROM t1 WHERE a > 1234));
--enable_warnings --enable_warnings
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug #54190: Comparison to row subquery produces incorrect result
--echo #
SELECT ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0);
SELECT ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0);
CREATE TABLE t1 (i INT);
INSERT INTO t1 () VALUES (1), (2), (3);
SELECT ROW(1,2) = (SELECT 1,2 FROM t1 WHERE 1 = 0);
SELECT ROW(1,2) = (SELECT 1,3 FROM t1 WHERE 1 = 0);
SELECT i FROM t1 WHERE ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0);
SELECT i FROM t1 WHERE ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0);
DROP TABLE t1;
--echo End of 5.1 tests
...@@ -1583,6 +1583,13 @@ int Arg_comparator::compare_row() ...@@ -1583,6 +1583,13 @@ int Arg_comparator::compare_row()
bool was_null= 0; bool was_null= 0;
(*a)->bring_value(); (*a)->bring_value();
(*b)->bring_value(); (*b)->bring_value();
if ((*a)->null_value || (*b)->null_value)
{
owner->null_value= 1;
return -1;
}
uint n= (*a)->cols(); uint n= (*a)->cols();
for (uint i= 0; i<n; i++) for (uint i= 0; i<n; i++)
{ {
......
...@@ -566,7 +566,10 @@ bool Item_singlerow_subselect::null_inside() ...@@ -566,7 +566,10 @@ bool Item_singlerow_subselect::null_inside()
void Item_singlerow_subselect::bring_value() void Item_singlerow_subselect::bring_value()
{ {
exec(); if (!exec() && assigned())
null_value= 0;
else
reset();
} }
double Item_singlerow_subselect::val_real() double Item_singlerow_subselect::val_real()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment