Commit c779905f authored by unknown's avatar unknown

Merge of LP BUG#872775 fix

parents 7755bd9f 71dda97a
drop table if exists t1,t2,t3,t4,t5;
drop view if exists v1;
set optimizer_switch='subquery_cache=on'; set optimizer_switch='subquery_cache=on';
create table t1 (a int, b int); create table t1 (a int, b int);
insert into t1 values (1,2),(3,4),(1,2),(3,4),(3,4),(4,5),(4,5),(5,6),(5,6),(4,5); insert into t1 values (1,2),(3,4),(1,2),(3,4),(3,4),(4,5),(4,5),(5,6),(5,6),(4,5);
...@@ -3354,5 +3356,31 @@ f1 f2 f3 f3 ...@@ -3354,5 +3356,31 @@ f1 f2 f3 f3
7 0 0 0 7 0 0 0
7 0 0 0 7 0 0 0
drop tables t1, t2, t3; drop tables t1, t2, t3;
#
# Test of LP BUG#872775 view with "outer references" bug
#
set @@optimizer_switch= default;
set optimizer_switch='subquery_cache=on';
CREATE TABLE t1 (a int) ;
CREATE TABLE t2 (b int, c varchar(1) NOT NULL ) ;
INSERT INTO t2 VALUES (1,'x'),(2,'y');
CREATE TABLE t3 (a int) ;
CREATE TABLE t4 ( pk int(11) NOT NULL , b int(11) NOT NULL ) ;
INSERT INTO t4 VALUES (26,9),(27,5),(28,0),(29,3);
CREATE OR REPLACE VIEW v1 AS
SELECT t2.b
FROM t1
JOIN t2
WHERE t2 .c > (
SELECT t2.c FROM t3
);
SELECT * FROM t4 WHERE b NOT IN ( SELECT * FROM v1 );
pk b
26 9
27 5
28 0
29 3
drop view v1;
drop table t1,t2,t3,t4;
# restore default # restore default
set @@optimizer_switch= default; set @@optimizer_switch= default;
--disable_warnings
drop table if exists t1,t2,t3,t4,t5;
drop view if exists v1;
--enable_warnings
set optimizer_switch='subquery_cache=on'; set optimizer_switch='subquery_cache=on';
create table t1 (a int, b int); create table t1 (a int, b int);
...@@ -1664,5 +1670,33 @@ FROM t1 ...@@ -1664,5 +1670,33 @@ FROM t1
WHERE t2.f1 OR t2.f3 ); WHERE t2.f1 OR t2.f3 );
drop tables t1, t2, t3; drop tables t1, t2, t3;
--echo #
--echo # Test of LP BUG#872775 view with "outer references" bug
--echo #
set @@optimizer_switch= default;
set optimizer_switch='subquery_cache=on';
CREATE TABLE t1 (a int) ;
CREATE TABLE t2 (b int, c varchar(1) NOT NULL ) ;
INSERT INTO t2 VALUES (1,'x'),(2,'y');
CREATE TABLE t3 (a int) ;
CREATE TABLE t4 ( pk int(11) NOT NULL , b int(11) NOT NULL ) ;
INSERT INTO t4 VALUES (26,9),(27,5),(28,0),(29,3);
CREATE OR REPLACE VIEW v1 AS
SELECT t2.b
FROM t1
JOIN t2
WHERE t2 .c > (
SELECT t2.c FROM t3
);
SELECT * FROM t4 WHERE b NOT IN ( SELECT * FROM v1 );
drop view v1;
drop table t1,t2,t3,t4;
--echo # restore default --echo # restore default
set @@optimizer_switch= default; set @@optimizer_switch= default;
...@@ -755,7 +755,9 @@ bool Item_ident::remove_dependence_processor(uchar * arg) ...@@ -755,7 +755,9 @@ bool Item_ident::remove_dependence_processor(uchar * arg)
bool Item_ident::collect_outer_ref_processor(uchar *param) bool Item_ident::collect_outer_ref_processor(uchar *param)
{ {
Collect_deps_prm *prm= (Collect_deps_prm *)param; Collect_deps_prm *prm= (Collect_deps_prm *)param;
if (depended_from && depended_from->nest_level < prm->nest_level) if (depended_from &&
depended_from->nest_level_base == prm->nest_level_base &&
depended_from->nest_level < prm->nest_level)
prm->parameters->add_unique(this, &cmp_items); prm->parameters->add_unique(this, &cmp_items);
return FALSE; return FALSE;
} }
......
...@@ -505,6 +505,7 @@ typedef void (*Cond_traverser) (const Item *item, void *arg); ...@@ -505,6 +505,7 @@ typedef void (*Cond_traverser) (const Item *item, void *arg);
class Item_equal; class Item_equal;
class COND_EQUAL; class COND_EQUAL;
class st_select_lex_unit;
class Item { class Item {
Item(const Item &); /* Prevent use of these */ Item(const Item &); /* Prevent use of these */
...@@ -1159,8 +1160,10 @@ class Item { ...@@ -1159,8 +1160,10 @@ class Item {
} }
struct Collect_deps_prm struct Collect_deps_prm
{ {
int nest_level;
List<Item> *parameters; List<Item> *parameters;
/* unit from which we count nest_level */
st_select_lex_unit *nest_level_base;
int nest_level;
}; };
/** /**
Collect outer references Collect outer references
......
...@@ -599,7 +599,9 @@ bool Item_subselect::exec() ...@@ -599,7 +599,9 @@ bool Item_subselect::exec()
void Item_subselect::get_cache_parameters(List<Item> &parameters) void Item_subselect::get_cache_parameters(List<Item> &parameters)
{ {
Collect_deps_prm prm= { unit->first_select()->nest_level, &parameters }; Collect_deps_prm prm= {&parameters,
unit->first_select()->nest_level_base,
unit->first_select()->nest_level};
walk(&Item::collect_outer_ref_processor, TRUE, (uchar*)&prm); walk(&Item::collect_outer_ref_processor, TRUE, (uchar*)&prm);
} }
......
...@@ -359,7 +359,9 @@ bool Item_sum::collect_outer_ref_processor(uchar *param) ...@@ -359,7 +359,9 @@ bool Item_sum::collect_outer_ref_processor(uchar *param)
{ {
Collect_deps_prm *prm= (Collect_deps_prm *)param; Collect_deps_prm *prm= (Collect_deps_prm *)param;
SELECT_LEX *ds; SELECT_LEX *ds;
if ((ds= depended_from()) && ds->nest_level < prm->nest_level) if ((ds= depended_from()) &&
ds->nest_level_base == prm->nest_level_base &&
ds->nest_level < prm->nest_level)
prm->parameters->add_unique(this, &cmp_items); prm->parameters->add_unique(this, &cmp_items);
return FALSE; return FALSE;
} }
......
...@@ -339,6 +339,7 @@ void lex_start(THD *thd) ...@@ -339,6 +339,7 @@ void lex_start(THD *thd)
lex->event_parse_data= NULL; lex->event_parse_data= NULL;
lex->profile_options= PROFILE_NONE; lex->profile_options= PROFILE_NONE;
lex->nest_level=0 ; lex->nest_level=0 ;
lex->select_lex.nest_level_base= &lex->unit;
lex->allow_sum_func= 0; lex->allow_sum_func= 0;
lex->in_sum_func= NULL; lex->in_sum_func= NULL;
lex->protect_against_global_read_lock= FALSE; lex->protect_against_global_read_lock= FALSE;
......
...@@ -684,6 +684,13 @@ class st_select_lex: public st_select_lex_node ...@@ -684,6 +684,13 @@ class st_select_lex: public st_select_lex_node
ulong table_join_options; ulong table_join_options;
uint in_sum_expr; uint in_sum_expr;
uint select_number; /* number of select (used for EXPLAIN) */ uint select_number; /* number of select (used for EXPLAIN) */
/*
nest_levels are local to the query or VIEW,
and that view merge procedure does not re-calculate them.
So we also have to remember unit against which we count levels.
*/
SELECT_LEX_UNIT *nest_level_base;
int nest_level; /* nesting level of select */ int nest_level; /* nesting level of select */
Item_sum *inner_sum_func_list; /* list of sum func in nested selects */ Item_sum *inner_sum_func_list; /* list of sum func in nested selects */
uint with_wild; /* item list contain '*' */ uint with_wild; /* item list contain '*' */
......
...@@ -5917,6 +5917,7 @@ mysql_new_select(LEX *lex, bool move_down) ...@@ -5917,6 +5917,7 @@ mysql_new_select(LEX *lex, bool move_down)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
select_lex->nest_level= lex->nest_level; select_lex->nest_level= lex->nest_level;
select_lex->nest_level_base= &thd->lex->unit;
if (move_down) if (move_down)
{ {
SELECT_LEX_UNIT *unit; SELECT_LEX_UNIT *unit;
......
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