Commit de54493e authored by unknown's avatar unknown

Bug #28677: SELECT on missing column gives extra error

Manual edit in order to merge from mysql-5.0 tree.


sql/sql_insert.cc:
  Bug#28677: Manual merge from 5.0:
  - moved everything beyond producing an error message out of select_insert::send_error 
    and into new override select_insert::abort() 
  - made corresponding move of code from select_create::send_error to
parent 0578f745
...@@ -3014,57 +3014,8 @@ void select_insert::send_error(uint errcode,const char *err) ...@@ -3014,57 +3014,8 @@ void select_insert::send_error(uint errcode,const char *err)
{ {
DBUG_ENTER("select_insert::send_error"); DBUG_ENTER("select_insert::send_error");
/* Avoid an extra 'unknown error' message if we already reported an error */
if (errcode != ER_UNKNOWN_ERROR && !thd->net.report_error)
my_message(errcode, err, MYF(0)); my_message(errcode, err, MYF(0));
/*
If the creation of the table failed (due to a syntax error, for
example), no table will have been opened and therefore 'table'
will be NULL. In that case, we still need to execute the rollback
and the end of the function.
*/
if (table)
{
/*
If we are not in prelocked mode, we end the bulk insert started
before.
*/
if (!thd->prelocked_mode)
table->file->ha_end_bulk_insert();
/*
If at least one row has been inserted/modified and will stay in
the table (the table doesn't have transactions) we must write to
the binlog (and the error code will make the slave stop).
For many errors (example: we got a duplicate key error while
inserting into a MyISAM table), no row will be added to the table,
so passing the error to the slave will not help since there will
be an error code mismatch (the inserts will succeed on the slave
with no error).
If table creation failed, the number of rows modified will also be
zero, so no check for that is made.
*/
if (info.copied || info.deleted || info.updated)
{
DBUG_ASSERT(table != NULL);
if (!table->file->has_transactions())
{
if (mysql_bin_log.is_open())
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
table->file->has_transactions(), FALSE);
if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table &&
!can_rollback_data())
thd->no_trans_update.all= TRUE;
query_cache_invalidate3(thd, table, 1);
}
}
table->file->ha_release_auto_increment();
}
ha_rollback_stmt(thd);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -3154,6 +3105,59 @@ bool select_insert::send_eof() ...@@ -3154,6 +3105,59 @@ bool select_insert::send_eof()
DBUG_RETURN(0); DBUG_RETURN(0);
} }
void select_insert::abort() {
DBUG_ENTER("select_insert::abort");
/*
If the creation of the table failed (due to a syntax error, for
example), no table will have been opened and therefore 'table'
will be NULL. In that case, we still need to execute the rollback
and the end of the function.
*/
if (table)
{
/*
If we are not in prelocked mode, we end the bulk insert started
before.
*/
if (!thd->prelocked_mode)
table->file->ha_end_bulk_insert();
/*
If at least one row has been inserted/modified and will stay in
the table (the table doesn't have transactions) we must write to
the binlog (and the error code will make the slave stop).
For many errors (example: we got a duplicate key error while
inserting into a MyISAM table), no row will be added to the table,
so passing the error to the slave will not help since there will
be an error code mismatch (the inserts will succeed on the slave
with no error).
If table creation failed, the number of rows modified will also be
zero, so no check for that is made.
*/
if (info.copied || info.deleted || info.updated)
{
DBUG_ASSERT(table != NULL);
if (!table->file->has_transactions())
{
if (mysql_bin_log.is_open())
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
table->file->has_transactions(), FALSE);
if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table &&
!can_rollback_data())
thd->no_trans_update.all= TRUE;
query_cache_invalidate3(thd, table, 1);
}
}
table->file->ha_release_auto_increment();
}
ha_rollback_stmt(thd);
DBUG_VOID_RETURN;
}
/*************************************************************************** /***************************************************************************
CREATE TABLE (SELECT) ... CREATE TABLE (SELECT) ...
...@@ -3572,6 +3576,14 @@ void select_create::abort() ...@@ -3572,6 +3576,14 @@ void select_create::abort()
{ {
DBUG_ENTER("select_create::abort"); DBUG_ENTER("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);
/* /*
We roll back the statement, including truncating the transaction We roll back the statement, including truncating the transaction
cache of the binary log, if the statement failed. cache of the binary log, if the statement failed.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment