diff options
author | Alexander Nozdrin <alik@sun.com> | 2010-08-12 17:55:27 +0400 |
---|---|---|
committer | Alexander Nozdrin <alik@sun.com> | 2010-08-12 17:55:27 +0400 |
commit | 93594dff84d61c199786d246c58948365c13ca84 (patch) | |
tree | a254f9f9ffa921f69300021067e8228b68597d29 /sql | |
parent | f886745dfadfa11ebdb5fde328120b304d8ee38d (diff) | |
parent | 7b3ea8fef869c049c3a6c37b4c478b9b3998f5f6 (diff) | |
download | mariadb-git-93594dff84d61c199786d246c58948365c13ca84.tar.gz |
Auto-merge from mysql-5.5-bugfixing.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/CMakeLists.txt | 13 | ||||
-rw-r--r-- | sql/item.cc | 4 | ||||
-rw-r--r-- | sql/log.cc | 2 | ||||
-rw-r--r-- | sql/log_event.cc | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 21 | ||||
-rw-r--r-- | sql/sql_class.cc | 122 | ||||
-rw-r--r-- | sql/sql_class.h | 149 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 125 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 |
10 files changed, 227 insertions, 215 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index e8a594c4d8b..943d6b2eece 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -42,7 +42,6 @@ SET (SQL_SOURCE ../sql-common/client.c derror.cc des_key_file.cc discover.cc ../libmysql/errmsg.c field.cc field_conv.cc filesort.cc gstream.cc sha2.cc - ha_partition.cc handler.cc hash_filo.h sql_plugin_services.h hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc item_create.cc item_func.cc item_geofunc.cc item_row.cc @@ -83,6 +82,7 @@ MYSQL_ADD_PLUGIN(partition ha_partition.cc STORAGE_ENGINE DEFAULT STATIC_ONLY RECOMPILE_FOR_EMBEDDED) ADD_LIBRARY(sql STATIC ${SQL_SOURCE}) +ADD_DEPENDENCIES(sql GenServerSource) DTRACE_INSTRUMENT(sql) TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS} mysys dbug strings vio regex @@ -189,6 +189,7 @@ ADD_EXECUTABLE(gen_lex_hash gen_lex_hash.cc) ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h COMMAND gen_lex_hash > lex_hash.h + DEPENDS gen_lex_hash ) MYSQL_ADD_EXECUTABLE(mysql_tzinfo_to_sql tztime.cc) @@ -266,18 +267,20 @@ IF(WIN32 AND MYSQLD_EXECUTABLE) ENDIF() MAKE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR}/data) ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/data/mysql/user.frm + OUTPUT initdb.dep COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_initial_db.cmake WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data + COMMAND ${CMAKE_COMMAND} -E touch initdb.dep + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS mysqld ) ADD_CUSTOM_TARGET(initial_database ALL - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/data/mysql/user.frm + DEPENDS initdb.dep ) - INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data DESTINATION . COMPONENT DataFiles - PATTERN "bootstrap.sql" EXCLUDE) + INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data DESTINATION . + COMPONENT DataFiles PATTERN "initdb.dep" EXCLUDE PATTERN "bootstrap.sql" EXCLUDE) ELSE() # Not windows or cross compiling, just install an empty directory INSTALL(FILES ${DUMMY_FILE} DESTINATION data/mysql) diff --git a/sql/item.cc b/sql/item.cc index 8210f4e6caf..1decb5ec426 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7510,13 +7510,13 @@ String *Item_cache_datetime::val_str(String *str) if (cached_field_type == MYSQL_TYPE_TIME) { ulonglong time= int_value; - DBUG_ASSERT(time < TIME_MAX_VALUE); + DBUG_ASSERT(time <= TIME_MAX_VALUE); set_zero_time(<ime, MYSQL_TIMESTAMP_TIME); ltime.second= time % 100; time/= 100; ltime.minute= time % 100; time/= 100; - ltime.hour= time % 100; + ltime.hour= time; } else { diff --git a/sql/log.cc b/sql/log.cc index 1e4682e4bc3..86f8100be07 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4704,7 +4704,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) file= cache_mngr->get_binlog_cache_log(is_trans_cache); cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache); - if (thd->stmt_accessed_non_trans_temp_table()) + if (thd->lex->stmt_accessed_non_trans_temp_table()) cache_data->set_changes_to_non_trans_temp_table(); thd->binlog_start_trans_and_stmt(); diff --git a/sql/log_event.cc b/sql/log_event.cc index ea7f4b4b245..d224f555cf2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -679,7 +679,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans) server_id= thd->server_id; when= thd->start_time; cache_type= ((using_trans || stmt_has_updated_trans_table(thd) || - (thd->stmt_accessed_temp_table() && + (thd->lex->stmt_accessed_temp_table() && trans_has_updated_trans_table(thd))) ? Log_event::EVENT_TRANSACTIONAL_CACHE : Log_event::EVENT_STMT_CACHE); @@ -2573,7 +2573,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, else { cache_type= ((using_trans || stmt_has_updated_trans_table(thd) || trx_cache || - (thd->stmt_accessed_temp_table() && + (thd->lex->stmt_accessed_temp_table() && trans_has_updated_trans_table(thd))) ? Log_event::EVENT_TRANSACTIONAL_CACHE : Log_event::EVENT_STMT_CACHE); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2d3a32c7f7f..a95bbe094c0 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1743,7 +1743,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Field *return_value_fld) { ulonglong binlog_save_options; - bool need_binlog_call; + bool need_binlog_call= FALSE; uint arg_no; sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; @@ -1950,6 +1950,14 @@ err_with_cleanup: free_root(&call_mem_root, MYF(0)); thd->spcont= octx; + /* + If not insided a procedure and a function printing warning + messsages. + */ + if (need_binlog_call && + thd->spcont == NULL && !thd->binlog_evt_union.do_union) + thd->issue_unsafe_warnings(); + DBUG_RETURN(err_status); } @@ -2195,6 +2203,17 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) thd->spcont= save_spcont; thd->utime_after_lock= utime_before_sp_exec; + /* + If not insided a procedure and a function printing warning + messsages. + */ + bool need_binlog_call= mysql_bin_log.is_open() && + (thd->variables.option_bits & OPTION_BIN_LOG) && + !thd->is_current_stmt_binlog_format_row(); + if (need_binlog_call && thd->spcont == NULL && + !thd->binlog_evt_union.do_union) + thd->issue_unsafe_warnings(); + DBUG_RETURN(err_status); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 60a871e9e88..2fdf270ae66 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -492,7 +492,6 @@ THD::THD() rli_fake(0), 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), @@ -3675,8 +3674,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 @@ -3700,7 +3708,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(); @@ -3716,16 +3725,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; @@ -3736,11 +3747,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 != @@ -3812,24 +3823,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 @@ -3847,28 +3858,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; } @@ -3959,13 +3970,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))); @@ -4441,23 +4453,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. @@ -4481,12 +4480,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; } @@ -4540,19 +4533,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 diff --git a/sql/sql_class.h b/sql/sql_class.h index b23b65dae2f..78eeda5843d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1566,125 +1566,6 @@ public: return current_stmt_binlog_format == BINLOG_FORMAT_ROW; } - enum enum_stmt_accessed_table - { - /* - If a transactional table is about to be read. Note that - a write implies a read. - */ - STMT_READS_TRANS_TABLE= 0, - /* - If a transactional table is about to be updated. - */ - STMT_WRITES_TRANS_TABLE, - /* - If a non-transactional table is about to be read. Note that - a write implies a read. - */ - STMT_READS_NON_TRANS_TABLE, - /* - If a non-transactional table is about to be updated. - */ - STMT_WRITES_NON_TRANS_TABLE, - /* - If a temporary transactional table is about to be read. Note - that a write implies a read. - */ - STMT_READS_TEMP_TRANS_TABLE, - /* - If a temporary transactional table is about to be updated. - */ - STMT_WRITES_TEMP_TRANS_TABLE, - /* - If a temporary non-transactional table is about to be read. Note - that a write implies a read. - */ - STMT_READS_TEMP_NON_TRANS_TABLE, - /* - If a temporary non-transactional table is about to be updated. - */ - STMT_WRITES_TEMP_NON_TRANS_TABLE, - /* - The last element of the enumeration. Please, if necessary add - anything before this. - */ - STMT_ACCESS_TABLE_COUNT - }; - - /** - Sets the type of table that is about to be accessed while executing a - statement. - - @param accessed_table Enumeration type that defines the type of table, - e.g. temporary, transactional, non-transactional. - */ - inline void set_stmt_accessed_table(enum_stmt_accessed_table accessed_table) - { - DBUG_ENTER("THD::set_stmt_accessed_table"); - - DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT); - stmt_accessed_table_flag |= (1U << accessed_table); - - DBUG_VOID_RETURN; - } - - /** - Checks if a type of table is about to be accessed while executing a - statement. - - @param accessed_table Enumeration type that defines the type of table, - e.g. temporary, transactional, non-transactional. - - @return - @retval TRUE if the type of the table is about to be accessed - @retval FALSE otherwise - */ - inline bool stmt_accessed_table(enum_stmt_accessed_table accessed_table) - { - DBUG_ENTER("THD::stmt_accessed_table"); - - DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT); - - DBUG_RETURN((stmt_accessed_table_flag & (1U << accessed_table)) != 0); - } - - /** - Checks if a temporary table is about to be accessed while executing a - statement. - - @return - @retval TRUE if a temporary table is about to be accessed - @retval FALSE otherwise - */ - inline bool stmt_accessed_temp_table() - { - DBUG_ENTER("THD::stmt_accessed_temp_table"); - - DBUG_RETURN((stmt_accessed_table_flag & - ((1U << STMT_READS_TEMP_TRANS_TABLE) | - (1U << STMT_WRITES_TEMP_TRANS_TABLE) | - (1U << STMT_READS_TEMP_NON_TRANS_TABLE) | - (1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0); - } - - /** - Checks if a temporary non-transactional table is about to be accessed - while executing a statement. - - @return - @retval TRUE if a temporary non-transactional table is about to be - accessed - @retval FALSE otherwise - */ - inline bool stmt_accessed_non_trans_temp_table() - { - DBUG_ENTER("THD::stmt_accessed_non_trans_temp_table"); - - DBUG_RETURN((stmt_accessed_table_flag & - ((1U << STMT_READS_TEMP_NON_TRANS_TABLE) | - (1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0); - } - private: /** Indicates the format in which the current statement will be @@ -1695,24 +1576,8 @@ private: /** Bit field for the state of binlog warnings. - There are two groups of bits: - - - The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of - unsafeness that the current statement has. - - - The following Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types - of unsafeness that the current statement has issued warnings - for. - - Hence, this variable must be big enough to hold - 2*Lex::BINLOG_STMT_UNSAFE_COUNT bits. This is asserted in @c - issue_unsafe_warnings(). - - The first and second groups of bits are set by @c - decide_logging_format() when it detects that a warning should be - issued. The third group of bits is set from @c binlog_query() - when a warning is issued. All bits are cleared at the end of the - top-level statement. + The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of + unsafeness that the current statement has. This must be a member of THD and not of LEX, because warnings are detected and issued in different places (@c @@ -1722,20 +1587,14 @@ private: */ uint32 binlog_unsafe_warning_flags; - /** - Bit field that determines the type of tables that are about to be - be accessed while executing a statement. - */ - uint32 stmt_accessed_table_flag; - - void issue_unsafe_warnings(); - /* Number of outstanding table maps, i.e., table maps in the transaction cache. */ uint binlog_table_maps; public: + void issue_unsafe_warnings(); + uint get_binlog_table_maps() const { return binlog_table_maps; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 6411b194a8a..b70f33a6c3f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2300,6 +2300,7 @@ void Query_tables_list::reset_query_tables_list(bool init) sroutines_list_own_last= sroutines_list.next; sroutines_list_own_elements= 0; binlog_stmt_flags= 0; + stmt_accessed_table_flag= 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index f1b558b8be4..e6c4e69d1a6 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1276,6 +1276,125 @@ public: DBUG_VOID_RETURN; } + enum enum_stmt_accessed_table + { + /* + If a transactional table is about to be read. Note that + a write implies a read. + */ + STMT_READS_TRANS_TABLE= 0, + /* + If a transactional table is about to be updated. + */ + STMT_WRITES_TRANS_TABLE, + /* + If a non-transactional table is about to be read. Note that + a write implies a read. + */ + STMT_READS_NON_TRANS_TABLE, + /* + If a non-transactional table is about to be updated. + */ + STMT_WRITES_NON_TRANS_TABLE, + /* + If a temporary transactional table is about to be read. Note + that a write implies a read. + */ + STMT_READS_TEMP_TRANS_TABLE, + /* + If a temporary transactional table is about to be updated. + */ + STMT_WRITES_TEMP_TRANS_TABLE, + /* + If a temporary non-transactional table is about to be read. Note + that a write implies a read. + */ + STMT_READS_TEMP_NON_TRANS_TABLE, + /* + If a temporary non-transactional table is about to be updated. + */ + STMT_WRITES_TEMP_NON_TRANS_TABLE, + /* + The last element of the enumeration. Please, if necessary add + anything before this. + */ + STMT_ACCESS_TABLE_COUNT + }; + + /** + Sets the type of table that is about to be accessed while executing a + statement. + + @param accessed_table Enumeration type that defines the type of table, + e.g. temporary, transactional, non-transactional. + */ + inline void set_stmt_accessed_table(enum_stmt_accessed_table accessed_table) + { + DBUG_ENTER("THD::set_stmt_accessed_table"); + + DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT); + stmt_accessed_table_flag |= (1U << accessed_table); + + DBUG_VOID_RETURN; + } + + /** + Checks if a type of table is about to be accessed while executing a + statement. + + @param accessed_table Enumeration type that defines the type of table, + e.g. temporary, transactional, non-transactional. + + @return + @retval TRUE if the type of the table is about to be accessed + @retval FALSE otherwise + */ + inline bool stmt_accessed_table(enum_stmt_accessed_table accessed_table) + { + DBUG_ENTER("THD::stmt_accessed_table"); + + DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT); + + DBUG_RETURN((stmt_accessed_table_flag & (1U << accessed_table)) != 0); + } + + /** + Checks if a temporary table is about to be accessed while executing a + statement. + + @return + @retval TRUE if a temporary table is about to be accessed + @retval FALSE otherwise + */ + inline bool stmt_accessed_temp_table() + { + DBUG_ENTER("THD::stmt_accessed_temp_table"); + + DBUG_RETURN((stmt_accessed_table_flag & + ((1U << STMT_READS_TEMP_TRANS_TABLE) | + (1U << STMT_WRITES_TEMP_TRANS_TABLE) | + (1U << STMT_READS_TEMP_NON_TRANS_TABLE) | + (1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0); + } + + /** + Checks if a temporary non-transactional table is about to be accessed + while executing a statement. + + @return + @retval TRUE if a temporary non-transactional table is about to be + accessed + @retval FALSE otherwise + */ + inline bool stmt_accessed_non_trans_temp_table() + { + DBUG_ENTER("THD::stmt_accessed_non_trans_temp_table"); + + DBUG_RETURN((stmt_accessed_table_flag & + ((1U << STMT_READS_TEMP_NON_TRANS_TABLE) | + (1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0); + } + /** true if the parsed tree contains references to stored procedures or functions, false otherwise @@ -1317,6 +1436,12 @@ private: stored procedure has its own LEX object (but no own THD object). */ uint32 binlog_stmt_flags; + + /** + Bit field that determines the type of tables that are about to be + be accessed while executing a statement. + */ + uint32 stmt_accessed_table_flag; }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2ef8e9761b1..fbcfb3f49c2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5640,7 +5640,6 @@ void THD::reset_for_next_command() thd->reset_current_stmt_binlog_format_row(); thd->binlog_unsafe_warning_flags= 0; - thd->stmt_accessed_table_flag= 0; DBUG_PRINT("debug", ("is_current_stmt_binlog_format_row(): %d", |