diff options
-rw-r--r-- | sql/item.h | 4 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/sp_head.cc | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 25 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_handler.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 14 |
7 files changed, 20 insertions, 31 deletions
diff --git a/sql/item.h b/sql/item.h index 6a1490a19d5..de292279e06 100644 --- a/sql/item.h +++ b/sql/item.h @@ -716,10 +716,6 @@ public: void cleanup(); bool remove_dependence_processor(byte * arg); void print(String *str); - - friend bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, - const char *table_name, List_iterator<Item> *it, - bool any_privileges, bool allocate_view_names); }; class Item_equal; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index dad524b4e53..2add9ac9269 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -894,8 +894,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, List<String> *index_list); bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, - List_iterator<Item> *it, bool any_privileges, - bool allocate_view_names); + List_iterator<Item> *it, bool any_privileges); bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds, TABLE_LIST **leaves, bool select_insert); int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ee824085df6..fae657a8caf 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -682,6 +682,7 @@ sp_head::execute(THD *thd) cleanup_items(thd->current_arena->free_list); thd->current_arena= old_arena; + state= EXECUTED; done: DBUG_PRINT("info", ("ret=%d killed=%d query_error=%d", diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8f83208f44b..fee3bdfeb5f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3051,7 +3051,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, } else if (insert_fields(thd,tables,((Item_field*) item)->db_name, ((Item_field*) item)->table_name, &it, - any_privileges, arena != 0)) + any_privileges)) { if (arena) thd->restore_backup_item_arena(arena, &backup); @@ -3304,8 +3304,6 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, any_privileges 0 If we should ensure that we have SELECT privileges for all columns 1 If any privilege is ok - allocate_view_names if true view names will be copied to current Query_arena - memory (made for SP/PS) RETURN 0 ok 'it' is updated to point at last inserted @@ -3315,7 +3313,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, bool insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator<Item> *it, - bool any_privileges, bool allocate_view_names) + bool any_privileges) { /* allocate variables on stack to avoid pool alloaction */ Field_iterator_table table_iter; @@ -3506,25 +3504,6 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, field->query_id=thd->query_id; table->used_keys.intersect(field->part_of_key); } - else if (allocate_view_names && - thd->lex->current_select->first_execution) - { - Item_field *item; - if (alias_used) - item= new Item_field(0, - thd->strdup(tables->alias), - thd->strdup(field_name)); - else - item= new Item_field(thd->strdup(tables->view_db.str), - thd->strdup(tables->view_name.str), - thd->strdup(field_name)); - /* - during cleunup() this item will be put in list to replace - expression from VIEW - */ - thd->nocheck_register_item_tree_change(it->ref(), item, - thd->mem_root); - } } /* All fields are used in case if usual tables (in case of view used diff --git a/sql/sql_class.h b/sql/sql_class.h index bee04303460..dd4b8310e51 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -699,6 +699,8 @@ public: virtual ~Query_arena() {}; inline bool is_stmt_prepare() const { return state == INITIALIZED; } + inline bool is_first_sp_execute() const + { return state == INITIALIZED_FOR_SP; } inline bool is_stmt_prepare_or_first_sp_execute() const { return (int)state < (int)PREPARED; } inline bool is_first_stmt_execute() const { return state == PREPARED; } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 9356ee04c45..e905f93b860 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -422,7 +422,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, } } - if (insert_fields(thd, tables, tables->db, tables->alias, &it, 0, 0)) + if (insert_fields(thd, tables, tables->db, tables->alias, &it, 0)) goto err0; protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 052873640c6..a9bfb6da926 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -530,7 +530,19 @@ public: query processing end even if we use temporary table */ bool subquery_in_having; - bool first_execution; /* first execution in SP or PS */ + /* + This variable is required to ensure proper work of subqueries and + stored procedures. Generally, one should use the states of + Query_arena to determine if it's a statement prepare or first + execution of a stored procedure. However, in case when there was an + error during the first execution of a stored procedure, the SP body + is not expelled from the SP cache. Therefore, a deeply nested + subquery might be left unoptimized. So we need this per-subquery + variable to inidicate the optimization/execution state of every + subquery. Prepared statements work OK in that regard, as in + case of an error during prepare the PS is not created. + */ + bool first_execution; bool first_cond_optimization; /* do not wrap view fields with Item_ref */ bool no_wrap_view_item; |