From 099be80130d852179bc4a568990c75ffc950719f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Jun 2007 11:55:48 +0200 Subject: [PATCH 1/4] Bug#28846 Use of undocumented Prepared Statements crashes server ALTER VIEW is currently not supported as a prepared statement and should be disabled as such as they otherwise could cause server crashes. ALTER VIEW is currently not supported when called from stored procedures or functions for related reasons and should also be disabled. This patch disables these DDL statements and adjusts the appropriate test cases accordingly. Additional tests has been added to reflect on the fact that we do support CREATE/ALTER/DROP TABLE for Prepared Statements (PS), Stored Procedures (SP) and PS within SP. mysql-test/r/ps_1general.result: - Updated test to reflect on the new policy to disallow ALTER VIEW within SP. mysql-test/r/sp-dynamic.result: - Added PS ALTER TABLE test from within SP-context to demonstrate that CREATE/ALTER/DROP TABLE statements is working. - Added PS CREATE/ALTER/DROP VIEW tests from within SP-context to show that ALTER VIEW is not supported, CREATE VIEW/DROP VIEW are supported. mysql-test/r/sp-error.result: - Updated test to reflect on the new policy to disallow VIEW DDL within SP. mysql-test/t/ps_1general.test: - Updated test to reflect on the new policy to disallow VIEW DDL within SP. mysql-test/t/sp-dynamic.test: - Add PS ALTER TABLE test from within SP to demonstrate that CREATE/ALTER/DROP TABLE statements are supported. mysql-test/t/sp-error.test: - Updated test to reflect on the new policy to disallow ALTER VIEW within SP-context. - Changed error code 1314 to the more abstract ER_SP_BADSTATEMENT. sql/sql_class.h: - Added comment for clarity sql/sql_parse.cc: - Added comment for clarity sql/sql_prepare.cc: - Disallow ALTER VIEW as prepared statements until they are properly supported. Note that SQLCOM_CREATE_VIEW also handles ALTER VIEW statements. sql/sql_view.cc: - converted to doxygen comments - Added comment for clarity sql/sql_yacc.yy: - Disallow ALTER VIEW statements within a SP. If the parser is operating within the SP context, this is shown on the sp->sphead pointer. If this flag is set for view DDL operations we stop parsing with the error 'ER_SP_BAD_STATEMENT'. --- mysql-test/r/ps_1general.result | 2 ++ mysql-test/r/sp-dynamic.result | 18 +++++++++++++++++- mysql-test/r/sp-error.result | 4 ++-- mysql-test/t/ps_1general.test | 4 ++++ mysql-test/t/sp-dynamic.test | 12 ++++++++++-- mysql-test/t/sp-error.test | 10 +++++----- sql/sql_class.h | 7 +++++++ sql/sql_parse.cc | 4 ++++ sql/sql_prepare.cc | 8 +++++++- sql/sql_view.cc | 19 +++++++++---------- sql/sql_yacc.yy | 5 +++++ 11 files changed, 72 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index df4ec793325..5ea6a758d42 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -396,6 +396,8 @@ prepare stmt1 from ' execute stmt2 ' ; ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' deallocate prepare never_prepared ' ; ERROR HY000: This command is not supported in the prepared statement protocol yet +prepare stmt1 from 'alter view v1 as select 2'; +ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt4 from ' use test ' ; ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt3 from ' create database mysqltest '; diff --git a/mysql-test/r/sp-dynamic.result b/mysql-test/r/sp-dynamic.result index d9d5706cded..0f50bcc97cd 100644 --- a/mysql-test/r/sp-dynamic.result +++ b/mysql-test/r/sp-dynamic.result @@ -87,6 +87,10 @@ prepare stmt from "create table t1 (a int)"; execute stmt; insert into t1 (a) values (1); select * from t1; +prepare stmt_alter from "alter table t1 add (b int)"; +execute stmt_alter; +insert into t1 (a,b) values (2,1); +deallocate prepare stmt_alter; deallocate prepare stmt; deallocate prepare stmt_drop; end| @@ -245,6 +249,9 @@ a 1 drop procedure p1| drop table if exists t1| +drop table if exists t2| +Warnings: +Note 1051 Unknown table 't2' create table t1 (id integer primary key auto_increment, stmt_text char(35), status varchar(20))| insert into t1 (stmt_text) values @@ -255,7 +262,10 @@ insert into t1 (stmt_text) values ("help help"), ("show databases"), ("show tables"), ("show table status"), ("show open tables"), ("show storage engines"), ("insert into t1 (id) values (1)"), ("update t1 set status=''"), -("delete from t1"), ("truncate t1"), ("call p1()"), ("foo bar")| +("delete from t1"), ("truncate t1"), ("call p1()"), ("foo bar"), +("create view v1 as select 1"), ("alter view v1 as select 2"), +("drop view v1"),("create table t2 (a int)"),("alter table t2 add (b int)"), +("drop table t2")| create procedure p1() begin declare v_stmt_text varchar(255); @@ -305,6 +315,12 @@ id stmt_text status 20 truncate t1 supported 21 call p1() supported 22 foo bar syntax error +23 create view v1 as select 1 supported +24 alter view v1 as select 2 not supported +25 drop view v1 supported +26 create table t2 (a int) supported +27 alter table t2 add (b int) supported +28 drop table t2 supported drop procedure p1| drop table t1| prepare stmt from 'select 1'| diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 7a2f812cde4..bd0640b2b14 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -982,9 +982,9 @@ ERROR HY000: Explicit or implicit commit is not allowed in stored function or tr CREATE FUNCTION bug_13627_f() returns int BEGIN create view v1 as select 1; return 1; END | ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN alter view v1 as select 1; END | -ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +ERROR 0A000: ALTER VIEW is not allowed in stored procedures CREATE FUNCTION bug_13627_f() returns int BEGIN alter view v1 as select 1; return 1; END | -ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +ERROR 0A000: ALTER VIEW is not allowed in stored procedures CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop view v1; END | ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. CREATE FUNCTION bug_13627_f() returns int BEGIN drop view v1; return 1; END | diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 2e7fea2ff3d..952931f2ad1 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -423,6 +423,10 @@ prepare stmt1 from ' execute stmt2 ' ; --error ER_UNSUPPORTED_PS prepare stmt1 from ' deallocate prepare never_prepared ' ; +## We don't support alter view as prepared statements +--error ER_UNSUPPORTED_PS +prepare stmt1 from 'alter view v1 as select 2'; + ## switch the database connection --error 1295 prepare stmt4 from ' use test ' ; diff --git a/mysql-test/t/sp-dynamic.test b/mysql-test/t/sp-dynamic.test index 6546a5ab548..e6f4aae96ac 100644 --- a/mysql-test/t/sp-dynamic.test +++ b/mysql-test/t/sp-dynamic.test @@ -85,7 +85,7 @@ call p1()| call p1()| drop procedure p1| # -# D. Create/Drop a table (a DDL that issues a commit) in Dynamic SQL. +# D. Create/Drop/Alter a table (a DDL that issues a commit) in Dynamic SQL. # (should work ok). # create procedure p1() @@ -96,6 +96,10 @@ begin execute stmt; insert into t1 (a) values (1); select * from t1; + prepare stmt_alter from "alter table t1 add (b int)"; + execute stmt_alter; + insert into t1 (a,b) values (2,1); + deallocate prepare stmt_alter; deallocate prepare stmt; deallocate prepare stmt_drop; end| @@ -239,6 +243,7 @@ drop procedure p1| # K. Use of continue handlers with Dynamic SQL. # drop table if exists t1| +drop table if exists t2| create table t1 (id integer primary key auto_increment, stmt_text char(35), status varchar(20))| insert into t1 (stmt_text) values @@ -249,7 +254,10 @@ insert into t1 (stmt_text) values ("help help"), ("show databases"), ("show tables"), ("show table status"), ("show open tables"), ("show storage engines"), ("insert into t1 (id) values (1)"), ("update t1 set status=''"), - ("delete from t1"), ("truncate t1"), ("call p1()"), ("foo bar")| + ("delete from t1"), ("truncate t1"), ("call p1()"), ("foo bar"), + ("create view v1 as select 1"), ("alter view v1 as select 2"), + ("drop view v1"),("create table t2 (a int)"),("alter table t2 add (b int)"), + ("drop table t2")| create procedure p1() begin declare v_stmt_text varchar(255); diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index ec91be13ba0..240cda67edc 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -1087,12 +1087,12 @@ delimiter ;| # # BUG 12490 (Packets out of order if calling HELP CONTENTS from Stored Procedure) # ---error 1314 +--error ER_SP_BADSTATEMENT CREATE PROCEDURE BUG_12490() HELP CONTENTS; ---error 1314 +--error ER_SP_BADSTATEMENT CREATE FUNCTION BUG_12490() RETURNS INT HELP CONTENTS; CREATE TABLE t_bug_12490(a int); ---error 1314 +--error ER_SP_BADSTATEMENT CREATE TRIGGER BUG_12490 BEFORE UPDATE ON t_bug_12490 FOR EACH ROW HELP CONTENTS; DROP TABLE t_bug_12490; @@ -1397,9 +1397,9 @@ CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create view v1 as sele -- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG CREATE FUNCTION bug_13627_f() returns int BEGIN create view v1 as select 1; return 1; END | --- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG +-- error ER_SP_BADSTATEMENT CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN alter view v1 as select 1; END | --- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG +-- error ER_SP_BADSTATEMENT CREATE FUNCTION bug_13627_f() returns int BEGIN alter view v1 as select 1; return 1; END | -- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG diff --git a/sql/sql_class.h b/sql/sql_class.h index 62f4df0719f..c2e22a6fd8b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -697,6 +697,13 @@ public: #ifndef DBUG_OFF bool is_backup_arena; /* True if this arena is used for backup. */ #endif + /* + The states relfects three diffrent life cycles for three + different types of statements: + Prepared statement: INITIALIZED -> PREPARED -> EXECUTED. + Stored procedure: INITIALIZED_FOR_SP -> EXECUTED. + Other statements: CONVENTIONAL_EXECUTION never changes. + */ enum enum_state { INITIALIZED= 0, INITIALIZED_FOR_SP= 1, PREPARED= 2, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6277a6c0c10..923e019d982 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4876,6 +4876,10 @@ create_sp_error: #endif // ifndef DBUG_OFF case SQLCOM_CREATE_VIEW: { + /* + Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands + as specified through the thd->lex->create_view_mode flag. + */ if (end_active_trans(thd)) goto error; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 42655608196..4cdf54393de 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1727,6 +1727,13 @@ static bool check_prepared_statement(Prepared_statement *stmt, res= mysql_test_create_table(stmt); break; + case SQLCOM_CREATE_VIEW: + if (lex->create_view_mode == VIEW_ALTER) + { + my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0)); + goto error; + } + break; case SQLCOM_DO: res= mysql_test_do_fields(stmt, tables, lex->insert_list); break; @@ -1769,7 +1776,6 @@ 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: case SQLCOM_REPAIR: case SQLCOM_ANALYZE: diff --git a/sql/sql_view.cc b/sql/sql_view.cc index bfa799ff289..54bd248fabb 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -205,18 +205,17 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) } -/* - Creating/altering VIEW procedure +/** + @brief Creating/altering VIEW procedure - SYNOPSIS - mysql_create_view() - thd - thread handler - views - views to create - mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE + @param thd thread handler + @param views views to create + @param mode VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE - RETURN VALUE - FALSE OK - TRUE Error + @note This function handles both create and alter view commands. + + @retval FALSE Operation was a success. + @retval TRUE An error occured. */ bool mysql_create_view(THD *thd, TABLE_LIST *views, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b970bcaedd6..a3a9ead897e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3671,6 +3671,11 @@ alter: { THD *thd= YYTHD; LEX *lex= thd->lex; + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW"); + MYSQL_YYABORT; + } lex->sql_command= SQLCOM_CREATE_VIEW; lex->create_view_mode= VIEW_ALTER; /* first table in list is target VIEW name */ From 1eee6b138976188abf656e1c29246011efd1efa2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Jun 2007 15:38:23 +0200 Subject: [PATCH 2/4] Bug #28846 Use of undocumented Prepared Statements crashes server - Manual merge patch. sql/sql_yacc.yy: Corrected merge error. ALTER VIEW rules has been split in two and both rules need to be checked for SP-context. --- sql/sql_yacc.yy | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 235100af9a8..b81a075c38c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5187,6 +5187,12 @@ alter: */ { LEX *lex= Lex; + + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW"); + MYSQL_YYABORT; + } lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; lex->create_view_mode= VIEW_ALTER; } From a50a88e29c53cc09a3c17d437609a7e9183cae45 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Jun 2007 19:58:27 +0400 Subject: [PATCH 3/4] Fix broken automatic dependency tracking of Automake in sql/: The embedded library is still broken, but there the situation with dependencies is even more broken. sql/Makefile.am: Fix broken automatic dependency tracking of Automake in sql/: use a convenience library to specify additional includes that are required to compile files ha_ndbcluster_*, and then add this convenience library to the main project. The embedded library is still broken, but there the situation with dependencies is even more broken. --- sql/Makefile.am | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/sql/Makefile.am b/sql/Makefile.am index fdf3f88c1f8..12d8c8206b2 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -27,6 +27,10 @@ SUBDIRS = share libexec_PROGRAMS = mysqld EXTRA_PROGRAMS = gen_lex_hash bin_PROGRAMS = mysql_tzinfo_to_sql + +noinst_LTLIBRARIES= libndb.la \ + udf_example.la + SUPPORTING_LIBS = $(top_builddir)/vio/libvio.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ @@ -34,7 +38,8 @@ SUPPORTING_LIBS = $(top_builddir)/vio/libvio.a \ $(top_builddir)/strings/libmystrings.a mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@ -mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ +mysqld_LDADD = libndb.la \ + @MYSQLD_EXTRA_LDFLAGS@ \ @pstack_libs@ \ @mysql_plugin_libs@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \ @@ -93,8 +98,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ log_event_old.cc rpl_record_old.cc \ discover.cc time.cc opt_range.cc opt_sum.cc \ records.cc filesort.cc handler.cc \ - ha_ndbcluster.cc ha_ndbcluster_cond.cc \ - ha_ndbcluster_binlog.cc ha_partition.cc \ + ha_partition.cc \ sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \ sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ @@ -114,6 +118,11 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ sql_builtin.cc sql_tablespace.cc partition_info.cc \ sql_servers.cc +libndb_la_CPPFLAGS= @ndbcluster_includes@ +libndb_la_SOURCES= ha_ndbcluster.cc \ + ha_ndbcluster_binlog.cc \ + ha_ndbcluster_cond.cc + gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ @@ -157,22 +166,7 @@ lex_hash.h: gen_lex_hash.cc lex.h ./gen_lex_hash$(EXEEXT) > $@-t $(MV) $@-t $@ -# the following four should eventually be moved out of this directory -ha_ndbcluster.o:ha_ndbcluster.cc ha_ndbcluster.h - $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< - -ha_ndbcluster_cond.o:ha_ndbcluster_cond.cc ha_ndbcluster_cond.h - $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< - -ha_ndbcluster_binlog.o:ha_ndbcluster_binlog.cc ha_ndbcluster_binlog.h - $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< - -#Until we can get rid of dependencies on ha_ndbcluster.h -handler.o: handler.cc ha_ndbcluster.h - $(CXXCOMPILE) @ndbcluster_includes@ $(CXXFLAGS) -c $< - # For testing of udf_example.so -noinst_LTLIBRARIES= udf_example.la udf_example_la_SOURCES= udf_example.c udf_example_la_LDFLAGS= -module -rpath $(pkglibdir) From ba7e22dbe4acab510c78e163f1993fbf569b6f2d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 23 Jun 2007 19:16:51 +0200 Subject: [PATCH 4/4] Fix for BUG#29318 "Statements prepared with PREPARE and with one parameter don't use query cache" Thanks to the fix of BUG#26842, statements prepared with SQL PREPARE and having parameters can now use the query cache. mysql-test/include/query_cache_sql_prepare.inc: now, statements prepared with SQL PREPARE use the query cache even when they have parameters. mysql-test/r/query_cache_ps_no_prot.result: updated result: we see caching happened. mysql-test/r/query_cache_ps_ps_prot.result: updated result: we see caching happened sql/sql_prepare.cc: query expansion does not insert user variables' references anymore, it now inserts parameters' values (BUG#26842's fix did this); so we can use the query cache. --- .../include/query_cache_sql_prepare.inc | 12 +- mysql-test/r/query_cache_ps_no_prot.result | 189 ++++++++++-------- mysql-test/r/query_cache_ps_ps_prot.result | 189 ++++++++++-------- sql/sql_prepare.cc | 12 -- 4 files changed, 212 insertions(+), 190 deletions(-) diff --git a/mysql-test/include/query_cache_sql_prepare.inc b/mysql-test/include/query_cache_sql_prepare.inc index cdb3bd586e7..cf6d4c26959 100644 --- a/mysql-test/include/query_cache_sql_prepare.inc +++ b/mysql-test/include/query_cache_sql_prepare.inc @@ -33,7 +33,7 @@ drop table if exists t1; create table t1(c1 int); insert into t1 values(1),(10),(100); -# Prepared statements has no parameters, query caching should happen +# First, prepared statements with no parameters prepare stmt1 from "select * from t1 where c1=10"; show status like 'Qcache_hits'; execute stmt1; @@ -113,7 +113,9 @@ show status like 'Qcache_hits'; --echo ---- switch to connection default ---- connection default; -# Prepared statement has parameters, query caching should not happen +# Query caching also works when statement has parameters +# (BUG#29318 Statements prepared with PREPARE and with one parameter don't use +# query cache) prepare stmt1 from "select * from t1 where c1=?"; show status like 'Qcache_hits'; set @a=1; @@ -127,6 +129,12 @@ set @a=1; prepare stmt4 from "select * from t1 where c1=?"; execute stmt4 using @a; show status like 'Qcache_hits'; +# verify that presence of user variables forbids caching +prepare stmt4 from "select @a from t1 where c1=?"; +execute stmt4 using @a; +show status like 'Qcache_hits'; +execute stmt4 using @a; +show status like 'Qcache_hits'; --echo ---- switch to connection default ---- connection default; diff --git a/mysql-test/r/query_cache_ps_no_prot.result b/mysql-test/r/query_cache_ps_no_prot.result index bf162439918..29d16d8a619 100644 --- a/mysql-test/r/query_cache_ps_no_prot.result +++ b/mysql-test/r/query_cache_ps_no_prot.result @@ -144,7 +144,7 @@ c1 1 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 14 +Qcache_hits 15 ---- switch to connection con1 ---- set @a=1; prepare stmt4 from "select * from t1 where c1=?"; @@ -153,64 +153,38 @@ c1 1 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 14 +Qcache_hits 16 +prepare stmt4 from "select @a from t1 where c1=?"; +execute stmt4 using @a; +@a +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 16 +execute stmt4 using @a; +@a +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 16 ---- switch to connection default ---- prepare stmt1 from "select * from t1 where c1=10"; set global query_cache_size=0; show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 14 +Qcache_hits 16 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 14 +Qcache_hits 16 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 14 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 14 ----- switch to connection con1 ---- -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 14 -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 14 -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 14 ----- switch to connection default ---- -set global query_cache_size=100000; -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 14 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 15 +Qcache_hits 16 execute stmt1; c1 10 @@ -223,42 +197,39 @@ c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 16 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value +Qcache_hits 16 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 16 +---- switch to connection default ---- +set global query_cache_size=100000; +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 16 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value Qcache_hits 18 -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 19 ----- switch to connection default ---- -set global query_cache_size=0; -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 19 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 19 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 19 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 19 ---- switch to connection con1 ---- execute stmt3; c1 @@ -271,13 +242,55 @@ c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 20 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 +---- switch to connection default ---- +set global query_cache_size=0; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 21 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 21 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 21 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 21 +---- switch to connection con1 ---- +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 21 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 21 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 21 ---- switch to connection default ---- set global query_cache_size=0; prepare stmt1 from "select * from t1 where c1=10"; @@ -287,75 +300,75 @@ prepare stmt3 from "select * from t1 where c1=10"; set global query_cache_size=100000; show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 ---- switch to connection con1 ---- show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 ---- switch to connection default ---- set global query_cache_size=0; prepare stmt1 from "select * from t1 where c1=?"; set global query_cache_size=100000; show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 set @a=1; execute stmt1 using @a; c1 1 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 set @a=100; execute stmt1 using @a; c1 100 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 set @a=10; execute stmt1 using @a; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 19 +Qcache_hits 21 drop table t1; ---- disconnect connection con1 ---- set @@global.query_cache_size=@initial_query_cache_size; diff --git a/mysql-test/r/query_cache_ps_ps_prot.result b/mysql-test/r/query_cache_ps_ps_prot.result index 56aeda4a253..ba675d57f50 100644 --- a/mysql-test/r/query_cache_ps_ps_prot.result +++ b/mysql-test/r/query_cache_ps_ps_prot.result @@ -144,7 +144,7 @@ c1 1 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 12 +Qcache_hits 13 ---- switch to connection con1 ---- set @a=1; prepare stmt4 from "select * from t1 where c1=?"; @@ -153,64 +153,38 @@ c1 1 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 12 +Qcache_hits 14 +prepare stmt4 from "select @a from t1 where c1=?"; +execute stmt4 using @a; +@a +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt4 using @a; +@a +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 ---- switch to connection default ---- prepare stmt1 from "select * from t1 where c1=10"; set global query_cache_size=0; show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 12 +Qcache_hits 14 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 12 +Qcache_hits 14 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 12 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 ----- switch to connection con1 ---- -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 ----- switch to connection default ---- -set global query_cache_size=100000; -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 13 +Qcache_hits 14 execute stmt1; c1 10 @@ -223,42 +197,39 @@ c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 15 +Qcache_hits 14 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value +Qcache_hits 14 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +---- switch to connection default ---- +set global query_cache_size=100000; +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 15 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value Qcache_hits 16 -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 17 ----- switch to connection default ---- -set global query_cache_size=0; -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 17 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 17 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 17 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 17 ---- switch to connection con1 ---- execute stmt3; c1 @@ -271,13 +242,55 @@ c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 18 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 +---- switch to connection default ---- +set global query_cache_size=0; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +---- switch to connection con1 ---- +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 ---- switch to connection default ---- set global query_cache_size=0; prepare stmt1 from "select * from t1 where c1=10"; @@ -287,75 +300,75 @@ prepare stmt3 from "select * from t1 where c1=10"; set global query_cache_size=100000; show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 execute stmt1; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 ---- switch to connection con1 ---- show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 execute stmt3; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 ---- switch to connection default ---- set global query_cache_size=0; prepare stmt1 from "select * from t1 where c1=?"; set global query_cache_size=100000; show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 set @a=1; execute stmt1 using @a; c1 1 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 set @a=100; execute stmt1 using @a; c1 100 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 set @a=10; execute stmt1 using @a; c1 10 show status like 'Qcache_hits'; Variable_name Value -Qcache_hits 17 +Qcache_hits 19 drop table t1; ---- disconnect connection con1 ---- set @@global.query_cache_size=@initial_query_cache_size; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d1d70089584..6994ff99422 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2922,18 +2922,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) thd->restore_backup_statement(this, &stmt_backup); thd->stmt_arena= old_stmt_arena; - if ((protocol->type() == Protocol::PROTOCOL_TEXT) && (param_count > 0)) - { - /* - This is a mysql_sql_stmt_prepare(); query expansion will insert user - variable references, and user variables are uncacheable, thus we have to - mark this statement as uncacheable. - This has to be done before setup_set_params(), as it may make expansion - unneeded. - */ - lex->safe_to_cache_query= FALSE; - } - if (error == 0) { setup_set_params();