summaryrefslogtreecommitdiff
path: root/sql/sql_insert.cc
diff options
context:
space:
mode:
authorAlfranio Correia <alfranio.correia@sun.com>2010-01-07 15:39:11 +0000
committerAlfranio Correia <alfranio.correia@sun.com>2010-01-07 15:39:11 +0000
commit6f7929b1432441ce90180b6b578aa4e06b84224c (patch)
treee9c523980c16c054c3f387b57137661edf708689 /sql/sql_insert.cc
parentb79df3bc1998e9c33353a64fb90b8bd6d137642c (diff)
parent05989e249bd41d899be0544320e756e4ce4c2617 (diff)
downloadmariadb-git-6f7929b1432441ce90180b6b578aa4e06b84224c.tar.gz
merge mysql-5.1-rep+2-delivery1 --> mysql-5.1-rpl-merge
Conflicts: Text conflict in .bzr-mysql/default.conf Text conflict in mysql-test/extra/rpl_tests/rpl_loaddata.test Text conflict in mysql-test/r/mysqlbinlog2.result Text conflict in mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result Text conflict in mysql-test/suite/binlog/r/binlog_unsafe.result Text conflict in mysql-test/suite/rpl/r/rpl_insert_id.result Text conflict in mysql-test/suite/rpl/r/rpl_loaddata.result Text conflict in mysql-test/suite/rpl/r/rpl_stm_auto_increment_bug33029.result Text conflict in mysql-test/suite/rpl/r/rpl_udf.result Text conflict in mysql-test/suite/rpl/t/rpl_slow_query_log.test Text conflict in sql/field.h Text conflict in sql/log.cc Text conflict in sql/log_event.cc Text conflict in sql/log_event_old.cc Text conflict in sql/mysql_priv.h Text conflict in sql/share/errmsg.txt Text conflict in sql/sp.cc Text conflict in sql/sql_acl.cc Text conflict in sql/sql_base.cc Text conflict in sql/sql_class.h Text conflict in sql/sql_db.cc Text conflict in sql/sql_delete.cc Text conflict in sql/sql_insert.cc Text conflict in sql/sql_lex.cc Text conflict in sql/sql_lex.h Text conflict in sql/sql_load.cc Text conflict in sql/sql_table.cc Text conflict in sql/sql_update.cc Text conflict in sql/sql_view.cc Conflict adding files to storage/innobase. Created directory. Conflict because storage/innobase is not versioned, but has versioned children. Versioned directory. Conflict adding file storage/innobase. Moved existing file to storage/innobase.moved. Conflict adding files to storage/innobase/handler. Created directory. Conflict because storage/innobase/handler is not versioned, but has versioned children. Versioned directory. Contents conflict in storage/innobase/handler/ha_innodb.cc
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r--sql/sql_insert.cc94
1 files changed, 51 insertions, 43 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 147e03ddf55..f933ac46b62 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -899,6 +899,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
*/
query_cache_invalidate3(thd, table_list, 1);
}
+
+ if (thd->transaction.stmt.modified_non_trans_table)
+ thd->transaction.all.modified_non_trans_table= TRUE;
+
if ((changed && error <= 0) ||
thd->transaction.stmt.modified_non_trans_table ||
was_insert_delayed)
@@ -937,15 +941,13 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
*/
DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query(), thd->query_length(),
- transactional_table, FALSE,
- errcode))
+ thd->query(), thd->query_length(),
+ transactional_table, FALSE, FALSE,
+ errcode))
{
- error=1;
+ error= 1;
}
}
- if (thd->transaction.stmt.modified_non_trans_table)
- thd->transaction.all.modified_non_trans_table= TRUE;
}
DBUG_ASSERT(transactional_table || !changed ||
thd->transaction.stmt.modified_non_trans_table);
@@ -1786,6 +1788,7 @@ public:
table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0),
group_count(0)
{
+ DBUG_ENTER("Delayed_insert constructor");
thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user;
thd.security_ctx->host=(char*) my_localhost;
thd.current_tablenr=0;
@@ -1794,11 +1797,21 @@ public:
thd.lex->current_select= 0; // for my_message_sql
thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock()
/*
- Statement-based replication of INSERT DELAYED has problems with RAND()
- and user vars, so in mixed mode we go to row-based.
+ Statement-based replication of INSERT DELAYED has problems with
+ RAND() and user variables, so in mixed mode we go to row-based.
+ For normal commands, the unsafe flag is set at parse time.
+ However, since the flag is a member of the THD object, of which
+ the delayed_insert thread has its own copy, we must set the
+ statement to unsafe here and explicitly set row logging mode.
+
+ @todo set_current_stmt_binlog_format_row_if_mixed should not be
+ called by anything else than thd->decide_logging_format(). When
+ we call set_current_blah here, none of the checks in
+ decide_logging_format is made. We should probably call
+ thd->decide_logging_format() directly instead. /Sven
*/
- thd.lex->set_stmt_unsafe();
- thd.set_current_stmt_binlog_row_based_if_mixed();
+ thd.lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_DELAYED);
+ thd.set_current_stmt_binlog_format_row_if_mixed();
bzero((char*) &thd.net, sizeof(thd.net)); // Safety
bzero((char*) &table_list, sizeof(table_list)); // Safety
@@ -1813,6 +1826,7 @@ public:
delayed_lock= global_system_variables.low_priority_updates ?
TL_WRITE_LOW_PRIORITY : TL_WRITE;
pthread_mutex_unlock(&LOCK_thread_count);
+ DBUG_VOID_RETURN;
}
~Delayed_insert()
{
@@ -2393,8 +2407,8 @@ pthread_handler_t handle_delayed_insert(void *arg)
Statement-based replication of INSERT DELAYED has problems with RAND()
and user vars, so in mixed mode we go to row-based.
*/
- thd->lex->set_stmt_unsafe();
- thd->set_current_stmt_binlog_row_based_if_mixed();
+ thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_DELAYED);
+ thd->set_current_stmt_binlog_format_row_if_mixed();
/* Open table */
if (!(di->table= open_n_lock_single_table(thd, &di->table_list,
@@ -2620,6 +2634,7 @@ bool Delayed_insert::handle_inserts(void)
{
int error;
ulong max_rows;
+ bool has_trans = TRUE;
bool using_ignore= 0, using_opt_replace= 0,
using_bin_log= mysql_bin_log.is_open();
delayed_row *row;
@@ -2772,9 +2787,9 @@ bool Delayed_insert::handle_inserts(void)
*/
if (thd.binlog_query(THD::ROW_QUERY_TYPE,
row->query.str, row->query.length,
- FALSE, FALSE, errcode))
+ FALSE, FALSE, FALSE, errcode))
goto err;
-
+
thd.time_zone_used = backup_time_zone_used;
thd.variables.time_zone = backup_time_zone;
}
@@ -2847,9 +2862,11 @@ bool Delayed_insert::handle_inserts(void)
or trigger.
TODO: Move the logging to last in the sequence of rows.
- */
- if (thd.current_stmt_binlog_row_based &&
- thd.binlog_flush_pending_rows_event(TRUE))
+ */
+ has_trans= thd.lex->sql_command == SQLCOM_CREATE_TABLE ||
+ table->file->has_transactions();
+ if (thd.is_current_stmt_binlog_format_row() &&
+ thd.binlog_flush_pending_rows_event(TRUE, has_trans))
goto err;
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
@@ -2914,19 +2931,6 @@ bool mysql_insert_select_prepare(THD *thd)
DBUG_ENTER("mysql_insert_select_prepare");
/*
- Statement-based replication of INSERT ... SELECT ... LIMIT is not safe
- as order of rows is not defined, so in mixed mode we go to row-based.
-
- Note that we may consider a statement as safe if ORDER BY primary_key
- is present or we SELECT a constant. However it may confuse users to
- see very similiar statements replicated differently.
- */
- if (lex->current_select->select_limit)
- {
- lex->set_stmt_unsafe();
- thd->set_current_stmt_binlog_row_based_if_mixed();
- }
- /*
SELECT_LEX do not belong to INSERT statement, so we can't add WHERE
clause if table is VIEW
*/
@@ -3291,9 +3295,11 @@ bool select_insert::send_eof()
and ha_autocommit_or_rollback.
*/
query_cache_invalidate3(thd, table, 1);
- if (thd->transaction.stmt.modified_non_trans_table)
- thd->transaction.all.modified_non_trans_table= TRUE;
}
+
+ if (thd->transaction.stmt.modified_non_trans_table)
+ thd->transaction.all.modified_non_trans_table= TRUE;
+
DBUG_ASSERT(trans_table || !changed ||
thd->transaction.stmt.modified_non_trans_table);
@@ -3313,7 +3319,7 @@ bool select_insert::send_eof()
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
- trans_table, FALSE, errcode))
+ trans_table, FALSE, FALSE, errcode))
{
table->file->ha_release_auto_increment();
DBUG_RETURN(1);
@@ -3385,16 +3391,17 @@ void select_insert::abort() {
transactional_table= table->file->has_transactions();
if (thd->transaction.stmt.modified_non_trans_table)
{
+ if (!can_rollback_data())
+ thd->transaction.all.modified_non_trans_table= TRUE;
+
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
/* error of writing binary log is ignored */
(void) thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
thd->query_length(),
- transactional_table, FALSE, errcode);
+ transactional_table, FALSE, FALSE, errcode);
}
- if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
- thd->transaction.all.modified_non_trans_table= TRUE;
if (changed)
query_cache_invalidate3(thd, table, 1);
}
@@ -3638,11 +3645,11 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
virtual int do_postlock(TABLE **tables, uint count)
{
THD *thd= const_cast<THD*>(ptr->get_thd());
- if (int error= decide_logging_format(thd, &all_tables))
+ if (int error= thd->decide_logging_format(&all_tables))
return error;
TABLE const *const table = *tables;
- if (thd->current_stmt_binlog_row_based &&
+ if (thd->is_current_stmt_binlog_format_row() &&
!table->s->tmp_table &&
!ptr->get_create_info()->table_existed)
{
@@ -3667,7 +3674,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
temporary table, we need to start a statement transaction.
*/
if ((thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) == 0 &&
- thd->current_stmt_binlog_row_based &&
+ thd->is_current_stmt_binlog_format_row() &&
mysql_bin_log.is_open())
{
thd->binlog_start_trans_and_stmt();
@@ -3686,7 +3693,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
create_table->table_name);
- if (thd->current_stmt_binlog_row_based)
+ if (thd->is_current_stmt_binlog_format_row())
binlog_show_create_table(&(create_table->table), 1);
table= create_table->table;
}
@@ -3774,7 +3781,7 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
schema that will do a close_thread_tables(), destroying the
statement transaction cache.
*/
- DBUG_ASSERT(thd->current_stmt_binlog_row_based);
+ DBUG_ASSERT(thd->is_current_stmt_binlog_format_row());
DBUG_ASSERT(tables && *tables && count > 0);
char buf[2048];
@@ -3796,6 +3803,7 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
result= thd->binlog_query(THD::STMT_QUERY_TYPE,
query.ptr(), query.length(),
/* is_trans */ TRUE,
+ /* direct */ FALSE,
/* suppress_use */ FALSE,
errcode);
}
@@ -3815,7 +3823,7 @@ void select_create::send_error(uint errcode,const char *err)
DBUG_PRINT("info",
("Current statement %s row-based",
- thd->current_stmt_binlog_row_based ? "is" : "is NOT"));
+ thd->is_current_stmt_binlog_format_row() ? "is" : "is NOT"));
DBUG_PRINT("info",
("Current table (at 0x%lu) %s a temporary (or non-existant) table",
(ulong) table,
@@ -3898,7 +3906,7 @@ void select_create::abort()
thd->transaction.stmt.modified_non_trans_table= FALSE;
reenable_binlog(thd);
/* possible error of writing binary log is ignored deliberately */
- (void)thd->binlog_flush_pending_rows_event(TRUE);
+ (void) thd->binlog_flush_pending_rows_event(TRUE, TRUE);
if (m_plock)
{