From b586bed728725af61d44e22a5dde68504d28721f Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 9 Feb 2010 12:53:13 +0400 Subject: BUG#49902 - SELECT returns incorrect results Queries optimized with GROUP_MIN_MAX didn't cleanup KEYREAD optimization properly. As a result subsequent queries may return incomplete rows (fields are initialized to default values). mysql-test/r/group_min_max.result: A test case for BUG#49902. mysql-test/t/group_min_max.test: A test case for BUG#49902. sql/opt_range.cc: Refactor of KEYREAD optimization switch so that KEYREAD handler state is in sync with st_table::key_read flag. All SQL code is supposed to switch KEYREAD optimization via st_table::set_keyread(). sql/opt_sum.cc: Refactor of KEYREAD optimization switch so that KEYREAD handler state is in sync with st_table::key_read flag. All SQL code is supposed to switch KEYREAD optimization via st_table::set_keyread(). sql/sql_select.cc: Refactor of KEYREAD optimization switch so that KEYREAD handler state is in sync with st_table::key_read flag. All SQL code is supposed to switch KEYREAD optimization via st_table::set_keyread(). sql/sql_update.cc: Refactor of KEYREAD optimization switch so that KEYREAD handler state is in sync with st_table::key_read flag. All SQL code is supposed to switch KEYREAD optimization via st_table::set_keyread(). sql/table.cc: Refactor of KEYREAD optimization switch so that KEYREAD handler state is in sync with st_table::key_read flag. All SQL code is supposed to switch KEYREAD optimization via st_table::set_keyread(). sql/table.h: Refactor of KEYREAD optimization switch so that KEYREAD handler state is in sync with st_table::key_read flag. All SQL code is supposed to switch KEYREAD optimization via st_table::set_keyread(). --- sql/sql_update.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'sql/sql_update.cc') diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 433e2619aca..32add8679ef 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -397,10 +397,7 @@ int mysql_update(THD *thd, matching rows before updating the table! */ if (used_index < MAX_KEY && old_covering_keys.is_set(used_index)) - { - table->key_read=1; table->mark_columns_used_by_index(used_index); - } else { table->use_all_columns(); @@ -844,11 +841,7 @@ int mysql_update(THD *thd, err: delete select; free_underlaid_joins(thd, select_lex); - if (table->key_read) - { - table->key_read=0; - table->file->extra(HA_EXTRA_NO_KEYREAD); - } + table->set_keyread(FALSE); thd->abort_on_warning= 0; DBUG_RETURN(1); } -- cgit v1.2.1 From 4661b593b6565e1cc841c44c084c71d7937561f0 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Wed, 10 Feb 2010 15:37:34 +0100 Subject: Bug#49534: multitable IGNORE update with sql_safe_updates error causes debug assertion The IGNORE option of the multiple-table UPDATE command was not intended to suppress errors caused by the sql_safe_updates mode. This flag will raise an error if the execution of UPDATE does not use a key for row retrieval, and should continue do so regardless of the IGNORE option. However the implementation of IGNORE does not support exceptions to the rule; it always converts errors to warnings and cannot be extended. The Internal_error_handler interface offers the infrastructure to handle individual errors, making sure that the error raised by sql_safe_updates is not silenced. Fixed by implementing an Internal_error_handler and using it for UPDATE IGNORE commands. --- sql/sql_update.cc | 87 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 10 deletions(-) (limited to 'sql/sql_update.cc') diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 32add8679ef..84610630d62 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1188,6 +1188,56 @@ reopen_tables: } +/** + 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_error(uint sql_errno, + const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd) + { + if (level == MYSQL_ERROR::WARN_LEVEL_ERROR && + sql_errno == ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE) + + { + thd->main_da.set_error_status(thd, sql_errno, message); + 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 */ @@ -1216,18 +1266,35 @@ bool mysql_multi_update(THD *thd, MODE_STRICT_ALL_TABLES)); List total_list; + + Safe_dml_handler handler; + bool using_handler= thd->options & 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, - conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL, - (ORDER *)NULL, - options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | - OPTION_SETUP_TABLES_DONE, - result, unit, select_lex); - DBUG_PRINT("info",("res: %d report_error: %d", res, - (int) thd->is_error())); + table_list, select_lex->with_wild, + total_list, + conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL, + (ORDER *)NULL, + options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | + OPTION_SETUP_TABLES_DONE, + result, unit, select_lex); + + if (using_handler) + { + Internal_error_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(); - if (unlikely(res)) + /* + 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 we had a another error reported earlier then this will be ignored */ result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR)); -- cgit v1.2.1 From 01995d1b2169e50a83bac2cedaac558686d6927c Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Mon, 22 Feb 2010 14:23:47 +0100 Subject: Bug #43414 Parenthesis (and other) warnings compiling MySQL with gcc 4.3.2 This is the final patch in the context of this bug. cmd-line-utils/readline/rlmbutil.h: Changed in a previous patch, reverted by a backport. cmd-line-utils/readline/text.c: Static var initialization. extra/yassl/include/yassl_error.hpp: SetErrorString handles errors outside of the YasslError enum. extra/yassl/src/ssl.cpp: SetErrorString handles errors outside of the YasslError enum. extra/yassl/src/yassl_error.cpp: SetErrorString handles errors outside of the YasslError enum. --- sql/sql_update.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_update.cc') diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 84610630d62..63af275cef3 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1283,7 +1283,8 @@ bool mysql_multi_update(THD *thd, if (using_handler) { - Internal_error_handler *top_handler= thd->pop_internal_handler(); + Internal_error_handler *top_handler; + top_handler= thd->pop_internal_handler(); DBUG_ASSERT(&handler == top_handler); } -- cgit v1.2.1