summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoristruewing@stella.local <>2008-03-26 10:56:03 +0100
committeristruewing@stella.local <>2008-03-26 10:56:03 +0100
commitc882b871100a73cda874d39fd0ec41b7ad4f94e4 (patch)
tree9e5ba5e508b636add1b3ab6b1fb7ca5124f9db4d
parent0eff6e7be5f290854e5810173b2239c41c7b75a5 (diff)
parent2d44db25e7a7687af75a94e8e5ff94071c6e05f5 (diff)
downloadmariadb-git-c882b871100a73cda874d39fd0ec41b7ad4f94e4.tar.gz
Merge stella.local:/home2/mydev/mysql-5.1-ateam
into stella.local:/home2/mydev/mysql-5.1-axmrg
-rw-r--r--mysql-test/r/federated.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_ps.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_unsafe.result28
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_ps.test2
-rw-r--r--mysql-test/suite/binlog/t/binlog_unsafe.test21
-rw-r--r--mysql-test/suite/rpl/t/rpl_optimize.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_user_variables.test2
-rw-r--r--mysql-test/t/federated.test6
-rw-r--r--sql/sql_delete.cc13
-rw-r--r--sql/sql_insert.cc13
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_servers.cc76
-rw-r--r--sql/sql_update.cc13
-rw-r--r--storage/federated/ha_federated.cc1
14 files changed, 152 insertions, 31 deletions
diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result
index 65fafcb2166..21743c3a8a6 100644
--- a/mysql-test/r/federated.result
+++ b/mysql-test/r/federated.result
@@ -2092,6 +2092,8 @@ DROP TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=federated CONNECTION='mysql://@:://';
DROP TABLE t1;
+create server 's1' foreign data wrapper 'mysql' options (port 3306);
+drop server 's1';
End of 5.1 tests
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_ps.result b/mysql-test/suite/binlog/r/binlog_stm_ps.result
index 47934665116..1cf7429987e 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_ps.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_ps.result
@@ -10,6 +10,8 @@ execute s using @a;
prepare s from "insert into t1 select 100 limit ?";
set @a=100;
execute s using @a;
+Warnings:
+Warning 1592 Statement is not safe to log in statement format.
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; create table t1 (a int)
diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result
index e7c0702af46..1f7b217dc31 100644
--- a/mysql-test/suite/binlog/r/binlog_unsafe.result
+++ b/mysql-test/suite/binlog/r/binlog_unsafe.result
@@ -192,3 +192,31 @@ DROP PROCEDURE proc4;
DROP FUNCTION func5;
DROP PREPARE prep6;
DROP TABLE t1, t2, t3, trigger_table, trigger_table2;
+CREATE TABLE t1(a INT, b INT, KEY(a), PRIMARY KEY(b));
+INSERT INTO t1 SELECT * FROM t1 LIMIT 1;
+Warnings:
+Warning 1592 Statement is not safe to log in statement format.
+REPLACE INTO t1 SELECT * FROM t1 LIMIT 1;
+Warnings:
+Warning 1592 Statement is not safe to log in statement format.
+UPDATE t1 SET a=1 LIMIT 1;
+Warnings:
+Warning 1592 Statement is not safe to log in statement format.
+DELETE FROM t1 LIMIT 1;
+Warnings:
+Warning 1592 Statement is not safe to log in statement format.
+CREATE PROCEDURE p1()
+BEGIN
+INSERT INTO t1 SELECT * FROM t1 LIMIT 1;
+REPLACE INTO t1 SELECT * FROM t1 LIMIT 1;
+UPDATE t1 SET a=1 LIMIT 1;
+DELETE FROM t1 LIMIT 1;
+END|
+CALL p1();
+Warnings:
+Warning 1592 Statement is not safe to log in statement format.
+Warning 1592 Statement is not safe to log in statement format.
+Warning 1592 Statement is not safe to log in statement format.
+Warning 1592 Statement is not safe to log in statement format.
+DROP PROCEDURE p1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/binlog_stm_ps.test b/mysql-test/suite/binlog/t/binlog_stm_ps.test
index 83add5af3d7..55e3d30ad23 100644
--- a/mysql-test/suite/binlog/t/binlog_stm_ps.test
+++ b/mysql-test/suite/binlog/t/binlog_stm_ps.test
@@ -1,7 +1,7 @@
# This test is to verify replication with PS
-- source include/not_embedded.inc
--- source include/have_binlog_format_mixed_or_statement.inc
+-- source include/have_binlog_format_statement.inc
-- disable_query_log
reset master; # get rid of previous tests binlog
diff --git a/mysql-test/suite/binlog/t/binlog_unsafe.test b/mysql-test/suite/binlog/t/binlog_unsafe.test
index f57ab668c58..0d7059bc31f 100644
--- a/mysql-test/suite/binlog/t/binlog_unsafe.test
+++ b/mysql-test/suite/binlog/t/binlog_unsafe.test
@@ -236,3 +236,24 @@ DROP PROCEDURE proc4;
DROP FUNCTION func5;
DROP PREPARE prep6;
DROP TABLE t1, t2, t3, trigger_table, trigger_table2;
+#
+# BUG#34768 - nondeterministic INSERT using LIMIT logged in stmt mode if
+# binlog_format=mixed
+#
+CREATE TABLE t1(a INT, b INT, KEY(a), PRIMARY KEY(b));
+INSERT INTO t1 SELECT * FROM t1 LIMIT 1;
+REPLACE INTO t1 SELECT * FROM t1 LIMIT 1;
+UPDATE t1 SET a=1 LIMIT 1;
+DELETE FROM t1 LIMIT 1;
+delimiter |;
+CREATE PROCEDURE p1()
+BEGIN
+ INSERT INTO t1 SELECT * FROM t1 LIMIT 1;
+ REPLACE INTO t1 SELECT * FROM t1 LIMIT 1;
+ UPDATE t1 SET a=1 LIMIT 1;
+ DELETE FROM t1 LIMIT 1;
+END|
+delimiter ;|
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/rpl/t/rpl_optimize.test b/mysql-test/suite/rpl/t/rpl_optimize.test
index 80f0c052fc8..f4582ba1167 100644
--- a/mysql-test/suite/rpl/t/rpl_optimize.test
+++ b/mysql-test/suite/rpl/t/rpl_optimize.test
@@ -31,7 +31,9 @@ INSERT INTO t1 (a) SELECT null FROM t1;
save_master_pos;
# a few updates to force OPTIMIZE to do something
update t1 set b=(a/2*rand());
+--disable_warnings
delete from t1 order by b limit 10000;
+--enable_warnings
connection slave;
sync_with_master;
diff --git a/mysql-test/suite/rpl/t/rpl_user_variables.test b/mysql-test/suite/rpl/t/rpl_user_variables.test
index 21b2063c9f2..8d570f28f64 100644
--- a/mysql-test/suite/rpl/t/rpl_user_variables.test
+++ b/mysql-test/suite/rpl/t/rpl_user_variables.test
@@ -315,7 +315,9 @@ create table t1(a int);
insert into t1 values (1),(2);
prepare s1 from 'insert into t1 select a from t1 limit ?';
set @x='1.1';
+--disable_warnings
execute s1 using @x;
+--enable_warnings
select * from t1;
sync_slave_with_master;
connection slave;
diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test
index 9d36e0e0cfc..f6752d60f0f 100644
--- a/mysql-test/t/federated.test
+++ b/mysql-test/t/federated.test
@@ -1828,5 +1828,11 @@ DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=federated CONNECTION='mysql://@:://';
DROP TABLE t1;
+#
+# Coverage testing of CREATE SERVER.
+#
+create server 's1' foreign data wrapper 'mysql' options (port 3306);
+drop server 's1';
+
--echo End of 5.1 tests
source include/federated_cleanup.inc;
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 4e0853dbbc4..1456b66638d 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -418,6 +418,19 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
DBUG_ENTER("mysql_prepare_delete");
List<Item> all_fields;
+ /*
+ Statement-based replication of DELETE ... 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. However it may confuse users to see very similiar statements
+ replicated differently.
+ */
+ if (thd->lex->current_select->select_limit)
+ {
+ thd->lex->set_stmt_unsafe();
+ thd->set_current_stmt_binlog_row_based_if_mixed();
+ }
thd->lex->allow_sum_func= 0;
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 2be932a6040..58acf40964b 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2764,6 +2764,19 @@ 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
*/
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 2f6994c1244..ad22311a4ce 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -6464,6 +6464,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
result= 1;
if (grant_reload(thd))
result= 1;
+ if (servers_reload(thd))
+ result= 1; /* purecov: inspected */
}
if (tmp_thd)
{
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index 8203ca92eed..4390919f8c7 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -55,8 +55,8 @@ static bool get_server_from_table_to_cache(TABLE *table);
static int insert_server(THD *thd, FOREIGN_SERVER *server_options);
static int insert_server_record(TABLE *table, FOREIGN_SERVER *server);
static int insert_server_record_into_cache(FOREIGN_SERVER *server);
-static void prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
- FOREIGN_SERVER *server);
+static FOREIGN_SERVER *
+prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options);
/* drop functions */
static int delete_server_record(TABLE *table,
char *server_name,
@@ -166,6 +166,9 @@ end:
RETURN VALUES
FALSE Success
TRUE Error
+
+ TODO
+ Revert back to old list if we failed to load new one.
*/
static bool servers_load(THD *thd, TABLE_LIST *tables)
@@ -175,10 +178,9 @@ static bool servers_load(THD *thd, TABLE_LIST *tables)
bool return_val= TRUE;
DBUG_ENTER("servers_load");
- /* first, send all cached rows to sleep with the fishes, oblivion!
- I expect this crappy comment replaced */
- free_root(&mem, MYF(MY_MARK_BLOCKS_FREE));
my_hash_reset(&servers_cache);
+ free_root(&mem, MYF(0));
+ init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0);
while (!(read_record_info.read_record(&read_record_info)))
@@ -966,10 +968,14 @@ int create_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
server_options->server_name_length))
goto end;
- server= (FOREIGN_SERVER *)alloc_root(&mem,
- sizeof(FOREIGN_SERVER));
- prepare_server_struct_for_insert(server_options, server);
+ if (!(server= prepare_server_struct_for_insert(server_options)))
+ {
+ /* purecov: begin inspected */
+ error= ER_OUT_OF_RESOURCES;
+ goto end;
+ /* purecov: end */
+ }
error= insert_server(thd, server);
@@ -1040,52 +1046,64 @@ end:
SYNOPSIS
prepare_server_struct_for_insert()
LEX_SERVER_OPTIONS *server_options
- FOREIGN_SERVER *server
NOTES
+ As FOREIGN_SERVER members are allocated on mem_root, we do not need to
+ free them in case of error.
RETURN VALUE
- none
+ On success filled FOREIGN_SERVER, or NULL in case out of memory.
*/
-static void
-prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
- FOREIGN_SERVER *server)
+static FOREIGN_SERVER *
+prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options)
{
char *unset_ptr= (char*)"";
+ FOREIGN_SERVER *server;
DBUG_ENTER("prepare_server_struct");
+ if (!(server= (FOREIGN_SERVER *)alloc_root(&mem, sizeof(FOREIGN_SERVER))))
+ DBUG_RETURN(NULL); /* purecov: inspected */
+
/* these two MUST be set */
- server->server_name= strdup_root(&mem, server_options->server_name);
+ if (!(server->server_name= strdup_root(&mem, server_options->server_name)))
+ DBUG_RETURN(NULL); /* purecov: inspected */
server->server_name_length= server_options->server_name_length;
- server->host= server_options->host ?
- strdup_root(&mem, server_options->host) : unset_ptr;
+ if (!(server->host= server_options->host ?
+ strdup_root(&mem, server_options->host) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->db= server_options->db ?
- strdup_root(&mem, server_options->db) : unset_ptr;
+ if (!(server->db= server_options->db ?
+ strdup_root(&mem, server_options->db) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->username= server_options->username ?
- strdup_root(&mem, server_options->username) : unset_ptr;
+ if (!(server->username= server_options->username ?
+ strdup_root(&mem, server_options->username) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->password= server_options->password ?
- strdup_root(&mem, server_options->password) : unset_ptr;
+ if (!(server->password= server_options->password ?
+ strdup_root(&mem, server_options->password) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
/* set to 0 if not specified */
server->port= server_options->port > -1 ?
server_options->port : 0;
- server->socket= server_options->socket ?
- strdup_root(&mem, server_options->socket) : unset_ptr;
+ if (!(server->socket= server_options->socket ?
+ strdup_root(&mem, server_options->socket) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->scheme= server_options->scheme ?
- strdup_root(&mem, server_options->scheme) : unset_ptr;
+ if (!(server->scheme= server_options->scheme ?
+ strdup_root(&mem, server_options->scheme) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->owner= server_options->owner ?
- strdup_root(&mem, server_options->owner) : unset_ptr;
+ if (!(server->owner= server_options->owner ?
+ strdup_root(&mem, server_options->owner) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ DBUG_RETURN(server);
}
/*
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index eae755ca87a..87777707252 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -859,6 +859,19 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
SELECT_LEX *select_lex= &thd->lex->select_lex;
DBUG_ENTER("mysql_prepare_update");
+ /*
+ Statement-based replication of UPDATE ... 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. However it may confuse users to see very similiar statements
+ replicated differently.
+ */
+ if (thd->lex->current_select->select_limit)
+ {
+ thd->lex->set_stmt_unsafe();
+ thd->set_current_stmt_binlog_row_based_if_mixed();
+ }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
table_list->grant.want_privilege= table->grant.want_privilege=
(SELECT_ACL & ~table->grant.privilege);
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index ec99b47ce65..ed9a7a9cf8f 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -847,7 +847,6 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATED_SHARE *share, TABLE *table,
if (!share->port)
{
if (!share->hostname || strcmp(share->hostname, my_localhost) == 0)
- share->socket= (char*) MYSQL_UNIX_ADDR;
else
share->port= MYSQL_PORT;
}