summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc51
1 files changed, 49 insertions, 2 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index b5ede32e6fe..110f140afe0 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+/* Copyright (c) 2000, 2012, Oracle and/or its affiliates.
Copyright (c) 2010, 2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
@@ -217,7 +217,8 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list);
static void free_cache_entry(TABLE *entry);
static bool
has_write_table_with_auto_increment(TABLE_LIST *tables);
-
+static bool
+has_write_table_with_auto_increment_and_select(TABLE_LIST *tables);
uint cached_open_tables(void)
{
@@ -5729,9 +5730,20 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
*(ptr++)= table->table;
}
+ /*
+ DML statements that modify a table with an auto_increment column based on
+ rows selected from a table are unsafe as the order in which the rows are
+ fetched fron the select tables cannot be determined and may differ on
+ master and slave.
+ */
+ if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables &&
+ has_write_table_with_auto_increment_and_select(tables))
+ thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT);
+
/* We have to emulate LOCK TABLES if we are statement needs prelocking. */
if (thd->lex->requires_prelocking())
{
+
/*
A query that modifies autoinc column in sub-statement can make the
master and slave inconsistent.
@@ -9406,6 +9418,41 @@ has_write_table_with_auto_increment(TABLE_LIST *tables)
return 0;
}
+/*
+ checks if we have select tables in the table list and write tables
+ with auto-increment column.
+
+ SYNOPSIS
+ has_two_write_locked_tables_with_auto_increment_and_select
+ tables Table list
+
+ RETURN VALUES
+
+ -true if the table list has atleast one table with auto-increment column
+
+
+ and atleast one table to select from.
+ -false otherwise
+*/
+
+static bool
+has_write_table_with_auto_increment_and_select(TABLE_LIST *tables)
+{
+ bool has_select= false;
+ bool has_auto_increment_tables = has_write_table_with_auto_increment(tables);
+ for(TABLE_LIST *table= tables; table; table= table->next_global)
+ {
+ if (!table->placeholder() &&
+ (table->lock_type <= TL_READ_NO_INSERT))
+ {
+ has_select= true;
+ break;
+ }
+ }
+ return(has_select && has_auto_increment_tables);
+}
+
+
/*
Open and lock system tables for read.