summaryrefslogtreecommitdiff
path: root/sql/mysql_priv.h
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2005-09-03 03:13:18 +0400
committerunknown <konstantin@mysql.com>2005-09-03 03:13:18 +0400
commitc910050a769a20db0eee0d5a4f7069959d3e3470 (patch)
tree981df38c4f1f46f7080926e10ff505778048f4af /sql/mysql_priv.h
parentdc92221300d4d5b9e72d85373187d14d7f398c19 (diff)
downloadmariadb-git-c910050a769a20db0eee0d5a4f7069959d3e3470.tar.gz
Implement WL#2661 "Prepared Statements: Dynamic SQL in Stored Procedures".
The idea of the patch is to separate statement processing logic, such as parsing, validation of the parsed tree, execution and cleanup, from global query processing logic, such as logging, resetting priorities of a thread, resetting stored procedure cache, resetting thread count of errors and warnings. This makes PREPARE and EXECUTE behave similarly to the rest of SQL statements and allows their use in stored procedures. This patch contains a change in behaviour: until recently for each SQL prepared statement command, 2 queries were written to the general log, e.g. [Query] prepare stmt from @stmt_text; [Prepare] select * from t1 <-- contents of @stmt_text The chagne was necessary to prevent [Prepare] commands from being written to the general log when executing a stored procedure with Dynamic SQL. We should consider whether the old behavior is preferrable and probably restore it. This patch refixes Bug#7115, Bug#10975 (partially), Bug#10605 (various bugs in Dynamic SQL reported before it was disabled). mysql-test/r/not_embedded_server.result: Since we don't want to log Dynamic SQL in stored procedures, now the general log gets only one log entry per SQL statement. mysql-test/r/sp-error.result: - remove obsolete tests - a better error message for the case when a stored procedure that returns a result set is called from a function mysql-test/r/trigger.result: - a better error message for the case when a stored procedure that returns a result set is called from a trigger mysql-test/t/sp-error.test: - a better error message for the case when a stored procedure that returns a result set is called from a function. - move the comment to its place (end of file). mysql-test/t/trigger.test: - a better error message for the case when a stored procedure that returns a result set is called from a trigger sql/item_func.cc: - we need to pass sql_command explicitly to get_var_with_binlog, because when creating a query for SQL prepared statement thd->lex->sql_command points at SQLCOM_EXECUTE, which is not listed in the list of update queries. sql/log_event.h: - remove an extra copy of the previous sentence sql/mysql_priv.h: - fix declarations of sql_prepare.cc API sql/share/errmsg.txt: - a new error message, when one attempts to execute a prepared statement which is currently being executed (this can happen only in Dynamic SQL at the moment). sql/sp_head.cc: - extend sp_multi_results_command to return different flags for a command (and rename it) - add support for SQLCOM_PREPARE,SQLCOM_EXECUTE, SQLCOM_DEALLOCATE to sp_get_flags_for_command - replace multiple boolean sp_head members with uint m_flags - a fix for a crash when user variables are used in a stored procedure and binlog is on. A temporary fix for Bug#12637 "SP crashes the server if it has update query with user var & binlog is enabled", which actually stands for stored functions: now instead of a crash we break replication if a user variable is used in a stored function which is executed in prelocked mode. sql/sp_head.h: - replace multiple boolean flags of sp_head with uint m_flags; - add flag CONTAINS_DYNAMIC_SQL - use this flag to error if a stored procedure with Dynamic SQL is called from a function or trigger. sql/sql_class.cc: - Statement_map::insert should not delete a statement if it exists, now it's done externally to be able to handle the case when the statement being deleted is in use. - remove extra code (free_list is already reset in free_items) sql/sql_lex.cc: - add lex->stmt_prepare_mode; we can't rely on thd->command any more, because we don't reset it any more (Dynamic SQL requirement is that PS are as little intrusive as possible). sql/sql_lex.h: - declare bool LEX::stmt_prepare_mode sql/sql_parse.cc: - move prepared statement code to sql_prepare.cc - change declarations (refactored code) - better error message when one attempts to use Dynamic SQL or a stored procedure that returns a result set in a function or trigger. sql/sql_prepare.cc: - major refactoring to ensure PREPARE/EXECUTE commands do not reset global THD state and allow their use in stored procedures. - add Prepared_statement::flags and use it to ensure no recursive execution of a prepared statement is possible - better comments sql/sql_yacc.yy: - enable PREPARE/EXECUTE/DEALLOCATE in stored procedures - produce an error message on attempt to use PREPARE/EXECUTE/DEALLOCATE in a stored function or trigger mysql-test/r/sp-dynamic.result: - sp-dynamic.test results mysql-test/t/sp-dynamic.test: - a new test for PREPARE/EXECUTE/DEALLOCATE in stored procedures.
Diffstat (limited to 'sql/mysql_priv.h')
-rw-r--r--sql/mysql_priv.h17
1 files changed, 9 insertions, 8 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 1ab753e0938..154909a275d 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -589,7 +589,7 @@ bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
void mysql_parse(THD *thd,char *inBuf,uint length);
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
bool is_update_query(enum enum_sql_command command);
-bool alloc_query(THD *thd, char *packet, ulong packet_length);
+bool alloc_query(THD *thd, const char *packet, uint packet_length);
void mysql_init_select(LEX *lex);
void mysql_reset_thd_for_next_command(THD *thd);
void mysql_init_query(THD *thd, uchar *buf, uint length);
@@ -848,16 +848,17 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
bool get_schema_tables_result(JOIN *join);
/* sql_prepare.cc */
-bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
- LEX_STRING *name);
+
+void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length);
void mysql_stmt_execute(THD *thd, char *packet, uint packet_length);
-void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name);
-void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length);
void mysql_stmt_close(THD *thd, char *packet);
+void mysql_sql_stmt_prepare(THD *thd);
+void mysql_sql_stmt_execute(THD *thd);
+void mysql_sql_stmt_close(THD *thd);
+void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length);
void mysql_stmt_reset(THD *thd, char *packet);
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
void reinit_stmt_before_use(THD *thd, LEX *lex);
-void init_stmt_after_parse(THD*, LEX*);
/* sql_handler.cc */
bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
@@ -1361,8 +1362,8 @@ extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
/* item_func.cc */
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
LEX_STRING component);
-int get_var_with_binlog(THD *thd, LEX_STRING &name,
- user_var_entry **out_entry);
+int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
+ LEX_STRING &name, user_var_entry **out_entry);
/* log.cc */
bool flush_error_log(void);