List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:August 9 2010 12:11pm
Subject:bzr commit into mysql-5.5-merge branch (jon.hauglid:3166)
View as plain text  
#At file:///export/home/x/mysql-5.5-merge-test/ based on revid:georgi.kodinov@stripped

 3166 Jon Olav Hauglid	2010-08-09 [merge]
      manual merge from mysql-5.1-bugteam

    modified:
      mysql-test/r/insert.result
      mysql-test/t/insert.test
      sql/sql_insert.cc
      sql/sql_select.cc
      sql/sql_update.cc
=== modified file 'mysql-test/r/insert.result'
--- a/mysql-test/r/insert.result	2010-04-11 06:52:42 +0000
+++ b/mysql-test/r/insert.result	2010-08-09 12:11:29 +0000
@@ -671,3 +671,18 @@ drop table t1;
 #
 # End of 5.4 tests
 #
+#
+# Bug#54106 assert in Protocol::end_statement,
+#           INSERT IGNORE ... SELECT ... UNION SELECT ...
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 (a, a) VALUES (1, 1);
+ERROR 42000: Column 'a' specified twice
+INSERT IGNORE t1 (a, a) VALUES (1, 1);
+ERROR 42000: Column 'a' specified twice
+INSERT IGNORE t1 (a, a) SELECT 1,1;
+ERROR 42000: Column 'a' specified twice
+INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2;
+ERROR 42000: Column 'a' specified twice
+DROP TABLE t1;

=== modified file 'mysql-test/t/insert.test'
--- a/mysql-test/t/insert.test	2010-04-11 06:52:42 +0000
+++ b/mysql-test/t/insert.test	2010-08-09 12:11:29 +0000
@@ -525,3 +525,28 @@ drop table t1;
 --echo #
 --echo # End of 5.4 tests
 --echo #
+
+--echo #
+--echo # Bug#54106 assert in Protocol::end_statement,
+--echo #           INSERT IGNORE ... SELECT ... UNION SELECT ...
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT);
+
+--error ER_FIELD_SPECIFIED_TWICE
+INSERT INTO t1 (a, a) VALUES (1, 1);
+# Verify that ER_FIELD_SPECIFIED_TWICE is not ignorable
+--error ER_FIELD_SPECIFIED_TWICE
+INSERT IGNORE t1 (a, a) VALUES (1, 1);
+
+--error ER_FIELD_SPECIFIED_TWICE
+INSERT IGNORE t1 (a, a) SELECT 1,1;
+# Used to cause an assert
+--error ER_FIELD_SPECIFIED_TWICE
+INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2;
+
+DROP TABLE t1;

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2010-07-30 15:13:38 +0000
+++ b/sql/sql_insert.cc	2010-08-09 12:11:29 +0000
@@ -3043,6 +3043,9 @@ select_insert::prepare(List<Item> &value
     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));

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-07-30 15:13:38 +0000
+++ b/sql/sql_select.cc	2010-08-09 12:11:29 +0000
@@ -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);

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2010-07-28 11:17:19 +0000
+++ b/sql/sql_update.cc	2010-08-09 12:11:29 +0000
@@ -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));


Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20100809121129-02aw7a0ll128llv1.bundle
Thread
bzr commit into mysql-5.5-merge branch (jon.hauglid:3166) Jon Olav Hauglid9 Aug