From 6105040ac46a33970119f863ce3bdf97704312d3 Mon Sep 17 00:00:00 2001 From: "anozdrin@mysql.com" <> Date: Tue, 25 Oct 2005 00:54:04 +0400 Subject: [PATCH] Fix for BUG#13095: Cannot create VIEWs in prepared statements - allow CREATE VIEW as well as DROP VIEW to use in prepared statements; - fix CREATE VIEW implementation to make it work in prepared statements. --- mysql-test/r/sp.result | 43 ++++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 56 ++++++++++++++++++++++++++++++++++++++++++ sql/sql_lex.h | 1 + sql/sql_prepare.cc | 2 ++ sql/sql_view.cc | 3 ++- sql/sql_yacc.yy | 2 ++ 6 files changed, 106 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 7fdbeff9a86..f91aadc02b6 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3532,4 +3532,47 @@ select @a| Local drop function bug13941| drop procedure bug13941| +DROP PROCEDURE IF EXISTS bug13095; +DROP TABLE IF EXISTS bug13095_t1; +DROP VIEW IF EXISTS bug13095_v1; +CREATE PROCEDURE bug13095(tbl_name varchar(32)) +BEGIN +SET @str = +CONCAT("CREATE TABLE ", tbl_name, "(stuff char(15))"); +SELECT @str; +PREPARE stmt FROM @str; +EXECUTE stmt; +SET @str = +CONCAT("INSERT INTO ", tbl_name, " VALUES('row1'),('row2'),('row3')" ); +SELECT @str; +PREPARE stmt FROM @str; +EXECUTE stmt; +SET @str = +CONCAT("CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM ", tbl_name); +SELECT @str; +PREPARE stmt FROM @str; +EXECUTE stmt; +SELECT * FROM bug13095_v1; +SET @str = +"DROP VIEW bug13095_v1"; +SELECT @str; +PREPARE stmt FROM @str; +EXECUTE stmt; +END| +CALL bug13095('bug13095_t1'); +@str +CREATE TABLE bug13095_t1(stuff char(15)) +@str +INSERT INTO bug13095_t1 VALUES('row1'),('row2'),('row3') +@str +CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM bug13095_t1 +c1 +row1 +row2 +row3 +@str +DROP VIEW bug13095_v1 +DROP PROCEDURE IF EXISTS bug13095; +DROP VIEW IF EXISTS bug13095_v1; +DROP TABLE IF EXISTS bug13095_t1; drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 18607c7f13c..ab57139bb77 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4433,6 +4433,62 @@ drop function bug13941| drop procedure bug13941| +# +# BUG#13095: Cannot create VIEWs in prepared statements +# + +delimiter ;| + +--disable_warnings +DROP PROCEDURE IF EXISTS bug13095; +DROP TABLE IF EXISTS bug13095_t1; +DROP VIEW IF EXISTS bug13095_v1; +--enable_warnings + +delimiter |; + +CREATE PROCEDURE bug13095(tbl_name varchar(32)) +BEGIN + SET @str = + CONCAT("CREATE TABLE ", tbl_name, "(stuff char(15))"); + SELECT @str; + PREPARE stmt FROM @str; + EXECUTE stmt; + + SET @str = + CONCAT("INSERT INTO ", tbl_name, " VALUES('row1'),('row2'),('row3')" ); + SELECT @str; + PREPARE stmt FROM @str; + EXECUTE stmt; + + SET @str = + CONCAT("CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM ", tbl_name); + SELECT @str; + PREPARE stmt FROM @str; + EXECUTE stmt; + + SELECT * FROM bug13095_v1; + + SET @str = + "DROP VIEW bug13095_v1"; + SELECT @str; + PREPARE stmt FROM @str; + EXECUTE stmt; +END| + +delimiter ;| + +CALL bug13095('bug13095_t1'); + +--disable_warnings +DROP PROCEDURE IF EXISTS bug13095; +DROP VIEW IF EXISTS bug13095_v1; +DROP TABLE IF EXISTS bug13095_t1; +--enable_warnings + +delimiter |; + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 1e935c6dc2a..1bf346eafb1 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -738,6 +738,7 @@ typedef struct st_lex /* store original leaf_tables for INSERT SELECT and PS/SP */ TABLE_LIST *leaf_tables_insert; st_lex_user *create_view_definer; + char *create_view_start; char *create_view_select_start; List col_list; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 5f3539ca1e9..865c597e00d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1742,6 +1742,8 @@ static bool check_prepared_statement(Prepared_statement *stmt, case SQLCOM_ROLLBACK: case SQLCOM_TRUNCATE: case SQLCOM_CALL: + case SQLCOM_CREATE_VIEW: + case SQLCOM_DROP_VIEW: break; default: diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 5db08275735..858f0c2520e 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -643,7 +643,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->query.length= str.length()-1; // we do not need last \0 view->source.str= thd->lex->create_view_select_start; view->source.length= (thd->query_length - - (thd->lex->create_view_select_start - thd->query)); + (thd->lex->create_view_select_start - + thd->lex->create_view_start)); view->file_version= 1; view->calc_md5(md5); view->md5.str= md5; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 94ce04fb5b1..670385dee93 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1263,6 +1263,7 @@ create: THD *thd= YYTHD; LEX *lex= thd->lex; lex->sql_command= SQLCOM_CREATE_VIEW; + lex->create_view_start= thd->query; /* first table in list is target VIEW name */ if (!lex->select_lex.add_table_to_list(thd, $7, NULL, 0)) YYABORT; @@ -3425,6 +3426,7 @@ alter: THD *thd= YYTHD; LEX *lex= thd->lex; lex->sql_command= SQLCOM_CREATE_VIEW; + lex->create_view_start= thd->query; lex->create_view_mode= VIEW_ALTER; /* first table in list is target VIEW name */ lex->select_lex.add_table_to_list(thd, $6, NULL, 0);