mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-5401: Wrong result (missing row) on a 2nd execution of PS with exists_to_in=on, MERGE view or a SELECT SQ
The problem was that the view substitute its fields (on prepare) with reverting the change after execution. After prepare on optimization exists2in convertion substituted arguments of '=' with constsnt '1', but then one of the arguments of '=' was reverted to the view field reference.This lead to incorrect WHERE condition on the second execution. To fix the problem we replace whole '=' with '1' permannently.
This commit is contained in:
parent
584c2d0ae9
commit
39afdcddd1
3 changed files with 53 additions and 9 deletions
|
@ -862,4 +862,27 @@ i c1 c2 t1_field t2_field
|
|||
drop table t1,t2,t3;
|
||||
set optimizer_switch=default;
|
||||
set optimizer_switch='exists_to_in=on';
|
||||
#
|
||||
#MDEV-5401: Wrong result (missing row) on a 2nd execution of PS with
|
||||
#exists_to_in=on, MERGE view or a SELECT SQ
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
|
||||
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES (2),(3);
|
||||
SELECT * FROM v1 WHERE EXISTS ( SELECT * FROM t2 t2x, t2 t2y WHERE t2y.b = a );
|
||||
a
|
||||
2
|
||||
PREPARE stmt FROM "SELECT * FROM v1 WHERE EXISTS ( SELECT * FROM t2 t2x, t2 t2y WHERE t2y.b = a )";
|
||||
EXECUTE stmt;
|
||||
a
|
||||
2
|
||||
EXECUTE stmt;
|
||||
a
|
||||
2
|
||||
deallocate prepare stmt;
|
||||
drop view v1;
|
||||
drop table t1,t2;
|
||||
# End of 10.0 tests
|
||||
set optimizer_switch=default;
|
||||
|
|
|
@ -735,5 +735,30 @@ drop table t1,t2,t3;
|
|||
set optimizer_switch=default;
|
||||
set optimizer_switch='exists_to_in=on';
|
||||
|
||||
--echo #
|
||||
--echo #MDEV-5401: Wrong result (missing row) on a 2nd execution of PS with
|
||||
--echo #exists_to_in=on, MERGE view or a SELECT SQ
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
|
||||
|
||||
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES (2),(3);
|
||||
|
||||
SELECT * FROM v1 WHERE EXISTS ( SELECT * FROM t2 t2x, t2 t2y WHERE t2y.b = a );
|
||||
|
||||
PREPARE stmt FROM "SELECT * FROM v1 WHERE EXISTS ( SELECT * FROM t2 t2x, t2 t2y WHERE t2y.b = a )";
|
||||
EXECUTE stmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
deallocate prepare stmt;
|
||||
|
||||
drop view v1;
|
||||
drop table t1,t2;
|
||||
|
||||
--echo # End of 10.0 tests
|
||||
|
||||
#restore defaults
|
||||
set optimizer_switch=default;
|
||||
|
|
|
@ -2626,7 +2626,7 @@ static bool check_equality_for_exist2in(Item_func *func,
|
|||
|
||||
typedef struct st_eq_field_outer
|
||||
{
|
||||
Item_func **eq_ref;
|
||||
Item **eq_ref;
|
||||
Item_ident *local_field;
|
||||
Item *outer_exp;
|
||||
} EQ_FIELD_OUTER;
|
||||
|
@ -2665,7 +2665,7 @@ static bool find_inner_outer_equalities(Item **conds,
|
|||
&element.outer_exp))
|
||||
{
|
||||
found= TRUE;
|
||||
element.eq_ref= (Item_func **)li.ref();
|
||||
element.eq_ref= li.ref();
|
||||
if (result.append(element))
|
||||
goto alloc_err;
|
||||
}
|
||||
|
@ -2677,7 +2677,7 @@ static bool find_inner_outer_equalities(Item **conds,
|
|||
&element.outer_exp))
|
||||
{
|
||||
found= TRUE;
|
||||
element.eq_ref= (Item_func **)conds;
|
||||
element.eq_ref= conds;
|
||||
if (result.append(element))
|
||||
goto alloc_err;
|
||||
}
|
||||
|
@ -2700,7 +2700,7 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
|
|||
THD *thd= (THD *)opt_arg;
|
||||
SELECT_LEX *first_select=unit->first_select(), *save_select;
|
||||
JOIN *join= first_select->join;
|
||||
Item_func *eq= NULL, **eq_ref= NULL;
|
||||
Item **eq_ref= NULL;
|
||||
Item_ident *local_field= NULL;
|
||||
Item *outer_exp= NULL;
|
||||
Item *left_exp= NULL; Item_in_subselect *in_subs;
|
||||
|
@ -2774,7 +2774,6 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
|
|||
{
|
||||
Item *item= it++;
|
||||
eq_ref= eqs.at(i).eq_ref;
|
||||
eq= *eq_ref;
|
||||
local_field= eqs.at(i).local_field;
|
||||
outer_exp= eqs.at(i).outer_exp;
|
||||
/* Add the field to the SELECT_LIST */
|
||||
|
@ -2789,10 +2788,7 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
|
|||
|
||||
/* remove the parts from condition */
|
||||
if (!upper_not || !local_field->maybe_null)
|
||||
{
|
||||
eq->arguments()[0]= new Item_int(1);
|
||||
eq->arguments()[1]= new Item_int(1);
|
||||
}
|
||||
*eq_ref= new Item_int(1);
|
||||
else
|
||||
{
|
||||
*eq_ref= new Item_func_isnotnull(
|
||||
|
|
Loading…
Reference in a new issue