mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug #39069: <row constructor> IN <table-subquery> seriously
messed up "ROW(...) IN (SELECT ... FROM DUAL)" always returned TRUE. Item_in_subselect::row_value_transformer rewrites "ROW(...) IN SELECT" conditions into the "EXISTS (SELECT ... HAVING ...)" form. For a subquery from the DUAL pseudotable resulting HAVING condition is an expression on constant values, so further transformation with optimize_cond() eliminates this HAVING condition and resets JOIN::having to NULL. Then JOIN::exec treated that NULL as an always-true-HAVING and that caused a bug. To distinguish an optimized out "HAVING TRUE" clause from "HAVING FALSE" we already have the JOIN::having_value flag. However, JOIN::exec() ignored JOIN::having_value as described above as if it always set to COND_TRUE. The JOIN::exec method has been modified to take into account the value of the JOIN::having_value field.
This commit is contained in:
@ -1608,8 +1608,13 @@ JOIN::exec()
|
||||
We have to test for 'conds' here as the WHERE may not be constant
|
||||
even if we don't have any tables for prepared statements or if
|
||||
conds uses something like 'rand()'.
|
||||
If the HAVING clause is either impossible or always true, then
|
||||
JOIN::having is set to NULL by optimize_cond.
|
||||
In this case JOIN::exec must check for JOIN::having_value, in the
|
||||
same way it checks for JOIN::cond_value.
|
||||
*/
|
||||
if (cond_value != Item::COND_FALSE &&
|
||||
having_value != Item::COND_FALSE &&
|
||||
(!conds || conds->val_int()) &&
|
||||
(!having || having->val_int()))
|
||||
{
|
||||
|
Reference in New Issue
Block a user