mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 18:41:56 +01:00
Merge
This commit is contained in:
commit
0df523d1f3
7 changed files with 110 additions and 2 deletions
|
@ -747,4 +747,21 @@ LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
|
||||||
GROUP BY field2;
|
GROUP BY field2;
|
||||||
field2
|
field2
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
#
|
||||||
|
# BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( c varchar(1)) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES ('r');
|
||||||
|
CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
|
||||||
|
INSERT INTO t2 VALUES (1,'r','r');
|
||||||
|
CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
|
||||||
|
EXECUTE st1;
|
||||||
|
a b c
|
||||||
|
1 r r
|
||||||
|
EXECUTE st1;
|
||||||
|
a b c
|
||||||
|
1 r r
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
set optimizer_switch=@subselect_sj2_tmp;
|
set optimizer_switch=@subselect_sj2_tmp;
|
||||||
|
|
|
@ -758,6 +758,23 @@ LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
|
||||||
GROUP BY field2;
|
GROUP BY field2;
|
||||||
field2
|
field2
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
#
|
||||||
|
# BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( c varchar(1)) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES ('r');
|
||||||
|
CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
|
||||||
|
INSERT INTO t2 VALUES (1,'r','r');
|
||||||
|
CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
|
||||||
|
EXECUTE st1;
|
||||||
|
a b c
|
||||||
|
1 r r
|
||||||
|
EXECUTE st1;
|
||||||
|
a b c
|
||||||
|
1 r r
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
set optimizer_switch=@subselect_sj2_tmp;
|
set optimizer_switch=@subselect_sj2_tmp;
|
||||||
set join_cache_level=default;
|
set join_cache_level=default;
|
||||||
show variables like 'join_cache_level';
|
show variables like 'join_cache_level';
|
||||||
|
|
|
@ -944,4 +944,22 @@ WHERE alias2.f11 IN (
|
||||||
GROUP BY field2;
|
GROUP BY field2;
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 ( c varchar(1)) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES ('r');
|
||||||
|
|
||||||
|
CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
|
||||||
|
INSERT INTO t2 VALUES (1,'r','r');
|
||||||
|
|
||||||
|
CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
|
||||||
|
PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
|
||||||
|
EXECUTE st1;
|
||||||
|
EXECUTE st1;
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
set optimizer_switch=@subselect_sj2_tmp;
|
set optimizer_switch=@subselect_sj2_tmp;
|
||||||
|
|
|
@ -4648,6 +4648,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
||||||
if (!outer_fixed && cached_table && cached_table->select_lex &&
|
if (!outer_fixed && cached_table && cached_table->select_lex &&
|
||||||
context->select_lex &&
|
context->select_lex &&
|
||||||
cached_table->select_lex != context->select_lex &&
|
cached_table->select_lex != context->select_lex &&
|
||||||
|
!context->select_lex->is_merged_child_of(cached_table->select_lex) &&
|
||||||
is_outer_table(cached_table, context->select_lex))
|
is_outer_table(cached_table, context->select_lex))
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -6447,11 +6447,25 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
||||||
{
|
{
|
||||||
SELECT_LEX *current_sel= thd->lex->current_select;
|
SELECT_LEX *current_sel= thd->lex->current_select;
|
||||||
SELECT_LEX *last_select= table_ref->select_lex;
|
SELECT_LEX *last_select= table_ref->select_lex;
|
||||||
|
bool all_merged= TRUE;
|
||||||
|
for (SELECT_LEX *sl= current_sel; sl && sl!=last_select;
|
||||||
|
sl=sl->outer_select())
|
||||||
|
{
|
||||||
|
Item *subs= sl->master_unit()->item;
|
||||||
|
if (subs->type() == Item::SUBSELECT_ITEM &&
|
||||||
|
((Item_subselect*)subs)->substype() == Item_subselect::IN_SUBS &&
|
||||||
|
((Item_in_subselect*)subs)->in_strategy & SUBS_SEMI_JOIN)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
all_merged= FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
If the field was an outer referencee, mark all selects using this
|
If the field was an outer referencee, mark all selects using this
|
||||||
sub query as dependent on the outer query
|
sub query as dependent on the outer query
|
||||||
*/
|
*/
|
||||||
if (current_sel != last_select)
|
if (!all_merged && current_sel != last_select)
|
||||||
{
|
{
|
||||||
mark_select_range_as_dependent(thd, last_select, current_sel,
|
mark_select_range_as_dependent(thd, last_select, current_sel,
|
||||||
found, *ref, item);
|
found, *ref, item);
|
||||||
|
|
|
@ -3622,6 +3622,47 @@ bool st_select_lex::save_prep_leaf_tables(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return true if this select_lex has been converted into a semi-join nest
|
||||||
|
within 'ancestor'.
|
||||||
|
|
||||||
|
We need a loop to check this because there could be several nested
|
||||||
|
subselects, like
|
||||||
|
|
||||||
|
SELECT ... FROM grand_parent
|
||||||
|
WHERE expr1 IN (SELECT ... FROM parent
|
||||||
|
WHERE expr2 IN ( SELECT ... FROM child)
|
||||||
|
|
||||||
|
which were converted into:
|
||||||
|
|
||||||
|
SELECT ...
|
||||||
|
FROM grand_parent SEMI_JOIN (parent JOIN child)
|
||||||
|
WHERE
|
||||||
|
expr1 AND expr2
|
||||||
|
|
||||||
|
In this case, both parent and child selects were merged into the parent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool st_select_lex::is_merged_child_of(st_select_lex *ancestor)
|
||||||
|
{
|
||||||
|
bool all_merged= TRUE;
|
||||||
|
for (SELECT_LEX *sl= this; sl && sl!=ancestor;
|
||||||
|
sl=sl->outer_select())
|
||||||
|
{
|
||||||
|
Item *subs= sl->master_unit()->item;
|
||||||
|
if (subs && subs->type() == Item::SUBSELECT_ITEM &&
|
||||||
|
((Item_subselect*)subs)->substype() == Item_subselect::IN_SUBS &&
|
||||||
|
((Item_in_subselect*)subs)->in_strategy & SUBS_SEMI_JOIN)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
all_merged= FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return all_merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A routine used by the parser to decide whether we are specifying a full
|
A routine used by the parser to decide whether we are specifying a full
|
||||||
partitioning or if only partitions to add or to split.
|
partitioning or if only partitions to add or to split.
|
||||||
|
|
|
@ -907,7 +907,7 @@ public:
|
||||||
|
|
||||||
bool save_leaf_tables(THD *thd);
|
bool save_leaf_tables(THD *thd);
|
||||||
bool save_prep_leaf_tables(THD *thd);
|
bool save_prep_leaf_tables(THD *thd);
|
||||||
|
bool is_merged_child_of(st_select_lex *ancestor);
|
||||||
private:
|
private:
|
||||||
/* current index hint kind. used in filling up index_hints */
|
/* current index hint kind. used in filling up index_hints */
|
||||||
enum index_hint_type current_index_hint_type;
|
enum index_hint_type current_index_hint_type;
|
||||||
|
|
Loading…
Add table
Reference in a new issue