Commit 67687d06 authored by Monty's avatar Monty

Simplify TABLE::decide_logging_format()

- Use local variables table and share to simplify code
- Use sql_command_flags to detect what kind of command was used
- Added CF_DELETES_DATA to simplify detecton of delete commands
- Removed duplicate error in create_table_from_items().
parent b62101f8
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#include <m_ctype.h> #include <m_ctype.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <thr_alarm.h> #include <thr_alarm.h>
#ifdef __WIN__ #ifdef __WIN__0
#include <io.h> #include <io.h>
#endif #endif
#include <mysys_err.h> #include <mysys_err.h>
...@@ -6021,26 +6021,31 @@ int THD::decide_logging_format(TABLE_LIST *tables) ...@@ -6021,26 +6021,31 @@ int THD::decide_logging_format(TABLE_LIST *tables)
Get the capabilities vector for all involved storage engines and Get the capabilities vector for all involved storage engines and
mask out the flags for the binary log. mask out the flags for the binary log.
*/ */
for (TABLE_LIST *table= tables; table; table= table->next_global) for (TABLE_LIST *tbl= tables; tbl; tbl= tbl->next_global)
{ {
if (table->placeholder()) TABLE *table;
TABLE_SHARE *share;
handler::Table_flags flags;
if (tbl->placeholder())
continue; continue;
handler::Table_flags flags= table->table->file->ha_table_flags(); table= tbl->table;
if (!table->table->s->table_creation_was_logged) share= table->s;
flags= table->file->ha_table_flags();
if (!share->table_creation_was_logged)
{ {
/* /*
This is a temporary table which was not logged in the binary log. This is a temporary table which was not logged in the binary log.
Disable statement logging to enforce row level logging. Disable statement logging to enforce row level logging.
*/ */
DBUG_ASSERT(table->table->s->tmp_table); DBUG_ASSERT(share->tmp_table);
flags&= ~HA_BINLOG_STMT_CAPABLE; flags&= ~HA_BINLOG_STMT_CAPABLE;
} }
DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx", DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx",
table->table_name.str, flags)); tbl->table_name.str, flags));
if (table->table->s->no_replicate) if (share->no_replicate)
{ {
/* /*
The statement uses a table that is not replicated. The statement uses a table that is not replicated.
...@@ -6058,44 +6063,44 @@ int THD::decide_logging_format(TABLE_LIST *tables) ...@@ -6058,44 +6063,44 @@ int THD::decide_logging_format(TABLE_LIST *tables)
*/ */
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE); lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE);
if (table->lock_type >= TL_WRITE_ALLOW_WRITE) if (tbl->lock_type >= TL_WRITE_ALLOW_WRITE)
{ {
non_replicated_tables_count++; non_replicated_tables_count++;
continue; continue;
} }
} }
if (table == lex->first_not_own_table()) if (tbl == lex->first_not_own_table())
found_first_not_own_table= true; found_first_not_own_table= true;
replicated_tables_count++; replicated_tables_count++;
if (table->prelocking_placeholder != TABLE_LIST::PRELOCK_FK) if (tbl->prelocking_placeholder != TABLE_LIST::PRELOCK_FK)
{ {
if (table->lock_type <= TL_READ_NO_INSERT) if (tbl->lock_type <= TL_READ_NO_INSERT)
has_read_tables= true; has_read_tables= true;
else if (table->table->found_next_number_field && else if (table->found_next_number_field &&
(table->lock_type >= TL_WRITE_ALLOW_WRITE)) (tbl->lock_type >= TL_WRITE_ALLOW_WRITE))
{ {
has_auto_increment_write_tables= true; has_auto_increment_write_tables= true;
has_auto_increment_write_tables_not_first= found_first_not_own_table; has_auto_increment_write_tables_not_first= found_first_not_own_table;
if (table->table->s->next_number_keypart != 0) if (share->next_number_keypart != 0)
has_write_table_auto_increment_not_first_in_pk= true; has_write_table_auto_increment_not_first_in_pk= true;
} }
} }
if (table->lock_type >= TL_WRITE_ALLOW_WRITE) if (tbl->lock_type >= TL_WRITE_ALLOW_WRITE)
{ {
bool trans; bool trans;
if (prev_write_table && prev_write_table->file->ht != if (prev_write_table && prev_write_table->file->ht !=
table->table->file->ht) table->file->ht)
multi_write_engine= TRUE; multi_write_engine= TRUE;
if (table->table->s->non_determinstic_insert && if (share->non_determinstic_insert &&
!(sql_command_flags[lex->sql_command] & CF_SCHEMA_CHANGE)) !(sql_command_flags[lex->sql_command] & CF_SCHEMA_CHANGE))
has_write_tables_with_unsafe_statements= true; has_write_tables_with_unsafe_statements= true;
trans= table->table->file->has_transactions(); trans= table->file->has_transactions();
if (table->table->s->tmp_table) if (share->tmp_table)
lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TEMP_TRANS_TABLE : lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TEMP_TRANS_TABLE :
LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE); LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE);
else else
...@@ -6106,17 +6111,16 @@ int THD::decide_logging_format(TABLE_LIST *tables) ...@@ -6106,17 +6111,16 @@ int THD::decide_logging_format(TABLE_LIST *tables)
flags_write_some_set |= flags; flags_write_some_set |= flags;
is_write= TRUE; is_write= TRUE;
prev_write_table= table->table; prev_write_table= table;
} }
flags_access_some_set |= flags; flags_access_some_set |= flags;
if (lex->sql_command != SQLCOM_CREATE_TABLE || if (lex->sql_command != SQLCOM_CREATE_TABLE || lex->tmp_table())
(lex->sql_command == SQLCOM_CREATE_TABLE && lex->tmp_table()))
{ {
my_bool trans= table->table->file->has_transactions(); my_bool trans= table->file->has_transactions();
if (table->table->s->tmp_table) if (share->tmp_table)
lex->set_stmt_accessed_table(trans ? LEX::STMT_READS_TEMP_TRANS_TABLE : lex->set_stmt_accessed_table(trans ? LEX::STMT_READS_TEMP_TRANS_TABLE :
LEX::STMT_READS_TEMP_NON_TRANS_TABLE); LEX::STMT_READS_TEMP_NON_TRANS_TABLE);
else else
...@@ -6125,10 +6129,10 @@ int THD::decide_logging_format(TABLE_LIST *tables) ...@@ -6125,10 +6129,10 @@ int THD::decide_logging_format(TABLE_LIST *tables)
} }
if (prev_access_table && prev_access_table->file->ht != if (prev_access_table && prev_access_table->file->ht !=
table->table->file->ht) table->file->ht)
multi_access_engine= TRUE; multi_access_engine= TRUE;
prev_access_table= table->table; prev_access_table= table;
} }
if (wsrep_binlog_format() != BINLOG_FORMAT_ROW) if (wsrep_binlog_format() != BINLOG_FORMAT_ROW)
...@@ -6335,10 +6339,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) ...@@ -6335,10 +6339,8 @@ int THD::decide_logging_format(TABLE_LIST *tables)
"ROW" : "STATEMENT")); "ROW" : "STATEMENT"));
if (variables.binlog_format == BINLOG_FORMAT_ROW && if (variables.binlog_format == BINLOG_FORMAT_ROW &&
(lex->sql_command == SQLCOM_UPDATE || (sql_command_flags[lex->sql_command] &
lex->sql_command == SQLCOM_UPDATE_MULTI || (CF_UPDATES_DATA | CF_DELETES_DATA)))
lex->sql_command == SQLCOM_DELETE ||
lex->sql_command == SQLCOM_DELETE_MULTI))
{ {
String table_names; String table_names;
/* /*
...@@ -6358,8 +6360,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) ...@@ -6358,8 +6360,8 @@ int THD::decide_logging_format(TABLE_LIST *tables)
} }
if (!table_names.is_empty()) if (!table_names.is_empty())
{ {
bool is_update= (lex->sql_command == SQLCOM_UPDATE || bool is_update= MY_TEST(sql_command_flags[lex->sql_command] &
lex->sql_command == SQLCOM_UPDATE_MULTI); CF_UPDATES_DATA);
/* /*
Replace the last ',' with '.' for table_names Replace the last ',' with '.' for table_names
*/ */
......
...@@ -6336,6 +6336,11 @@ class select_dumpvar :public select_result_interceptor { ...@@ -6336,6 +6336,11 @@ class select_dumpvar :public select_result_interceptor {
/* Bits in server_command_flags */ /* Bits in server_command_flags */
/**
Statement that deletes existing rows (DELETE, DELETE_MULTI)
*/
#define CF_DELETES_DATA (1U << 24)
/** /**
Skip the increase of the global query id counter. Commonly set for Skip the increase of the global query id counter. Commonly set for
commands that are stateless (won't cause any change on the server commands that are stateless (won't cause any change on the server
......
...@@ -4357,7 +4357,10 @@ TABLE *select_create::create_table_from_items(THD *thd, ...@@ -4357,7 +4357,10 @@ TABLE *select_create::create_table_from_items(THD *thd,
/* /*
This can happen in innodb when you get a deadlock when using same table This can happen in innodb when you get a deadlock when using same table
in insert and select or when you run out of memory. in insert and select or when you run out of memory.
It can also happen if there was a conflict in
THD::decide_logging_format()
*/ */
if (!thd->is_error())
my_error(ER_CANT_LOCK, MYF(0), my_errno); my_error(ER_CANT_LOCK, MYF(0), my_errno);
if (*lock) if (*lock)
{ {
......
...@@ -605,11 +605,12 @@ void init_update_queries(void) ...@@ -605,11 +605,12 @@ void init_update_queries(void)
CF_CAN_GENERATE_ROW_EVENTS | CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE | CF_OPTIMIZER_TRACE |
CF_CAN_BE_EXPLAINED | CF_CAN_BE_EXPLAINED |
CF_SP_BULK_SAFE; CF_SP_BULK_SAFE | CF_DELETES_DATA;
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS | CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE | CF_OPTIMIZER_TRACE |
CF_CAN_BE_EXPLAINED; CF_CAN_BE_EXPLAINED |
CF_DELETES_DATA;
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS | CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE | CF_OPTIMIZER_TRACE |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment