diff options
author | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2010-08-20 16:10:49 +0300 |
---|---|---|
committer | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2010-08-20 16:10:49 +0300 |
commit | c95f7a9816deb1a563ac2d0a7027d359c9b2a27b (patch) | |
tree | 131ffa70b19236e991dc12e5bdbbe8e4fb548d7c /sql | |
parent | cd8060a7ae482a065d8ce893b6f13e9137b01af5 (diff) | |
parent | c9d20d6c08fe85a852175887d5d361fe1d43b9c2 (diff) | |
download | mariadb-git-c95f7a9816deb1a563ac2d0a7027d359c9b2a27b.tar.gz |
merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/CMakeLists.txt | 18 | ||||
-rw-r--r-- | sql/events.cc | 2 | ||||
-rw-r--r-- | sql/events.h | 2 | ||||
-rw-r--r-- | sql/examples/CMakeLists.txt | 4 | ||||
-rw-r--r-- | sql/ha_partition.cc | 7 | ||||
-rw-r--r-- | sql/item.cc | 4 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_sum.cc | 6 | ||||
-rw-r--r-- | sql/log.cc | 2 | ||||
-rw-r--r-- | sql/log.h | 2 | ||||
-rw-r--r-- | sql/log_event.cc | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 8 | ||||
-rw-r--r-- | sql/mysqld.h | 6 | ||||
-rw-r--r-- | sql/share/CMakeLists.txt | 8 | ||||
-rw-r--r-- | sql/sp_head.cc | 21 | ||||
-rw-r--r-- | sql/sql_class.cc | 126 | ||||
-rw-r--r-- | sql/sql_class.h | 161 | ||||
-rw-r--r-- | sql/sql_insert.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 125 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 46 | ||||
-rw-r--r-- | sql/sql_select.h | 2 | ||||
-rw-r--r-- | sql/sql_update.cc | 70 | ||||
-rw-r--r-- | sql/sys_vars.h | 14 |
27 files changed, 320 insertions, 335 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index e8a594c4d8b..06e1a77e33e 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2006 MySQL AB +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -11,8 +11,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include @@ -42,7 +41,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 +81,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 +188,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 +266,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/events.cc b/sql/events.cc index 5379ec2c9eb..99304a1c460 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -76,7 +76,7 @@ Event_queue *Events::event_queue; Event_scheduler *Events::scheduler; Event_db_repository *Events::db_repository; -uint Events::opt_event_scheduler= Events::EVENTS_OFF; +ulong Events::opt_event_scheduler= Events::EVENTS_OFF; mysql_mutex_t Events::LOCK_event_metadata; bool Events::check_system_tables_error= FALSE; diff --git a/sql/events.h b/sql/events.h index c84c37b881d..1482e736d29 100644 --- a/sql/events.h +++ b/sql/events.h @@ -91,7 +91,7 @@ public: */ enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED }; /* Protected using LOCK_global_system_variables only. */ - static uint opt_event_scheduler; + static ulong opt_event_scheduler; static mysql_mutex_t LOCK_event_metadata; static bool check_if_system_tables_error(); static bool start(); diff --git a/sql/examples/CMakeLists.txt b/sql/examples/CMakeLists.txt index 3c5cc23ec3b..abe4de402bf 100644 --- a/sql/examples/CMakeLists.txt +++ b/sql/examples/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2006 MySQL AB +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFE_MUTEX") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFE_MUTEX") diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 7891f658f45..e6915b45a97 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -2446,9 +2446,14 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root) tot_partition_words= (m_tot_parts + 3) / 4; engine_array= (handlerton **) my_alloca(m_tot_parts * sizeof(handlerton*)); for (i= 0; i < m_tot_parts; i++) + { engine_array[i]= ha_resolve_by_legacy_type(ha_thd(), (enum legacy_db_type) - *(uchar *) ((file_buffer) + 12 + i)); + *(uchar *) ((file_buffer) + + 12 + i)); + if (!engine_array[i]) + goto err3; + } address_tot_name_len= file_buffer + 12 + 4 * tot_partition_words; tot_name_words= (uint4korr(address_tot_name_len) + 3) / 4; if (len_words != (tot_partition_words + tot_name_words + 4)) 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/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 85565b735d4..c18b79371df 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4617,7 +4617,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref) return TRUE; } - if (escape_item->const_item()) + if (escape_item->const_item() && !thd->lex->view_prepare_mode) { /* If we are on execution stage */ String *escape_str= escape_item->val_str(&cmp.value1); diff --git a/sql/item_func.cc b/sql/item_func.cc index c6a5a67cd2d..eab44170f36 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2532,7 +2532,7 @@ void Item_func_min_max::fix_length_and_dec() unsigned_flag)); } else if (cmp_type == REAL_RESULT) - max_length= float_length(decimals); + fix_char_length(float_length(decimals)); cached_field_type= agg_field_type(args, arg_count); } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index db5710db4ee..bd6e96aedc6 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -984,7 +984,8 @@ bool Aggregator_distinct::add() { int error; copy_fields(tmp_table_param); - copy_funcs(tmp_table_param->items_to_copy); + if (copy_funcs(tmp_table_param->items_to_copy, table->in_use)) + return TRUE; for (Field **field=table->field ; *field ; field++) if ((*field)->is_real_null(0)) @@ -3153,7 +3154,8 @@ bool Item_func_group_concat::add() if (always_null) return 0; copy_fields(tmp_table_param); - copy_funcs(tmp_table_param->items_to_copy); + if (copy_funcs(tmp_table_param->items_to_copy, table->in_use)) + return TRUE; for (uint i= 0; i < arg_count_field; i++) { 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.h b/sql/log.h index 6e87b6cbade..c8f565e6ef5 100644 --- a/sql/log.h +++ b/sql/log.h @@ -394,7 +394,7 @@ public: /* Use this to start writing a new log file */ void new_file(); - bool write(Log_event* event_info); + bool write(Log_event* event_info); // binary log write bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident); bool write_incident(THD *thd, bool lock); 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/mysqld.cc b/sql/mysqld.cc index afc515a9d8c..eaa3e27cf29 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -439,10 +439,10 @@ static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */ #endif uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; uint mysqld_port_timeout; -uint delay_key_write_options; +ulong delay_key_write_options; uint protocol_version; uint lower_case_table_names; -uint tc_heuristic_recover= 0; +ulong tc_heuristic_recover= 0; uint volatile thread_count; int32 thread_running; ulong thread_created; @@ -453,7 +453,7 @@ ulong slow_launch_time, slave_open_temp_tables; ulong open_files_limit, max_binlog_size, max_relay_log_size; ulong slave_trans_retries; uint slave_net_timeout; -uint slave_exec_mode_options; +ulong slave_exec_mode_options; ulonglong slave_type_conversions_options; ulong thread_cache_size=0, thread_pool_size= 0; ulong binlog_cache_size=0; @@ -552,7 +552,7 @@ char *mysql_data_home= const_cast<char*>("."); const char *mysql_real_data_home_ptr= mysql_real_data_home; char server_version[SERVER_VERSION_LENGTH]; char *mysqld_unix_port, *opt_mysql_tmpdir; -uint thread_handling; +ulong thread_handling; /** name of reference on left expression in rewritten IN subquery */ const char *in_left_expr_name= "<left expr>"; diff --git a/sql/mysqld.h b/sql/mysqld.h index 22e757e6e8a..9605128166d 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -105,7 +105,7 @@ extern uint connection_count; extern my_bool opt_safe_user_create; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; extern my_bool opt_slave_compressed_protocol, use_temp_pool; -extern uint slave_exec_mode_options; +extern ulong slave_exec_mode_options; extern ulonglong slave_type_conversions_options; extern my_bool opt_readonly, lower_case_file_system; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; @@ -136,7 +136,7 @@ extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb; extern my_bool relay_log_recovery; extern uint test_flags,select_errors,ha_open_options; extern uint protocol_version, mysqld_port, dropping_tables; -extern uint delay_key_write_options; +extern ulong delay_key_write_options; extern char *opt_logname, *opt_slow_logname; extern char *opt_backup_history_logname, *opt_backup_progress_logname, *opt_backup_settings_name; @@ -300,7 +300,7 @@ extern ulong specialflag; extern uint mysql_data_home_len; extern uint mysql_real_data_home_len; extern const char *mysql_real_data_home_ptr; -extern uint thread_handling; +extern ulong thread_handling; extern MYSQL_PLUGIN_IMPORT char *mysql_data_home; extern char server_version[SERVER_VERSION_LENGTH]; extern MYSQL_PLUGIN_IMPORT char mysql_real_data_home[]; diff --git a/sql/share/CMakeLists.txt b/sql/share/CMakeLists.txt index 14de851aaa2..f8fd51fda23 100644 --- a/sql/share/CMakeLists.txt +++ b/sql/share/CMakeLists.txt @@ -1,17 +1,17 @@ -# Copyright (C) 2009 Sun Microsystems, Inc +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA SET (dirs danish 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..958a3c17e79 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), @@ -3640,7 +3639,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) { DBUG_ENTER("THD::decide_logging_format"); DBUG_PRINT("info", ("query: %s", query())); - DBUG_PRINT("info", ("variables.binlog_format: %u", + DBUG_PRINT("info", ("variables.binlog_format: %lu", variables.binlog_format)); DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x", lex->get_stmt_unsafe_flags())); @@ -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))); @@ -4000,7 +4012,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) DBUG_PRINT("info", ("decision: no logging since " "mysql_bin_log.is_open() = %d " "and (options & OPTION_BIN_LOG) = 0x%llx " - "and binlog_format = %u " + "and binlog_format = %lu " "and binlog_filter->db_ok(db) = %d", mysql_bin_log.is_open(), (variables.option_bits & OPTION_BIN_LOG), @@ -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..5acdda7f40b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -114,7 +114,7 @@ extern bool volatile shutdown_in_progress; #define TC_HEURISTIC_RECOVER_COMMIT 1 #define TC_HEURISTIC_RECOVER_ROLLBACK 2 -extern uint tc_heuristic_recover; +extern ulong tc_heuristic_recover; typedef struct st_user_var_events { @@ -426,13 +426,13 @@ typedef struct system_variables ulong log_warnings; ulong group_concat_max_len; - uint binlog_format; ///< binlog format for this thd (see enum_binlog_format) + ulong binlog_format; ///< binlog format for this thd (see enum_binlog_format) my_bool binlog_direct_non_trans_update; my_bool sql_log_bin; - uint completion_type; - uint query_cache_type; - uint tx_isolation; - uint updatable_views_with_limit; + ulong completion_type; + ulong query_cache_type; + ulong tx_isolation; + ulong updatable_views_with_limit; uint max_user_connections; /** In slave thread we need to know in behalf of which @@ -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_insert.cc b/sql/sql_insert.cc index a0d347f48de..326a5defa9b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3043,6 +3043,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) we are fixing fields from insert list. */ lex->current_select= &lex->select_lex; + + /* Errors during check_insert_fields() should not be ignored. */ + lex->current_select->no_error= FALSE; res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) || check_insert_fields(thd, table_list, *fields, values, !insert_into_view, 1, &map)); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 424dba78d39..1d288f3de20 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2297,6 +2297,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", diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 7e8c1fed999..e3323260373 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -3025,11 +3025,11 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, Allocate temporary space for the value of the tristate. This option will have a limited lifetime and is not used beyond server initialization. - GET_ENUM value is an unsigned integer. + GET_ENUM value is an unsigned long integer. */ options[0].value= options[1].value= - (uchar **)alloc_root(mem_root, sizeof(uint)); - *((uint*) options[0].value)= (uint) options[0].def_value; + (uchar **)alloc_root(mem_root, sizeof(ulong)); + *((ulong*) options[0].value)= (ulong) options[0].def_value; options+= 2; } @@ -3328,7 +3328,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, list is always the <plugin name> option value. */ if (!tmp->is_mandatory) - plugin_load_policy= (enum_plugin_load_policy)*(uint*)opts[0].value; + plugin_load_policy= (enum_plugin_load_policy)*(ulong*)opts[0].value; } disable_plugin= (plugin_load_policy == PLUGIN_OFF); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ccfd93a1bc8..2dabeeaa22e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6914,6 +6914,8 @@ bool error_if_full_join(JOIN *join) { if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) { + /* This error should not be ignored. */ + join->select_lex->no_error= FALSE; my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); return(1); @@ -12721,7 +12723,9 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (!end_of_records) { copy_fields(&join->tmp_table_param); - copy_funcs(join->tmp_table_param.items_to_copy); + if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) + DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ + if (!join->having || join->having->val_int()) { int error; @@ -12811,7 +12815,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), memcpy(table->record[0]+key_part->offset, group->buff, 1); } init_tmptable_sum_functions(join->sum_funcs); - copy_funcs(join->tmp_table_param.items_to_copy); + if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) + DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ if ((error=table->file->ha_write_row(table->record[0]))) { if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param, @@ -12846,7 +12851,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), init_tmptable_sum_functions(join->sum_funcs); copy_fields(&join->tmp_table_param); // Groups are copied twice. - copy_funcs(join->tmp_table_param.items_to_copy); + if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) + DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ if (!(error=table->file->ha_write_row(table->record[0]))) join->send_records++; // New group @@ -12933,7 +12939,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (idx < (int) join->send_group_parts) { copy_fields(&join->tmp_table_param); - copy_funcs(join->tmp_table_param.items_to_copy); + if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) + DBUG_RETURN(NESTED_LOOP_ERROR); if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1])) DBUG_RETURN(NESTED_LOOP_ERROR); if (join->procedure) @@ -15805,14 +15812,39 @@ update_sum_func(Item_sum **func_ptr) return 0; } -/** Copy result of functions to record in tmp_table. */ +/** + Copy result of functions to record in tmp_table. -void -copy_funcs(Item **func_ptr) + Uses the thread pointer to check for errors in + some of the val_xxx() methods called by the + save_in_result_field() function. + TODO: make the Item::val_xxx() return error code + + @param func_ptr array of the function Items to copy to the tmp table + @param thd pointer to the current thread for error checking + @retval + FALSE if OK + @retval + TRUE on error +*/ + +bool +copy_funcs(Item **func_ptr, const THD *thd) { Item *func; for (; (func = *func_ptr) ; func_ptr++) + { func->save_in_result_field(1); + /* + Need to check the THD error state because Item::val_xxx() don't + return error code, but can generate errors + TODO: change it for a real status check when Item::val_xxx() + are extended to return status code. + */ + if (thd->is_error()) + return TRUE; + } + return FALSE; } diff --git a/sql/sql_select.h b/sql/sql_select.h index 40f9e6d4054..77fff4ee24c 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -606,7 +606,7 @@ bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, List<Item> &new_list1, List<Item> &new_list2, uint elements, List<Item> &fields); void copy_fields(TMP_TABLE_PARAM *param); -void copy_funcs(Item **func_ptr); +bool copy_funcs(Item **func_ptr, const THD *thd); bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, int error, bool ignore_last_dupp_error); uint find_shortest_key(TABLE *table, const key_map *usable_keys); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 35478e28520..68440f6623a 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1145,57 +1145,6 @@ int mysql_multi_update_prepare(THD *thd) } -/** - Implementation of the safe update options during UPDATE IGNORE. This syntax - causes an UPDATE statement to ignore all errors. In safe update mode, - however, we must never ignore the ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE. There - is a special hook in my_message_sql that will otherwise delete all errors - when the IGNORE option is specified. - - In the future, all IGNORE handling should be used with this class and all - traces of the hack outlined below should be removed. - - - The parser detects IGNORE option and sets thd->lex->ignore= 1 - - - In JOIN::optimize, if this is set, then - thd->lex->current_select->no_error gets set. - - - In my_message_sql(), if the flag above is set then any error is - unconditionally converted to a warning. - - We are moving in the direction of using Internal_error_handler subclasses - to do all such error tweaking, please continue this effort if new bugs - appear. - */ -class Safe_dml_handler : public Internal_error_handler { - -private: - bool m_handled_error; - -public: - explicit Safe_dml_handler() : m_handled_error(FALSE) {} - - bool handle_condition(THD *thd, - uint sql_errno, - const char* sqlstate, - MYSQL_ERROR::enum_warning_level level, - const char* msg, - MYSQL_ERROR ** cond_hdl) - { - if (level == MYSQL_ERROR::WARN_LEVEL_ERROR && - sql_errno == ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE) - { - thd->stmt_da->set_error_status(thd, sql_errno, msg, sqlstate); - m_handled_error= TRUE; - return TRUE; - } - return FALSE; - } - - bool handled_error() { return m_handled_error; } - -}; - /* Setup multi-update handling and call SELECT to do the join */ @@ -1229,11 +1178,6 @@ bool mysql_multi_update(THD *thd, List<Item> total_list; - Safe_dml_handler handler; - bool using_handler= thd->variables.option_bits & OPTION_SAFE_UPDATES; - if (using_handler) - thd->push_internal_handler(&handler); - res= mysql_select(thd, &select_lex->ref_pointer_array, table_list, select_lex->with_wild, total_list, @@ -1243,21 +1187,9 @@ bool mysql_multi_update(THD *thd, OPTION_SETUP_TABLES_DONE, *result, unit, select_lex); - if (using_handler) - { - Internal_error_handler *top_handler; - top_handler= thd->pop_internal_handler(); - DBUG_ASSERT(&handler == top_handler); - } - DBUG_PRINT("info",("res: %d report_error: %d", res, (int) thd->is_error())); res|= thd->is_error(); - /* - Todo: remove below code and make Safe_dml_handler do error processing - instead. That way we can return the actual error instead of - ER_UNKNOWN_ERROR. - */ - if (unlikely(res) && (!using_handler || !handler.handled_error())) + if (unlikely(res)) { /* If we had a another error reported earlier then this will be ignored */ (*result)->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR)); diff --git a/sql/sys_vars.h b/sql/sys_vars.h index ca3fc99deba..ee6b429b04a 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -271,28 +271,28 @@ public: deprecated_version, substitute) { option.var_type= GET_ENUM; - global_var(uint)= def_val; + global_var(ulong)= def_val; DBUG_ASSERT(def_val < typelib.count); - DBUG_ASSERT(size == sizeof(uint)); + DBUG_ASSERT(size == sizeof(ulong)); } bool session_update(THD *thd, set_var *var) { - session_var(thd, uint)= var->save_result.ulonglong_value; + session_var(thd, ulong)= var->save_result.ulonglong_value; return false; } bool global_update(THD *thd, set_var *var) { - global_var(uint)= var->save_result.ulonglong_value; + global_var(ulong)= var->save_result.ulonglong_value; return false; } void session_save_default(THD *thd, set_var *var) - { var->save_result.ulonglong_value= global_var(uint); } + { var->save_result.ulonglong_value= global_var(ulong); } void global_save_default(THD *thd, set_var *var) { var->save_result.ulonglong_value= option.def_value; } uchar *session_value_ptr(THD *thd, LEX_STRING *base) - { return (uchar*)typelib.type_names[session_var(thd, uint)]; } + { return (uchar*)typelib.type_names[session_var(thd, ulong)]; } uchar *global_value_ptr(THD *thd, LEX_STRING *base) - { return (uchar*)typelib.type_names[global_var(uint)]; } + { return (uchar*)typelib.type_names[global_var(ulong)]; } }; /** |