diff options
author | istruewing@stella.local <> | 2008-03-26 10:56:03 +0100 |
---|---|---|
committer | istruewing@stella.local <> | 2008-03-26 10:56:03 +0100 |
commit | c882b871100a73cda874d39fd0ec41b7ad4f94e4 (patch) | |
tree | 9e5ba5e508b636add1b3ab6b1fb7ca5124f9db4d | |
parent | 0eff6e7be5f290854e5810173b2239c41c7b75a5 (diff) | |
parent | 2d44db25e7a7687af75a94e8e5ff94071c6e05f5 (diff) | |
download | mariadb-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.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_stm_ps.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_unsafe.result | 28 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/binlog_stm_ps.test | 2 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/binlog_unsafe.test | 21 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_optimize.test | 2 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_user_variables.test | 2 | ||||
-rw-r--r-- | mysql-test/t/federated.test | 6 | ||||
-rw-r--r-- | sql/sql_delete.cc | 13 | ||||
-rw-r--r-- | sql/sql_insert.cc | 13 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_servers.cc | 76 | ||||
-rw-r--r-- | sql/sql_update.cc | 13 | ||||
-rw-r--r-- | storage/federated/ha_federated.cc | 1 |
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; } |