diff options
author | unknown <konstantin@mysql.com> | 2005-06-08 00:34:53 +0400 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2005-06-08 00:34:53 +0400 |
commit | 936688feb5638a8e11d0de363a05eaced99abdd5 (patch) | |
tree | 45fafa0273fdf02d6120d49c8ab078c18fe54107 | |
parent | 0bc3c6221cbaae56ba444e06603c4afbf11f685e (diff) | |
download | mariadb-git-936688feb5638a8e11d0de363a05eaced99abdd5.tar.gz |
A followup patch for Bug#7306 (limit in prepared statements):
don't evaluate subqueries during statement prepare, even if they
are not correlated.
With post-review fixes.
sql/mysql_priv.h:
Add UNCACHEABLE_PREPARE to mark subqueries as non-constant in
mysql_stmt_prepare
sql/sql_lex.cc:
Add a missing assert: noone can call unit::set_limit from
mysql_stmt_prepare.
sql/sql_lex.h:
Comment fixed.
sql/sql_parse.cc:
Mark new SELECT_LEXes as uncacheable if they created during
statement prepare.
sql/sql_prepare.cc:
Switch off the uncacheable flag when prepare is done.
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 14 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 3 |
5 files changed, 15 insertions, 6 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index e8ec1b69959..338e45fa058 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -336,6 +336,8 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define UNCACHEABLE_SIDEEFFECT 4 // forcing to save JOIN for explain #define UNCACHEABLE_EXPLAIN 8 +/* Don't evaluate subqueries in prepare even if they're not correlated */ +#define UNCACHEABLE_PREPARE 16 #ifdef EXTRA_DEBUG /* diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 6b9330182d6..1270aab18ae 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1757,6 +1757,7 @@ void st_select_lex_unit::set_limit(SELECT_LEX *sl) { ulonglong select_limit_val; + DBUG_ASSERT(! thd->current_arena->is_stmt_prepare()); select_limit_val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR; offset_limit_cnt= sl->offset_limit ? sl->offset_limit->val_uint() : ULL(0); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5022392565c..a6f729d7677 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -303,6 +303,7 @@ public: UNCACHEABLE_RAND UNCACHEABLE_SIDEEFFECT UNCACHEABLE_EXPLAIN + UNCACHEABLE_PREPARE */ uint8 uncacheable; enum sub_select_type linkage; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7d00cfa4c98..f48bc3713e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5169,26 +5169,28 @@ bool mysql_new_select(LEX *lex, bool move_down) { SELECT_LEX *select_lex; - THD *thd; + THD *thd= lex->thd; DBUG_ENTER("mysql_new_select"); - if (!(select_lex= new(lex->thd->mem_root) SELECT_LEX())) + if (!(select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); - select_lex->select_number= ++lex->thd->select_number; + select_lex->select_number= ++thd->select_number; select_lex->init_query(); select_lex->init_select(); select_lex->parent_lex= lex; + if (thd->current_arena->is_stmt_prepare()) + select_lex->uncacheable|= UNCACHEABLE_PREPARE; if (move_down) { SELECT_LEX_UNIT *unit; lex->subqueries= TRUE; /* first select_lex of subselect or derived table */ - if (!(unit= new(lex->thd->mem_root) SELECT_LEX_UNIT())) + if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT())) DBUG_RETURN(1); unit->init_query(); unit->init_select(); - unit->thd= lex->thd; + unit->thd= thd; unit->include_down(lex->current_select); unit->link_next= 0; unit->link_prev= 0; @@ -5212,7 +5214,7 @@ mysql_new_select(LEX *lex, bool move_down) as far as we included SELECT_LEX for UNION unit should have fake SELECT_LEX for UNION processing */ - if (!(fake= unit->fake_select_lex= new(lex->thd->mem_root) SELECT_LEX())) + if (!(fake= unit->fake_select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); fake->include_standalone(unit, (SELECT_LEX_NODE**)&unit->fake_select_lex); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1521b206e0d..4440e542434 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1838,7 +1838,10 @@ void init_stmt_after_parse(THD *thd, LEX *lex) optimisation. */ for (; sl; sl= sl->next_select_in_list()) + { sl->prep_where= sl->where; + sl->uncacheable&= ~UNCACHEABLE_PREPARE; + } for (TABLE_LIST *table= lex->query_tables; table; table= table->next_global) table->prep_on_expr= table->on_expr; |