#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 Hauglid | 9 Aug |