mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge mysql-5.5-bugfixing -> mysql-5.5-innodb
This commit is contained in:
168
sql/sql_class.cc
168
sql/sql_class.cc
@ -29,7 +29,6 @@
|
||||
#include "sql_priv.h"
|
||||
#include "unireg.h" // REQUIRED: for other includes
|
||||
#include "sql_class.h"
|
||||
#include "lock.h" // unlock_global_read_lock, mysql_unlock_tables
|
||||
#include "sql_cache.h" // query_cache_abort
|
||||
#include "sql_base.h" // close_thread_tables
|
||||
#include "sql_time.h" // date_time_format_copy
|
||||
@ -496,10 +495,8 @@ THD::THD()
|
||||
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
|
||||
/* statement id */ 0),
|
||||
rli_fake(0),
|
||||
lock_id(&main_lock_id),
|
||||
user_time(0), in_sub_stmt(0),
|
||||
binlog_unsafe_warning_flags(0),
|
||||
stmt_accessed_table_flag(0),
|
||||
binlog_table_maps(0),
|
||||
table_map_for_update(0),
|
||||
arg_of_last_insert_id_function(FALSE),
|
||||
@ -630,7 +627,6 @@ THD::THD()
|
||||
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
|
||||
substitute_null_with_insert_id = FALSE;
|
||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||
thr_lock_owner_init(&main_lock_id, &lock_info);
|
||||
|
||||
m_internal_handler= NULL;
|
||||
current_user_used= FALSE;
|
||||
@ -853,35 +849,6 @@ MYSQL_ERROR* THD::raise_condition(uint sql_errno,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If a continue handler is found, the error message will be cleared
|
||||
by the stored procedures code.
|
||||
*/
|
||||
if (!is_fatal_error && spcont &&
|
||||
spcont->handle_condition(this, sql_errno, sqlstate, level, msg, &cond))
|
||||
{
|
||||
/*
|
||||
Do not push any warnings, a handled error must be completely
|
||||
silenced.
|
||||
*/
|
||||
DBUG_RETURN(cond);
|
||||
}
|
||||
|
||||
/* Un-handled conditions */
|
||||
|
||||
cond= raise_condition_no_handler(sql_errno, sqlstate, level, msg);
|
||||
DBUG_RETURN(cond);
|
||||
}
|
||||
|
||||
MYSQL_ERROR*
|
||||
THD::raise_condition_no_handler(uint sql_errno,
|
||||
const char* sqlstate,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
const char* msg)
|
||||
{
|
||||
MYSQL_ERROR *cond= NULL;
|
||||
DBUG_ENTER("THD::raise_condition_no_handler");
|
||||
|
||||
query_cache_abort(&query_cache_tls);
|
||||
|
||||
/* FIXME: broken special case */
|
||||
@ -894,6 +861,7 @@ THD::raise_condition_no_handler(uint sql_errno,
|
||||
cond= warning_info->push_warning(this, sql_errno, sqlstate, level, msg);
|
||||
DBUG_RETURN(cond);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void *thd_alloc(MYSQL_THD thd, unsigned int size)
|
||||
{
|
||||
@ -1119,7 +1087,6 @@ THD::~THD()
|
||||
}
|
||||
#endif
|
||||
stmt_map.reset(); /* close all prepared statements */
|
||||
DBUG_ASSERT(lock_info.n_cursors == 0);
|
||||
if (!cleanup_done)
|
||||
cleanup();
|
||||
|
||||
@ -1746,9 +1713,9 @@ bool select_send::send_result_set_metadata(List<Item> &list, uint flags)
|
||||
return res;
|
||||
}
|
||||
|
||||
void select_send::abort()
|
||||
void select_send::abort_result_set()
|
||||
{
|
||||
DBUG_ENTER("select_send::abort");
|
||||
DBUG_ENTER("select_send::abort_result_set");
|
||||
|
||||
if (is_result_set_started && thd->spcont)
|
||||
{
|
||||
@ -1822,12 +1789,6 @@ bool select_send::send_eof()
|
||||
*/
|
||||
ha_release_temporary_latches(thd);
|
||||
|
||||
/* Unlock tables before sending packet to gain some speed */
|
||||
if (thd->lock && ! thd->locked_tables_mode)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0;
|
||||
}
|
||||
/*
|
||||
Don't send EOF if we're in error condition (which implies we've already
|
||||
sent or are sending an error)
|
||||
@ -2601,7 +2562,6 @@ Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
|
||||
id(id_arg),
|
||||
mark_used_columns(MARK_COLUMNS_READ),
|
||||
lex(lex_arg),
|
||||
cursor(0),
|
||||
db(NULL),
|
||||
db_length(0)
|
||||
{
|
||||
@ -2623,7 +2583,6 @@ void Statement::set_statement(Statement *stmt)
|
||||
mark_used_columns= stmt->mark_used_columns;
|
||||
lex= stmt->lex;
|
||||
query_string= stmt->query_string;
|
||||
cursor= stmt->cursor;
|
||||
}
|
||||
|
||||
|
||||
@ -3720,8 +3679,17 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
Innodb and Falcon; Innodb and MyIsam.
|
||||
*/
|
||||
my_bool multi_access_engine= FALSE;
|
||||
|
||||
/*
|
||||
Identifies if a table is changed.
|
||||
*/
|
||||
my_bool is_write= FALSE;
|
||||
/*
|
||||
A pointer to a previous table that was changed.
|
||||
*/
|
||||
TABLE* prev_write_table= NULL;
|
||||
/*
|
||||
A pointer to a previous table that was accessed.
|
||||
*/
|
||||
TABLE* prev_access_table= NULL;
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
@ -3745,7 +3713,8 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
if (table->placeholder())
|
||||
continue;
|
||||
|
||||
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
|
||||
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE ||
|
||||
table->table->s->table_category == TABLE_CATEGORY_LOG)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE);
|
||||
|
||||
handler::Table_flags const flags= table->table->file->ha_table_flags();
|
||||
@ -3761,16 +3730,18 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
my_bool trans= table->table->file->has_transactions();
|
||||
|
||||
if (table->table->s->tmp_table)
|
||||
set_stmt_accessed_table(trans ? STMT_WRITES_TEMP_TRANS_TABLE :
|
||||
STMT_WRITES_TEMP_NON_TRANS_TABLE);
|
||||
lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TEMP_TRANS_TABLE :
|
||||
LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE);
|
||||
else
|
||||
set_stmt_accessed_table(trans ? STMT_WRITES_TRANS_TABLE :
|
||||
STMT_WRITES_NON_TRANS_TABLE);
|
||||
lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TRANS_TABLE :
|
||||
LEX::STMT_WRITES_NON_TRANS_TABLE);
|
||||
|
||||
flags_write_all_set &= flags;
|
||||
flags_write_some_set |= flags;
|
||||
is_write= TRUE;
|
||||
|
||||
prev_write_table= table->table;
|
||||
|
||||
}
|
||||
flags_access_some_set |= flags;
|
||||
|
||||
@ -3781,11 +3752,11 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
my_bool trans= table->table->file->has_transactions();
|
||||
|
||||
if (table->table->s->tmp_table)
|
||||
set_stmt_accessed_table(trans ? STMT_READS_TEMP_TRANS_TABLE :
|
||||
STMT_READS_TEMP_NON_TRANS_TABLE);
|
||||
lex->set_stmt_accessed_table(trans ? LEX::STMT_READS_TEMP_TRANS_TABLE :
|
||||
LEX::STMT_READS_TEMP_NON_TRANS_TABLE);
|
||||
else
|
||||
set_stmt_accessed_table(trans ? STMT_READS_TRANS_TABLE :
|
||||
STMT_READS_NON_TRANS_TABLE);
|
||||
lex->set_stmt_accessed_table(trans ? LEX::STMT_READS_TRANS_TABLE :
|
||||
LEX::STMT_READS_NON_TRANS_TABLE);
|
||||
}
|
||||
|
||||
if (prev_access_table && prev_access_table->file->ht !=
|
||||
@ -3857,24 +3828,24 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
my_bool non_trans_unsafe= FALSE;
|
||||
|
||||
/* Case 1. */
|
||||
if (stmt_accessed_table(STMT_WRITES_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
|
||||
if (lex->stmt_accessed_table(LEX::STMT_WRITES_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 2. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TEMP_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 3. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 4. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TEMP_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 5. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_TRANS_TABLE) &&
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_TRANS_TABLE) &&
|
||||
tx_isolation < ISO_REPEATABLE_READ)
|
||||
/*
|
||||
By default, InnoDB operates in REPEATABLE READ and with the option
|
||||
@ -3892,28 +3863,28 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
if (trans_has_updated_trans_table(this))
|
||||
{
|
||||
/* Case 6. */
|
||||
if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_TRANS_TABLE))
|
||||
if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 7. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_TEMP_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_TEMP_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 8. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_TEMP_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_TEMP_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 9. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 10. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 11. */
|
||||
else if (!variables.binlog_direct_non_trans_update &&
|
||||
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
|
||||
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
|
||||
non_trans_unsafe= TRUE;
|
||||
}
|
||||
|
||||
@ -4004,13 +3975,14 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
*/
|
||||
my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), "");
|
||||
}
|
||||
else if ((unsafe_flags= lex->get_stmt_unsafe_flags()) != 0)
|
||||
else if (is_write && (unsafe_flags= lex->get_stmt_unsafe_flags()) != 0)
|
||||
{
|
||||
/*
|
||||
7. Warning: Unsafe statement logged as statement due to
|
||||
binlog_format = STATEMENT
|
||||
*/
|
||||
binlog_unsafe_warning_flags|= unsafe_flags;
|
||||
|
||||
DBUG_PRINT("info", ("Scheduling warning to be issued by "
|
||||
"binlog_query: '%s'",
|
||||
ER(ER_BINLOG_UNSAFE_STATEMENT)));
|
||||
@ -4486,23 +4458,10 @@ void THD::issue_unsafe_warnings()
|
||||
Ensure that binlog_unsafe_warning_flags is big enough to hold all
|
||||
bits. This is actually a constant expression.
|
||||
*/
|
||||
DBUG_ASSERT(2 * LEX::BINLOG_STMT_UNSAFE_COUNT <=
|
||||
DBUG_ASSERT(LEX::BINLOG_STMT_UNSAFE_COUNT <=
|
||||
sizeof(binlog_unsafe_warning_flags) * CHAR_BIT);
|
||||
|
||||
uint32 unsafe_type_flags= binlog_unsafe_warning_flags;
|
||||
|
||||
/*
|
||||
Clear: (1) bits above BINLOG_STMT_UNSAFE_COUNT; (2) bits for
|
||||
warnings that have been printed already.
|
||||
*/
|
||||
unsafe_type_flags &= (LEX::BINLOG_STMT_UNSAFE_ALL_FLAGS ^
|
||||
(unsafe_type_flags >> LEX::BINLOG_STMT_UNSAFE_COUNT));
|
||||
/* If all warnings have been printed already, return. */
|
||||
if (unsafe_type_flags == 0)
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
DBUG_PRINT("info", ("unsafe_type_flags: 0x%x", unsafe_type_flags));
|
||||
|
||||
/*
|
||||
For each unsafe_type, check if the statement is unsafe in this way
|
||||
and issue a warning.
|
||||
@ -4526,12 +4485,6 @@ void THD::issue_unsafe_warnings()
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Mark these unsafe types as already printed, to avoid printing
|
||||
warnings for them again.
|
||||
*/
|
||||
binlog_unsafe_warning_flags|=
|
||||
unsafe_type_flags << LEX::BINLOG_STMT_UNSAFE_COUNT;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -4585,19 +4538,32 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
|
||||
|
||||
/*
|
||||
Warnings for unsafe statements logged in statement format are
|
||||
printed here instead of in decide_logging_format(). This is
|
||||
because the warnings should be printed only if the statement is
|
||||
actually logged. When executing decide_logging_format(), we cannot
|
||||
know for sure if the statement will be logged.
|
||||
printed in three places instead of in decide_logging_format().
|
||||
This is because the warnings should be printed only if the statement
|
||||
is actually logged. When executing decide_logging_format(), we cannot
|
||||
know for sure if the statement will be logged:
|
||||
|
||||
1 - sp_head::execute_procedure which prints out warnings for calls to
|
||||
stored procedures.
|
||||
|
||||
2 - sp_head::execute_function which prints out warnings for calls
|
||||
involving functions.
|
||||
|
||||
3 - THD::binlog_query (here) which prints warning for top level
|
||||
statements not covered by the two cases above: i.e., if not insided a
|
||||
procedure and a function.
|
||||
|
||||
Besides, we should not try to print these warnings if it is not
|
||||
possible to write statements to the binary log as it happens when
|
||||
the execution is inside a function, or generaly speaking, when
|
||||
the variables.option_bits & OPTION_BIN_LOG is false.
|
||||
|
||||
*/
|
||||
if (variables.option_bits & OPTION_BIN_LOG)
|
||||
if ((variables.option_bits & OPTION_BIN_LOG) &&
|
||||
spcont == NULL && !binlog_evt_union.do_union)
|
||||
issue_unsafe_warnings();
|
||||
|
||||
|
||||
switch (qtype) {
|
||||
/*
|
||||
ROW_QUERY_TYPE means that the statement may be logged either in
|
||||
|
Reference in New Issue
Block a user