Skip to content

Commit 2296f90

Browse files
author
Ole John Aske
committed
Backport to mysql-5.1-telco-7.0:
Fix for bug#58818: Incorrect result for IN/ANY subquery If the ::single_value_transformer() find an existing HAVING condition it used to do the transformation: 1) HAVING cond -> (HAVING Cond) AND (cond_guard (Item_ref_null_helper(...)) As the AND condition in 1) is Mc'Carty evaluated, the right side of the AND cond should be executed only if the original 'HAVING evaluated' to true. However, as we failed to set 'top_level' for the tranformed HAVING condition, 'abort_on_null' was FALSE after transformation. An UNKNOWN having condition will then not terminate evaluation of the transformed having condition, and we incorrectly continued into the Item_ref_null_helper() part.
1 parent abf7f55 commit 2296f90

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed

mysql-test/r/subselect.result

+52
Original file line numberDiff line numberDiff line change
@@ -4733,4 +4733,56 @@ ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
47334733
SELECT * FROM t2 UNION SELECT * FROM t2
47344734
ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
47354735
DROP TABLE t1,t2;
4736+
#
4737+
# Bug #58818: Incorrect result for IN/ANY subquery
4738+
# with HAVING condition
4739+
#
4740+
CREATE TABLE t1(i INT);
4741+
INSERT INTO t1 VALUES (1), (2), (3);
4742+
CREATE TABLE t1s(i INT);
4743+
INSERT INTO t1s VALUES (10), (20), (30);
4744+
CREATE TABLE t2s(i INT);
4745+
INSERT INTO t2s VALUES (100), (200), (300);
4746+
SELECT * FROM t1
4747+
WHERE t1.i NOT IN
4748+
(
4749+
SELECT STRAIGHT_JOIN t2s.i
4750+
FROM
4751+
t1s LEFT OUTER JOIN t2s ON t2s.i = t1s.i
4752+
HAVING t2s.i = 999
4753+
);
4754+
i
4755+
1
4756+
2
4757+
3
4758+
SELECT * FROM t1
4759+
WHERE t1.I IN
4760+
(
4761+
SELECT STRAIGHT_JOIN t2s.i
4762+
FROM
4763+
t1s LEFT OUTER JOIN t2s ON t2s.i = t1s.i
4764+
HAVING t2s.i = 999
4765+
) IS UNKNOWN;
4766+
i
4767+
SELECT * FROM t1
4768+
WHERE NOT t1.I = ANY
4769+
(
4770+
SELECT STRAIGHT_JOIN t2s.i
4771+
FROM
4772+
t1s LEFT OUTER JOIN t2s ON t2s.i = t1s.i
4773+
HAVING t2s.i = 999
4774+
);
4775+
i
4776+
1
4777+
2
4778+
3
4779+
SELECT * FROM t1
4780+
WHERE t1.i = ANY (
4781+
SELECT STRAIGHT_JOIN t2s.i
4782+
FROM
4783+
t1s LEFT OUTER JOIN t2s ON t2s.i = t1s.i
4784+
HAVING t2s.i = 999
4785+
) IS UNKNOWN;
4786+
i
4787+
DROP TABLE t1,t1s,t2s;
47364788
End of 5.1 tests

mysql-test/t/subselect.test

+49
Original file line numberDiff line numberDiff line change
@@ -3725,4 +3725,53 @@ SELECT * FROM t2 UNION SELECT * FROM t2
37253725
DROP TABLE t1,t2;
37263726
--enable_result_log
37273727

3728+
--echo #
3729+
--echo # Bug #58818: Incorrect result for IN/ANY subquery
3730+
--echo # with HAVING condition
3731+
--echo #
3732+
3733+
CREATE TABLE t1(i INT);
3734+
INSERT INTO t1 VALUES (1), (2), (3);
3735+
CREATE TABLE t1s(i INT);
3736+
INSERT INTO t1s VALUES (10), (20), (30);
3737+
CREATE TABLE t2s(i INT);
3738+
INSERT INTO t2s VALUES (100), (200), (300);
3739+
3740+
SELECT * FROM t1
3741+
WHERE t1.i NOT IN
3742+
(
3743+
SELECT STRAIGHT_JOIN t2s.i
3744+
FROM
3745+
t1s LEFT OUTER JOIN t2s ON t2s.i = t1s.i
3746+
HAVING t2s.i = 999
3747+
);
3748+
3749+
SELECT * FROM t1
3750+
WHERE t1.I IN
3751+
(
3752+
SELECT STRAIGHT_JOIN t2s.i
3753+
FROM
3754+
t1s LEFT OUTER JOIN t2s ON t2s.i = t1s.i
3755+
HAVING t2s.i = 999
3756+
) IS UNKNOWN;
3757+
3758+
SELECT * FROM t1
3759+
WHERE NOT t1.I = ANY
3760+
(
3761+
SELECT STRAIGHT_JOIN t2s.i
3762+
FROM
3763+
t1s LEFT OUTER JOIN t2s ON t2s.i = t1s.i
3764+
HAVING t2s.i = 999
3765+
);
3766+
3767+
SELECT * FROM t1
3768+
WHERE t1.i = ANY (
3769+
SELECT STRAIGHT_JOIN t2s.i
3770+
FROM
3771+
t1s LEFT OUTER JOIN t2s ON t2s.i = t1s.i
3772+
HAVING t2s.i = 999
3773+
) IS UNKNOWN;
3774+
3775+
DROP TABLE t1,t1s,t2s;
3776+
37283777
--echo End of 5.1 tests

sql/item_subselect.cc

+3
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,9 @@ Item_in_subselect::single_value_transformer(JOIN *join,
11311131
select_lex->having= join->having= and_items(join->having, item);
11321132
if (join->having == item)
11331133
item->name= (char*)in_having_cond;
1134+
#ifndef MCP_BUG58818
1135+
select_lex->having->top_level_item();
1136+
#endif
11341137
select_lex->having_fix_field= 1;
11351138
/*
11361139
we do not check join->having->fixed, because Item_and (from and_items)

0 commit comments

Comments
 (0)