summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_create.cc4
-rw-r--r--sql/share/errmsg.txt3
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/sql_base.cc4
-rw-r--r--sql/sql_class.cc19
-rw-r--r--sql/sql_class.h12
-rw-r--r--sql/sql_insert.cc1
-rw-r--r--sql/sql_lex.cc2
-rw-r--r--sql/sql_lex.h44
-rw-r--r--sql/sql_view.cc4
11 files changed, 79 insertions, 18 deletions
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 8ff78ef1b48..67ffbaba1ad 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -2341,7 +2341,7 @@ Create_udf_func::create(THD *thd, udf_func *udf, List<Item> *item_list)
if (item_list != NULL)
arg_count= item_list->elements;
- thd->lex->binlog_row_based_if_mixed= TRUE;
+ thd->lex->set_stmt_unsafe();
DBUG_ASSERT( (udf->type == UDFTYPE_FUNCTION)
|| (udf->type == UDFTYPE_AGGREGATE));
@@ -4527,7 +4527,7 @@ Create_func_uuid Create_func_uuid::s_singleton;
Item*
Create_func_uuid::create(THD *thd)
{
- thd->lex->binlog_row_based_if_mixed= TRUE;
+ thd->lex->set_stmt_unsafe();
return new (thd->mem_root) Item_func_uuid();
}
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 03990bbad0e..2e1240ab616 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -6059,3 +6059,6 @@ ER_SLAVE_INCIDENT
eng "The incident %s occured on the master. Message: %-.64s"
ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT
eng "Table has no partition for some existing values"
+ER_BINLOG_UNSAFE_STATEMENT
+ eng "Statement is not safe to log in statement format."
+ swe "Detta är inte säkert att logga i statement-format."
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index a2ce5111a25..6bd6360e642 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1873,7 +1873,7 @@ sp_head::restore_lex(THD *thd)
cannot switch from statement-based to row-based only for this
substatement).
*/
- if (sublex->binlog_row_based_if_mixed)
+ if (sublex->is_stmt_unsafe())
m_flags|= BINLOG_ROW_BASED_IF_MIXED;
/*
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 551707fa7bd..61407440a11 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -379,7 +379,7 @@ public:
the substatements not).
*/
if (m_flags & BINLOG_ROW_BASED_IF_MIXED)
- lex->binlog_row_based_if_mixed= TRUE;
+ lex->set_stmt_unsafe();
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 0f428da1fdb..0ec6ababab0 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3591,7 +3591,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
/*
CREATE ... SELECT UUID() locks no tables, we have to test here.
*/
- if (thd->lex->binlog_row_based_if_mixed)
+ if (thd->lex->is_stmt_unsafe())
thd->set_current_stmt_binlog_row_based_if_mixed();
if (!tables && !thd->lex->requires_prelocking())
@@ -3632,7 +3632,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
has_two_write_locked_tables_with_auto_increment(tables))
{
- thd->lex->binlog_row_based_if_mixed= TRUE;
+ thd->lex->set_stmt_unsafe();
thd->set_current_stmt_binlog_row_based_if_mixed();
}
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 4ee36f5864c..3e8b43f638e 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -201,7 +201,7 @@ THD::THD()
Open_tables_state(refresh_version), rli_fake(0),
lock_id(&main_lock_id),
user_time(0), in_sub_stmt(0),
- binlog_table_maps(0),
+ binlog_table_maps(0), binlog_flags(0UL),
global_read_lock(0), is_fatal_error(0),
rand_used(0), time_zone_used(0),
arg_of_last_insert_id_function(FALSE),
@@ -2888,6 +2888,23 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype,
to how you treat this.
*/
case THD::STMT_QUERY_TYPE:
+ if (lex->is_stmt_unsafe())
+ {
+ DBUG_ASSERT(this->query != NULL);
+ push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_BINLOG_UNSAFE_STATEMENT,
+ ER(ER_BINLOG_UNSAFE_STATEMENT));
+ if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
+ {
+
+ char warn_buf[MYSQL_ERRMSG_SIZE];
+ my_snprintf(warn_buf, MYSQL_ERRMSG_SIZE, "%s Statement: %s",
+ ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
+ sql_print_warning(warn_buf);
+ binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
+ }
+ }
+
/*
The MYSQL_LOG::write() function will set the STMT_END_F flag and
flush the pending rows event if necessary.
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3d53c19633e..7f933c331c3 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1048,6 +1048,17 @@ public:
private:
uint binlog_table_maps; // Number of table maps currently in the binlog
+
+ enum enum_binlog_flag {
+ BINLOG_FLAG_UNSAFE_STMT_PRINTED,
+ BINLOG_FLAG_COUNT
+ };
+
+ /**
+ Flags with per-thread information regarding the status of the
+ binary log.
+ */
+ uint32 binlog_flags;
public:
uint get_binlog_table_maps() const {
return binlog_table_maps;
@@ -1599,6 +1610,7 @@ public:
void restore_sub_statement_state(Sub_statement_state *backup);
void set_n_backup_active_arena(Query_arena *set, Query_arena *backup);
void restore_active_arena(Query_arena *set, Query_arena *backup);
+
inline void set_current_stmt_binlog_row_based_if_mixed()
{
/*
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index f6ae2df3750..b50568df9f6 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1533,6 +1533,7 @@ public:
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();
bzero((char*) &thd.net, sizeof(thd.net)); // Safety
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 4a162478388..685b915a8b9 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1719,7 +1719,7 @@ void Query_tables_list::reset_query_tables_list(bool init)
sroutines_list.empty();
sroutines_list_own_last= sroutines_list.next;
sroutines_list_own_elements= 0;
- binlog_row_based_if_mixed= FALSE;
+ binlog_stmt_flags= 0;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 850586c6098..7097c2de4fd 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -910,14 +910,6 @@ public:
uint sroutines_list_own_elements;
/*
- Tells if the parsing stage detected that some items require row-based
- binlogging to give a reliable binlog/replication, or if we will use
- stored functions or triggers which themselves need require row-based
- binlogging.
- */
- bool binlog_row_based_if_mixed;
-
- /*
These constructor and destructor serve for creation/destruction
of Query_tables_list instances which are used as backup storage.
*/
@@ -964,6 +956,41 @@ public:
query_tables_own_last= 0;
}
}
+
+ /**
+ Has the parser/scanner detected that this statement is unsafe?
+ */
+ inline bool is_stmt_unsafe() const {
+ return binlog_stmt_flags & (1U << BINLOG_STMT_FLAG_UNSAFE);
+ }
+
+ /**
+ Flag the current (top-level) statement as unsafe.
+
+ The flag will be reset after the statement has finished.
+
+ */
+ inline void set_stmt_unsafe() {
+ binlog_stmt_flags|= (1U << BINLOG_STMT_FLAG_UNSAFE);
+ }
+
+ inline void clear_stmt_unsafe() {
+ binlog_stmt_flags&= ~(1U << BINLOG_STMT_FLAG_UNSAFE);
+ }
+
+private:
+ enum enum_binlog_stmt_flag {
+ BINLOG_STMT_FLAG_UNSAFE,
+ BINLOG_STMT_FLAG_COUNT
+ };
+
+ /*
+ Tells if the parsing stage detected properties of the statement,
+ for example: that some items require row-based binlogging to give
+ a reliable binlog/replication, or if we will use stored functions
+ or triggers which themselves need require row-based binlogging.
+ */
+ uint32 binlog_stmt_flags;
};
@@ -1299,6 +1326,7 @@ typedef struct st_lex : public Query_tables_list
void restore_backup_query_tables_list(Query_tables_list *backup);
bool table_or_sp_used();
+
} LEX;
struct st_lex_local: public st_lex
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index c02fb7bcdc0..306c759359c 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1114,8 +1114,8 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
If the view's body needs row-based binlogging (e.g. the VIEW is created
from SELECT UUID()), the top statement also needs it.
*/
- if (lex->binlog_row_based_if_mixed)
- old_lex->binlog_row_based_if_mixed= TRUE;
+ if (lex->is_stmt_unsafe())
+ old_lex->set_stmt_unsafe();
view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
lex->can_be_merged());
LINT_INIT(view_main_select_tables);