diff options
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 139 |
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 |