mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +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:
@@ -1480,6 +1480,43 @@ error:
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Validate and prepare for execution CALL statement expressions.
|
||||
|
||||
@param stmt prepared statement
|
||||
@param tables list of tables used in this query
|
||||
@param value_list list of expressions
|
||||
|
||||
@retval FALSE success
|
||||
@retval TRUE error, error message is set in THD
|
||||
*/
|
||||
|
||||
static bool mysql_test_call_fields(Prepared_statement *stmt,
|
||||
TABLE_LIST *tables,
|
||||
List<Item> *value_list)
|
||||
{
|
||||
DBUG_ENTER("mysql_test_call_fields");
|
||||
|
||||
List_iterator<Item> it(*value_list);
|
||||
THD *thd= stmt->thd;
|
||||
Item *item;
|
||||
|
||||
if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE) ||
|
||||
open_normal_and_derived_tables(thd, tables, 0))
|
||||
goto err;
|
||||
|
||||
while ((item= it++))
|
||||
{
|
||||
if (!item->fixed && item->fix_fields(thd, it.ref()) ||
|
||||
item->check_cols(1))
|
||||
goto err;
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
err:
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check internal SELECT of the prepared command.
|
||||
|
||||
@@ -1601,6 +1638,17 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
|
||||
|
||||
res= select_like_stmt_test(stmt, 0, 0);
|
||||
}
|
||||
else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
|
||||
{
|
||||
/*
|
||||
Check that the source table exist, and also record
|
||||
its metadata version. Even though not strictly necessary,
|
||||
we validate metadata of all CREATE TABLE statements,
|
||||
which keeps metadata validation code simple.
|
||||
*/
|
||||
if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/* put tables back for PS rexecuting */
|
||||
lex->link_first_table_back(create_table, link_to_local);
|
||||
@@ -1838,7 +1886,21 @@ static bool check_prepared_statement(Prepared_statement *stmt)
|
||||
case SQLCOM_DELETE:
|
||||
res= mysql_test_delete(stmt, tables);
|
||||
break;
|
||||
|
||||
/* The following allow WHERE clause, so they must be tested like SELECT */
|
||||
case SQLCOM_SHOW_DATABASES:
|
||||
case SQLCOM_SHOW_TABLES:
|
||||
case SQLCOM_SHOW_TRIGGERS:
|
||||
case SQLCOM_SHOW_EVENTS:
|
||||
case SQLCOM_SHOW_OPEN_TABLES:
|
||||
case SQLCOM_SHOW_FIELDS:
|
||||
case SQLCOM_SHOW_KEYS:
|
||||
case SQLCOM_SHOW_COLLATIONS:
|
||||
case SQLCOM_SHOW_CHARSETS:
|
||||
case SQLCOM_SHOW_VARIABLES:
|
||||
case SQLCOM_SHOW_STATUS:
|
||||
case SQLCOM_SHOW_TABLE_STATUS:
|
||||
case SQLCOM_SHOW_STATUS_PROC:
|
||||
case SQLCOM_SHOW_STATUS_FUNC:
|
||||
case SQLCOM_SELECT:
|
||||
res= mysql_test_select(stmt, tables);
|
||||
if (res == 2)
|
||||
@@ -1863,6 +1925,9 @@ static bool check_prepared_statement(Prepared_statement *stmt)
|
||||
res= mysql_test_do_fields(stmt, tables, lex->insert_list);
|
||||
break;
|
||||
|
||||
case SQLCOM_CALL:
|
||||
res= mysql_test_call_fields(stmt, tables, &lex->value_list);
|
||||
break;
|
||||
case SQLCOM_SET_OPTION:
|
||||
res= mysql_test_set_fields(stmt, tables, &lex->var_list);
|
||||
break;
|
||||
@@ -1912,7 +1977,6 @@ static bool check_prepared_statement(Prepared_statement *stmt)
|
||||
case SQLCOM_DROP_INDEX:
|
||||
case SQLCOM_ROLLBACK:
|
||||
case SQLCOM_TRUNCATE:
|
||||
case SQLCOM_CALL:
|
||||
case SQLCOM_DROP_VIEW:
|
||||
case SQLCOM_REPAIR:
|
||||
case SQLCOM_ANALYZE:
|
||||
@@ -3064,6 +3128,26 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Assign parameter values either from variables, in case of SQL PS
|
||||
or from the execute packet.
|
||||
|
||||
@param expanded_query a container with the original SQL statement.
|
||||
'?' placeholders will be replaced with
|
||||
their values in case of success.
|
||||
The result is used for logging and replication
|
||||
@param packet pointer to execute packet.
|
||||
NULL in case of SQL PS
|
||||
@param packet_end end of the packet. NULL in case of SQL PS
|
||||
|
||||
@todo Use a paremeter source class family instead of 'if's, and
|
||||
support stored procedure variables.
|
||||
|
||||
@retval TRUE an error occurred when assigning a parameter (likely
|
||||
a conversion error or out of memory, or malformed packet)
|
||||
@retval FALSE success
|
||||
*/
|
||||
|
||||
bool
|
||||
Prepared_statement::set_parameters(String *expanded_query,
|
||||
uchar *packet, uchar *packet_end)
|
||||
|
Reference in New Issue
Block a user