1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

WL#4165 "Prepared statements: validation".

Add metadata validation to ~20 more SQL commands. Make sure that
these commands actually work in ps-protocol, since until now they
were enabled, but not carefully tested.
Fixes the ml003 bug found by Matthias during internal testing of the
patch.


mysql-test/r/ps_ddl.result:
  Update test results (WL#4165)
mysql-test/t/ps_ddl.test:
  Cover with tests metadata validation of 26 SQL statements.
sql/mysql_priv.h:
  Fix the name in the comment.
sql/sp_head.cc:
  Changed the way the observer is removed in case of stored procedures
  to support validation prepare stmt from "call p1(<expr>)": whereas
  tables used in the expression must be validated, substatements
  of p1 must not.
  The previous scheme used to silence the observer only in stored
  functions and triggers.
sql/sql_class.cc:
  Now the observer is silenced in sp_head::execute(). Remove it from
  Sub_statement_state.
sql/sql_class.h:
  Now the observer is silenced in sp_head::execute(). Remove it from
  Sub_statement_state.
sql/sql_parse.cc:
  Add CF_REEXECUTION_FRAGILE to 20 more SQLCOMs that need it.
sql/sql_prepare.cc:
  Add metadata validation to ~20 new SQLCOMs that need it.
  Fix memory leaks with expressions used in SHOW DATABASES and CALL
  (and prepared statements).
  We need to fix all expressions at prepare, since if these expressions
  use subqueries, there are one-time transformations of the parse
  tree that must be done at prepare. 
  List of fixed commands includes: SHOW TABLES, SHOW DATABASES,
  SHOW TRIGGERS, SHOW EVENTS, SHOW OPEN TABLES,SHOW KEYS, SHOW FIELDS, 
  SHOW COLLATIONS, SHOW CHARSETS, SHOW VARIABLES, SHOW TATUS, SHOW TABLE
  STATUS, SHOW PROCEDURE STATUS, SHOW FUNCTION STATUS, CALL.
  Add comment to set_parameters().
sql/table.h:
  Update comments.
This commit is contained in:
unknown
2008-04-17 01:04:49 +04:00
parent 1ff9a2437a
commit bd2a732812
9 changed files with 1255 additions and 47 deletions

View File

@ -614,6 +614,8 @@ select * from t1;
--echo # Currently a different result from conventional statements.
--echo # A view is inlined once at prepare, later on view DDL
--echo # does not affect prepared statement and it is not re-prepared.
--echo # This is reported in Bug#36002 Prepared statements: if a view
--echo # used in a statement is replaced, bad data
execute stmt;
call p_verify_reprepare_count(0);
flush table t2;
@ -1347,6 +1349,588 @@ drop procedure p_12093;
deallocate prepare stmt_sf;
deallocate prepare stmt_sp;
--echo =====================================================================
--echo Ensure that metadata validation is performed for every type of
--echo SQL statement where it is needed.
--echo =====================================================================
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
--echo #
--echo # SQLCOM_SELECT
--echo #
prepare stmt from "select 1 as res from dual where (1) in (select * from t1)";
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
call p_verify_reprepare_count(1);
--echo #
--echo # SQLCOM_CREATE_TABLE
--echo #
--disable_warnings
drop table if exists t1;
drop table if exists t2;
--enable_warnings
create table t1 (a int);
prepare stmt from 'create table t2 as select * from t1';
execute stmt;
drop table t2;
execute stmt;
drop table t2;
execute stmt;
call p_verify_reprepare_count(0);
--error ER_TABLE_EXISTS_ERROR
execute stmt;
call p_verify_reprepare_count(1);
--error ER_TABLE_EXISTS_ERROR
execute stmt;
call p_verify_reprepare_count(0);
drop table t2;
create temporary table t2 (a int);
--error ER_TABLE_EXISTS_ERROR
execute stmt;
call p_verify_reprepare_count(1);
--error ER_TABLE_EXISTS_ERROR
execute stmt;
call p_verify_reprepare_count(0);
drop temporary table t2;
execute stmt;
call p_verify_reprepare_count(1);
drop table t2;
execute stmt;
call p_verify_reprepare_count(0);
drop table t2;
drop table t1;
create table t1 (x varchar(20));
execute stmt;
call p_verify_reprepare_count(1);
select * from t2;
drop table t2;
execute stmt;
call p_verify_reprepare_count(0);
drop table t2;
drop table t1;
deallocate prepare stmt;
--echo # XXX: no validation of the first table in case of
--echo # CREATE TEMPORARY TABLE. This is a shortcoming of the current code,
--echo # but since validation is not strictly necessary, nothing is done
--echo # about it.
--echo # Will be fixed as part of work on Bug#21431 "Incomplete support of
--echo # temporary tables"
create table t1 (a int);
insert into t1 (a) values (1);
prepare stmt from "create temporary table if not exists t2 as select * from t1";
execute stmt;
drop table t2;
execute stmt;
execute stmt;
select * from t2;
execute stmt;
select * from t2;
drop table t2;
create temporary table t2 (a varchar(10));
execute stmt;
select * from t2;
call p_verify_reprepare_count(0);
drop table t1;
create table t1 (x int);
execute stmt;
call p_verify_reprepare_count(1);
execute stmt;
call p_verify_reprepare_count(0);
drop table t1;
drop table t2;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_UPDATE
--echo #
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
prepare stmt from "update t2 set a=a+1 where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1, t2;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_INSERT
--echo #
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
prepare stmt from "insert into t2 set a=((1) in (select * from t1))";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1, t2;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_INSERT_SELECT
--echo #
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
prepare stmt from "insert into t2 select * from t1";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1, t2;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_REPLACE
--echo #
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
prepare stmt from "replace t2 set a=((1) in (select * from t1))";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1, t2;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_REPLACE_SELECT
--echo #
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
prepare stmt from "replace t2 select * from t1";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1, t2;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_DELETE
--echo #
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
prepare stmt from "delete from t2 where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1, t2;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_DELETE_MULTI
--echo #
--disable_warnings
drop table if exists t1, t2, t3;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
create table t3 (a int);
prepare stmt from "delete t2, t3 from t2, t3 where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1, t2, t3;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_UPDATE_MULTI
--echo #
--disable_warnings
drop table if exists t1, t2, t3;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
create table t3 (a int);
prepare stmt from "update t2, t3 set t3.a=t2.a, t2.a=null where (1) in (select * from t1)";
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1, t2, t3;
deallocate prepare stmt;
--echo # Intermediate results: 8 SQLCOMs tested, 8 automatic reprepares
call p_verify_reprepare_count(8);
--echo #
--echo # SQLCOM_LOAD
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a varchar(20));
--error ER_UNSUPPORTED_PS
prepare stmt from "load data infile '../std_data_ln/words.dat' into table t1";
drop table t1;
--echo #
--echo # SQLCOM_SHOW_DATABASES
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show databases where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_TABLES
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show tables where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_FIELDS
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show fields from t1 where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_KEYS
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show keys from t1 where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_VARIABLES
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show variables where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_STATUS
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show status where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_LOGS,
--echo # SQLCOM_SHOW_ENGINE_MUTEX, SQLCOM_SHOW_PROCESSLIST
--echo #
--echo # Currently can not have a where clause, need to be covered
--echo # with tests
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
--error ER_PARSE_ERROR
prepare stmt from "show engine all status where (1) in (select * from t1)";
--error ER_PARSE_ERROR
prepare stmt from "show engine all logs where (1) in (select * from t1)";
--error ER_PARSE_ERROR
prepare stmt from "show engine all mutex where (1) in (select * from t1)";
--error ER_PARSE_ERROR
prepare stmt from "show processlist where (1) in (select * from t1)";
drop table t1;
--echo #
--echo # SQLCOM_SHOW_CHARSETS
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show charset where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_COLLATIONS
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show collation where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_TABLE_STATUS
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show table status where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_TRIGGERS
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show triggers where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_OPEN_TABLES
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show open tables where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_STATUS_PROC
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show procedure status where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_STATUS_FUNC
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show function status where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SHOW_EVENTS
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "show events where (1) in (select * from t1)";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_SET_OPTION
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "set @a=((1) in (select * from t1))";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_DO
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
prepare stmt from "do ((1) in (select * from t1))";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_CALL
--echo #
--disable_warnings
drop table if exists t1;
drop procedure if exists p1;
--enable_warnings
create procedure p1(a int) begin end;
create table t1 (a int);
prepare stmt from "call p1((1) in (select * from t1))";
execute stmt;
drop table t1;
create table t1 (x int);
execute stmt;
drop table t1;
drop procedure p1;
deallocate prepare stmt;
--echo #
--echo # SQLCOM_CREATE_VIEW
--echo #
--disable_warnings
drop table if exists t1;
drop view if exists v1;
--enable_warnings
create table t1 (a int);
prepare stmt from "create view v1 as select * from t1";
execute stmt;
drop view v1;
drop table t1;
create table t1 (x int);
execute stmt;
drop view v1;
drop table t1;
deallocate prepare stmt;
--echo # Intermediate result: number of reprepares matches the number
--echo # of tests
call p_verify_reprepare_count(18);
--echo #
--echo # SQLCOM_ALTER_VIEW
--echo #
--disable_warnings
drop view if exists v1;
--enable_warnings
create view v1 as select 1;
--error ER_UNSUPPORTED_PS
prepare stmt from "alter view v1 as select 2";
drop view v1;
--echo # Cleanup
--echo #
--disable_warnings