diff options
-rw-r--r-- | mysql-test/r/errors.result | 14 | ||||
-rw-r--r-- | mysql-test/t/errors.test | 13 | ||||
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/sql_insert.cc | 92 | ||||
-rw-r--r-- | sql/sql_select.cc | 5 |
5 files changed, 80 insertions, 45 deletions
diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index 94debb1785f..022a32d9c9b 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -41,3 +41,17 @@ SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); a 1 DROP TABLE t1; +CREATE TABLE t1( a INT ); +SELECT b FROM t1; +ERROR 42S22: Unknown column 'b' in 'field list' +SHOW ERRORS; +Level Code Message +Error 1054 Unknown column 'b' in 'field list' +CREATE TABLE t2 SELECT b FROM t1; +ERROR 42S22: Unknown column 'b' in 'field list' +SHOW ERRORS; +Level Code Message +Error 1054 Unknown column 'b' in 'field list' +INSERT INTO t1 SELECT b FROM t1; +ERROR 42S22: Unknown column 'b' in 'field list' +DROP TABLE t1; diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index 4fbdcba635f..89579ec1739 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -53,4 +53,17 @@ INSERT INTO t1 VALUES(2),(3); SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); DROP TABLE t1; +# +# Bug #28677: SELECT on missing column gives extra error +# +CREATE TABLE t1( a INT ); +--error ER_BAD_FIELD_ERROR +SELECT b FROM t1; +SHOW ERRORS; +--error ER_BAD_FIELD_ERROR +CREATE TABLE t2 SELECT b FROM t1; +SHOW ERRORS; +--error ER_BAD_FIELD_ERROR +INSERT INTO t1 SELECT b FROM t1; +DROP TABLE t1; # End of 5.0 tests diff --git a/sql/sql_class.h b/sql/sql_class.h index 5f813e82307..ceb50bd669c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1951,6 +1951,7 @@ class select_insert :public select_result_interceptor { virtual void store_values(List<Item> &values); void send_error(uint errcode,const char *err); bool send_eof(); + void abort(); /* not implemented: select_insert is never re-used in prepared statements */ void cleanup(); }; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 5720758128e..02c5012b0c5 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2862,41 +2862,6 @@ void select_insert::send_error(uint errcode,const char *err) my_message(errcode, err, MYF(0)); - if (!table) - { - /* - This can only happen when using CREATE ... SELECT and the table was not - created becasue of an syntax error - */ - DBUG_VOID_RETURN; - } - if (!thd->prelocked_mode) - table->file->end_bulk_insert(); - /* - If at least one row has been inserted/modified and will stay in the table - (the table doesn't have transactions) (example: we got a duplicate key - error while inserting into a MyISAM table) we must write to the binlog (and - the error code will make the slave stop). - */ - if ((info.copied || info.deleted || info.updated) && - !table->file->has_transactions()) - { - if (last_insert_id) - thd->insert_id(last_insert_id); // For binary log - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, - table->file->has_transactions(), FALSE); - mysql_bin_log.write(&qinfo); - } - if (!table->s->tmp_table) - thd->no_trans_update.all= TRUE; - } - if (info.copied || info.deleted || info.updated) - { - query_cache_invalidate3(thd, table, 1); - } - ha_rollback_stmt(thd); DBUG_VOID_RETURN; } @@ -2952,6 +2917,49 @@ bool select_insert::send_eof() DBUG_RETURN(0); } +void select_insert::abort() +{ + DBUG_ENTER("select_insert::abort"); + + if (!table) + { + /* + This can only happen when using CREATE ... SELECT and the table was not + created becasue of an syntax error + */ + DBUG_VOID_RETURN; + } + if (!thd->prelocked_mode) + table->file->end_bulk_insert(); + /* + If at least one row has been inserted/modified and will stay in the table + (the table doesn't have transactions) (example: we got a duplicate key + error while inserting into a MyISAM table) we must write to the binlog (and + the error code will make the slave stop). + */ + if ((info.copied || info.deleted || info.updated) && + !table->file->has_transactions()) + { + if (last_insert_id) + thd->insert_id(last_insert_id); // For binary log + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, + table->file->has_transactions(), FALSE); + mysql_bin_log.write(&qinfo); + } + if (!table->s->tmp_table) + thd->no_trans_update.all= TRUE; + } + if (info.copied || info.deleted || info.updated) + { + query_cache_invalidate3(thd, table, 1); + } + ha_rollback_stmt(thd); + + DBUG_VOID_RETURN; + +} /*************************************************************************** CREATE TABLE (SELECT) ... @@ -3209,13 +3217,7 @@ void select_create::store_values(List<Item> &values) void select_create::send_error(uint errcode,const char *err) { - /* - Disable binlog, because we "roll back" partial inserts in ::abort - by removing the table, even for non-transactional tables. - */ - tmp_disable_binlog(thd); select_insert::send_error(errcode, err); - reenable_binlog(thd); } @@ -3240,6 +3242,14 @@ bool select_create::send_eof() void select_create::abort() { + /* + Disable binlog, because we "roll back" partial inserts in ::abort + by removing the table, even for non-transactional tables. + */ + tmp_disable_binlog(thd); + select_insert::abort(); + reenable_binlog(thd); + if (lock) { mysql_unlock_tables(thd, lock); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ea59cbbe9f2..d284ebbfb0f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -258,11 +258,8 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, thd->net.report_error)); res|= thd->net.report_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)); result->abort(); - } + DBUG_RETURN(res); } |