diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 8ed85e611a6..e0124597d36 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -940,7 +940,7 @@ grant update,select(b) on mysqltest.t2 to mysqltest_1@localhost; create view v4 as select b+1 from mysqltest.t2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; drop database mysqltest; -drop view v1,v2; +drop view v1,v2,v4; set sql_mode='ansi'; create table t1 ("a*b" int); create view v1 as select "a*b" from t1; @@ -1040,7 +1040,6 @@ CREATE VIEW v02 AS SELECT * FROM DUAL; ERROR HY000: No tables used SHOW TABLES; Tables_in_test table_type -v4 VIEW CREATE VIEW v1 AS SELECT EXISTS (SELECT 1 UNION SELECT 2); select * from v1; EXISTS (SELECT 1 UNION SELECT 2) @@ -1202,3 +1201,19 @@ select * from v1; 5 drop view v1; drop table t1; +create function x1 () returns int return 5; +create table t1 (s1 int); +create view v1 as select x1() from t1; +drop function x1; +select * from v1; +ERROR 42000: FUNCTION test.x1 does not exist +show table status; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL +v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view +show table status; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL +v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view +drop view v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 3bb995f8022..690c4e0d64c 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -849,7 +849,7 @@ create view v4 as select b+1 from mysqltest.t2; connection root; REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; drop database mysqltest; -drop view v1,v2; +drop view v1,v2,v4; # # VIEW fields quoting @@ -1145,3 +1145,19 @@ create view v1 as select 5 from t1 order by 1; select * from v1; drop view v1; drop table t1; + +# +# VIEW over droped function +# +create function x1 () returns int return 5; +create table t1 (s1 int); +create view v1 as select x1() from t1; +drop function x1; +-- error 1304 +select * from v1; +--replace_column 12 # 13 # +show table status; +--replace_column 12 # 13 # +show table status; +drop view v1; +drop table t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index b5af98b6caf..f9ab1886a23 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3270,7 +3270,7 @@ Item_func_sp::Item_func_sp(sp_name *name, List &list) const char * Item_func_sp::func_name() const { - THD * thd= current_thd; + THD *thd= current_thd; /* Calculate length to avoud reallocation of string for sure */ uint len= ((m_name->m_db.length + m_name->m_name.length)*2 + //characters*quoting @@ -3280,6 +3280,7 @@ Item_func_sp::func_name() const ALIGN_SIZE(1)); // to avoid String reallocation String qname((char *)alloc_root(&thd->mem_root, len), len, system_charset_info); + qname.length(0); append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length); qname.append('.'); diff --git a/sql/sp.cc b/sql/sp.cc index b881eeb78d9..a69f18e10be 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -93,10 +93,15 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, key[128]= type; keylen= sizeof(key); - for (table= thd->open_tables ; table ; table= table->next) - if (strcmp(table->table_cache_key, "mysql") == 0 && - strcmp(table->real_name, "proc") == 0) - break; + if (thd->lex->proc_table) + table= thd->lex->proc_table->table; + else + { + for (table= thd->open_tables ; table ; table= table->next) + if (strcmp(table->table_cache_key, "mysql") == 0 && + strcmp(table->real_name, "proc") == 0) + break; + } if (table) *opened= FALSE; else @@ -954,6 +959,7 @@ sp_cache_functions(THD *thd, LEX *lex) LEX *newlex= new st_lex; thd->lex= newlex; + newlex->proc_table= oldlex->proc_table; // hint if mysql.oper is opened name.m_name.str= strchr(name.m_qname.str, '.'); name.m_db.length= name.m_name.str - name.m_qname.str; name.m_db.str= strmake_root(&thd->mem_root, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 84b5cf3454b..1c479444485 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -641,6 +641,7 @@ typedef struct st_lex TABLE_LIST *query_tables; /* global list of all tables in this query */ /* last element next_global of previous list */ TABLE_LIST **query_tables_last; + TABLE_LIST *proc_table; /* refer to mysql.proc if it was opened by VIEW */ List col_list; List ref_list; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 54156459f86..d0ac3cfbc6a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4246,7 +4246,7 @@ mysql_init_query(THD *thd, uchar *buf, uint length, bool lexonly) lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; - lex->query_tables= 0; + lex->proc_table= lex->query_tables= 0; lex->query_tables_last= &lex->query_tables; lex->variables_used= 0; lex->select_lex.parent_lex= lex; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 3f0e0db1724..17c5951d5cd 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -520,6 +520,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, my_bool mysql_make_view(File_parser *parser, TABLE_LIST *table) { + bool include_proc_table= 0; DBUG_ENTER("mysql_make_view"); if (table->view) @@ -612,10 +613,25 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) table->belong_to_view : table); - /* move SP to main LEX */ - sp_merge_funs(old_lex, lex); - if (lex->spfuns.array.buffer) - hash_free(&lex->spfuns); + if (lex->spfuns.records) + { + /* move SP to main LEX */ + sp_merge_funs(old_lex, lex); + if (lex->spfuns.array.buffer) + hash_free(&lex->spfuns); + if (old_lex->proc_table == 0 && + (old_lex->proc_table= + (TABLE_LIST*)thd->calloc(sizeof(TABLE_LIST))) != 0) + { + TABLE_LIST *table= old_lex->proc_table; + table->db= (char*)"mysql"; + table->db_length= 5; + table->real_name= table->alias= (char*)"proc"; + table->real_name_length= 4; + table->cacheable_table= 1; + include_proc_table= 1; + } + } old_next= table->next_global; if ((table->next_global= lex->query_tables)) @@ -742,6 +758,17 @@ ok: lex->all_selects_list->link_prev= (st_select_lex_node**)&old_lex->all_selects_list; + if (include_proc_table) + { + TABLE_LIST *proc= old_lex->proc_table; + if((proc->next_global= table->next_global)) + { + table->next_global->prev_global= &proc->next_global; + } + proc->prev_global= &table->next_global; + table->next_global= proc; + } + thd->lex= old_lex; DBUG_RETURN(0);