summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc139
1 files changed, 90 insertions, 49 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f7572a374f1..d7490a5ac8e 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -180,11 +180,11 @@ sp_get_flags_for_command(LEX *lex)
case SQLCOM_SHOW_ERRORS:
case SQLCOM_SHOW_FIELDS:
case SQLCOM_SHOW_GRANTS:
- case SQLCOM_SHOW_INNODB_STATUS:
+ case SQLCOM_SHOW_ENGINE_STATUS:
+ case SQLCOM_SHOW_ENGINE_LOGS:
+ case SQLCOM_SHOW_ENGINE_MUTEX:
case SQLCOM_SHOW_KEYS:
- case SQLCOM_SHOW_LOGS:
case SQLCOM_SHOW_MASTER_STAT:
- case SQLCOM_SHOW_MUTEX_STATUS:
case SQLCOM_SHOW_NEW_MASTER:
case SQLCOM_SHOW_OPEN_TABLES:
case SQLCOM_SHOW_PRIVILEGES:
@@ -255,6 +255,9 @@ sp_get_flags_for_command(LEX *lex)
case SQLCOM_ALTER_FUNCTION:
case SQLCOM_DROP_PROCEDURE:
case SQLCOM_DROP_FUNCTION:
+ case SQLCOM_CREATE_EVENT:
+ case SQLCOM_ALTER_EVENT:
+ case SQLCOM_DROP_EVENT:
flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
break;
default:
@@ -314,6 +317,9 @@ sp_eval_expr(THD *thd, Field *result_field, Item *expr_item)
{
DBUG_ENTER("sp_eval_expr");
+ if (!expr_item)
+ DBUG_RETURN(TRUE);
+
if (!(expr_item= sp_prepare_func_item(thd, &expr_item)))
DBUG_RETURN(TRUE);
@@ -497,7 +503,7 @@ void
sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
{
DBUG_ENTER("sp_head::init_strings");
- uchar *endp; /* Used to trim the end */
+ const uchar *endp; /* Used to trim the end */
/* During parsing, we must use thd->mem_root */
MEM_ROOT *root= thd->mem_root;
@@ -698,7 +704,8 @@ sp_head::create_result_field(uint field_max_length, const char *field_name,
field_length= !m_return_field_def.length ?
field_max_length : m_return_field_def.length;
- field= ::make_field((char*) 0, /* field ptr */
+ field= ::make_field(table->s, /* TABLE_SHARE ptr */
+ (char*) 0, /* field ptr */
field_length, /* field [max] length */
(uchar*) "", /* null ptr */
0, /* null bit */
@@ -708,8 +715,10 @@ sp_head::create_result_field(uint field_max_length, const char *field_name,
m_return_field_def.geom_type,
Field::NONE, /* unreg check */
m_return_field_def.interval,
- field_name ? field_name : (const char *) m_name.str,
- table);
+ field_name ? field_name : (const char *) m_name.str);
+
+ if (field)
+ field->init(table);
DBUG_RETURN(field);
}
@@ -723,6 +732,9 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
/*
StoredRoutinesBinlogging
+ This paragraph applies only to statement-based binlogging. Row-based
+ binlogging does not need anything special like this.
+
Top-down overview:
1. Statements
@@ -736,7 +748,7 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
Statements that have is_update_query(stmt) == FALSE (e.g. SELECTs) are not
written into binary log. Instead we catch function calls the statement
makes and write it into binary log separately (see #3).
-
+
2. PROCEDURE calls
CALL statements are not written into binary log. Instead
@@ -757,7 +769,7 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
function execution (grep for start_union_events and stop_union_events)
If the answers are No and Yes, we write the function call into the binary
- log as "SELECT spfunc(<param1value>, <param2value>, ...)".
+ log as "SELECT spfunc(<param1value>, <param2value>, ...)"
4. Miscellaneous issues.
@@ -1284,56 +1296,62 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
thd->spcont= nctx;
- binlog_save_options= thd->options;
- need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
+ /*
+ If row-based binlogging, we don't need to binlog the function's call, let
+ each substatement be binlogged its way.
+ */
+ need_binlog_call= mysql_bin_log.is_open() &&
+ (thd->options & OPTION_BIN_LOG) && !thd->current_stmt_binlog_row_based;
if (need_binlog_call)
{
reset_dynamic(&thd->user_var_events);
mysql_bin_log.start_union_events(thd);
+ binlog_save_options= thd->options;
+ thd->options&= ~OPTION_BIN_LOG;
}
-
- thd->options&= ~OPTION_BIN_LOG;
+
err_status= execute(thd);
- thd->options= binlog_save_options;
-
- if (need_binlog_call)
- mysql_bin_log.stop_union_events(thd);
- if (need_binlog_call && thd->binlog_evt_union.unioned_events)
+ if (need_binlog_call)
{
- char buf[256];
- String bufstr(buf, sizeof(buf), &my_charset_bin);
- bufstr.length(0);
- bufstr.append(STRING_WITH_LEN("SELECT "));
- append_identifier(thd, &bufstr, m_name.str, m_name.length);
- bufstr.append('(');
- for (uint i=0; i < argcount; i++)
+ mysql_bin_log.stop_union_events(thd);
+ thd->options= binlog_save_options;
+ if (thd->binlog_evt_union.unioned_events)
{
- String str_value_holder;
- String *str_value;
-
- if (i)
- bufstr.append(',');
+ char buf[256];
+ String bufstr(buf, sizeof(buf), &my_charset_bin);
+ bufstr.length(0);
+ bufstr.append(STRING_WITH_LEN("SELECT "));
+ append_identifier(thd, &bufstr, m_name.str, m_name.length);
+ bufstr.append('(');
+ for (uint i=0; i < argcount; i++)
+ {
+ String str_value_holder;
+ String *str_value;
- str_value= sp_get_item_value(param_values[i], &str_value_holder);
+ if (i)
+ bufstr.append(',');
+
+ str_value= sp_get_item_value(param_values[i], &str_value_holder);
- if (str_value)
- bufstr.append(*str_value);
- else
- bufstr.append(STRING_WITH_LEN("NULL"));
- }
- bufstr.append(')');
-
- Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
- thd->binlog_evt_union.unioned_events_trans, FALSE);
- if (mysql_bin_log.write(&qinfo) &&
- thd->binlog_evt_union.unioned_events_trans)
- {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
- "Invoked ROUTINE modified a transactional table but MySQL "
- "failed to reflect this change in the binary log");
+ if (str_value)
+ bufstr.append(*str_value);
+ else
+ bufstr.append(STRING_WITH_LEN("NULL"));
+ }
+ bufstr.append(')');
+
+ Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
+ thd->binlog_evt_union.unioned_events_trans, FALSE);
+ if (mysql_bin_log.write(&qinfo) &&
+ thd->binlog_evt_union.unioned_events_trans)
+ {
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "Invoked ROUTINE modified a transactional table but MySQL "
+ "failed to reflect this change in the binary log");
+ }
+ reset_dynamic(&thd->user_var_events);
}
- reset_dynamic(&thd->user_var_events);
}
if (m_type == TYPE_ENUM_FUNCTION && !err_status)
@@ -1394,6 +1412,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
uint params = m_pcont->context_pvars();
sp_rcontext *save_spcont, *octx;
sp_rcontext *nctx = NULL;
+ bool save_enable_slow_log= false;
+ bool save_log_general= false;
DBUG_ENTER("sp_head::execute_procedure");
DBUG_PRINT("info", ("procedure %s", m_name.str));
@@ -1492,12 +1512,28 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
DBUG_PRINT("info",(" %.*s: eval args done", m_name.length, m_name.str));
}
-
+ if (!(m_flags & LOG_SLOW_STATEMENTS) && thd->enable_slow_log)
+ {
+ DBUG_PRINT("info", ("Disabling slow log for the execution"));
+ save_enable_slow_log= true;
+ thd->enable_slow_log= FALSE;
+ }
+ if (!(m_flags & LOG_GENERAL_LOG) && !(thd->options & OPTION_LOG_OFF))
+ {
+ DBUG_PRINT("info", ("Disabling general log for the execution"));
+ save_log_general= true;
+ /* disable this bit */
+ thd->options |= OPTION_LOG_OFF;
+ }
thd->spcont= nctx;
-
+
if (!err_status)
err_status= execute(thd);
+ if (save_log_general)
+ thd->options &= ~OPTION_LOG_OFF;
+ if (save_enable_slow_log)
+ thd->enable_slow_log= true;
/*
In the case when we weren't able to employ reuse mechanism for
OUT/INOUT paranmeters, we should reallocate memory. This
@@ -2276,10 +2312,15 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
(the order of query cache and subst_spvars calls is irrelevant because
queries with SP vars can't be cached)
*/
+ if (unlikely((thd->options & OPTION_LOG_OFF)==0))
+ general_log_print(thd, COM_QUERY, "%s", thd->query);
+
if (query_cache_send_result_to_client(thd,
thd->query, thd->query_length) <= 0)
{
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
+ if (!res && unlikely(thd->enable_slow_log))
+ log_slow_statement(thd);
query_cache_end_of_result(thd);
}
else