Commit c3389776 authored by unknown's avatar unknown

adding mysql.proc to table list if view contains stored procedures (BUG#5151)


mysql-test/r/view.result:
  fixed test
  VIEW over droped function
mysql-test/t/view.test:
  VIEW over droped function
sql/item_func.cc:
  after review fix
sql/sp.cc:
  hint to find mysql.proc
sql/sql_lex.h:
  hint to find mysql.proc
sql/sql_parse.cc:
  hint to find mysql.proc
sql/sql_view.cc:
  adding mysql.proc to table list if view contains stored procedures
parent d3423ca6
......@@ -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;
......@@ -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;
......@@ -3270,7 +3270,7 @@ Item_func_sp::Item_func_sp(sp_name *name, List<Item> &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('.');
......
......@@ -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,
......
......@@ -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<key_part_spec> col_list;
List<key_part_spec> ref_list;
......
......@@ -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;
......
......@@ -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 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
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);
......
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