diff options
author | unknown <antony@pcg5ppc.xiphis.org> | 2007-07-23 23:35:43 -0700 |
---|---|---|
committer | unknown <antony@pcg5ppc.xiphis.org> | 2007-07-23 23:35:43 -0700 |
commit | 0f85ae9f2cb88dd8a17aaa5f69639e3e22fd0f9f (patch) | |
tree | 08599e66c46ca787fcb363a53ba51081b988fd4e | |
parent | 7d3cecca0ae25abdc2943e79410a19bdde5fff54 (diff) | |
download | mariadb-git-0f85ae9f2cb88dd8a17aaa5f69639e3e22fd0f9f.tar.gz |
Bug#25714
"getGeneratedKeys() does not work with FEDERATED table"
mysql_insert() expected the storage engine to update the row data
during the write_row() operation with the value of the new auto-
increment field. The field must be updated when only one row has
been inserted as mysql_insert() would ignore the thd->last_insert.
This patch implements HA_STATUS_AUTO support in ha_federated::info()
and ensures that ha_federated::write_row() does update the row's
auto-increment value.
The test case was written in C as the protocol's 'id' value is
accessible through libmysqlclient and not via SQL statements.
mysql-test-run.pl was extended to enable running the test binary.
mysql-test/mysql-test-run.pl:
bug25714
implement support to run C test for bug25714
sql/ha_federated.cc:
bug25714
The storage engine instance property auto_increment_value was not
being set.
mysql_insert() requires that the storage engine updates the row with
the auto-increment value, especially when only inserting one row.
Implement support for ha_federated::info(HA_STATUS_AUTO)
tests/Makefile.am:
bug25714
build C test for bug
mysql-test/include/have_bug25714.inc:
New BitKeeper file ``mysql-test/include/have_bug25714.inc''
mysql-test/r/federated_bug_25714.result:
New BitKeeper file ``mysql-test/r/federated_bug_25714.result''
mysql-test/r/have_bug25714.require:
New BitKeeper file ``mysql-test/r/have_bug25714.require''
mysql-test/t/federated_bug_25714.test:
New BitKeeper file ``mysql-test/t/federated_bug_25714.test''
tests/bug25714.c:
New BitKeeper file ``tests/bug25714.c''
-rw-r--r-- | mysql-test/include/have_bug25714.inc | 7 | ||||
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 12 | ||||
-rw-r--r-- | mysql-test/r/federated_bug_25714.result | 56 | ||||
-rw-r--r-- | mysql-test/r/have_bug25714.require | 2 | ||||
-rw-r--r-- | mysql-test/t/federated_bug_25714.test | 47 | ||||
-rw-r--r-- | sql/ha_federated.cc | 14 | ||||
-rw-r--r-- | tests/Makefile.am | 5 | ||||
-rw-r--r-- | tests/bug25714.c | 68 |
8 files changed, 207 insertions, 4 deletions
diff --git a/mysql-test/include/have_bug25714.inc b/mysql-test/include/have_bug25714.inc new file mode 100644 index 00000000000..0c995cd0d4c --- /dev/null +++ b/mysql-test/include/have_bug25714.inc @@ -0,0 +1,7 @@ +# +# Check if the variable MYSQL_BUG25714 is set +# +--require r/have_bug25714.require +disable_query_log; +eval select LENGTH("MYSQL_BUG25714") > 0 as "have_bug25714_exe"; +enable_query_log; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c58ed308bd8..43b1ef7ac86 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -144,6 +144,7 @@ our $exe_mysqladmin; our $exe_mysql_upgrade; our $exe_mysqlbinlog; our $exe_mysql_client_test; +our $exe_bug25714; our $exe_mysqld; our $exe_mysqlcheck; our $exe_mysqldump; @@ -1630,6 +1631,12 @@ sub executable_setup () { "$glob_basedir/tests/mysql_client_test", "$glob_basedir/bin/mysql_client_test"); } + + # Look for bug25714 executable which may _not_ exist in + # some versions, test using it should be skipped + $exe_bug25714= + mtr_exe_maybe_exists(vs_config_dirs('tests', 'bug25714'), + "$glob_basedir/tests/bug25714"); } @@ -2011,6 +2018,11 @@ sub environment_setup () { $ENV{'MYSQL'}= $cmdline_mysql; # ---------------------------------------------------- + # Setup env so childs can execute bug25714 + # ---------------------------------------------------- + $ENV{'MYSQL_BUG25714'}= $exe_bug25714; + + # ---------------------------------------------------- # Setup env so childs can execute mysql_client_test # ---------------------------------------------------- $ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments(); diff --git a/mysql-test/r/federated_bug_25714.result b/mysql-test/r/federated_bug_25714.result new file mode 100644 index 00000000000..12554f7af3a --- /dev/null +++ b/mysql-test/r/federated_bug_25714.result @@ -0,0 +1,56 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +stop slave; +DROP DATABASE IF EXISTS federated; +CREATE DATABASE federated; +DROP DATABASE IF EXISTS federated; +CREATE DATABASE federated; +DROP TABLE IF EXISTS federated.bug_13118_table; +CREATE TABLE federated.t1 ( +`id` int auto_increment primary key, +`value` int +) ENGINE=MyISAM; +INSERT INTO federated.t1 SET value=1; +INSERT INTO federated.t1 SET value=2; +INSERT INTO federated.t1 SET value=2; +DROP TABLE IF EXISTS federated.t1; +CREATE TABLE federated.t1 ( +`id` int auto_increment primary key, +`value` int +) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +SELECT * from federated.t1; +id value +1 1 +2 2 +3 2 +INSERT INTO federated.t1 SET value=4; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +4 + +5 inserted +6 inserted + +7 inserted +8 inserted +SELECT * from federated.t1; +id value +1 1 +2 2 +3 2 +4 4 +5 54 +6 55 +7 54 +8 55 +DROP TABLE federated.t1; +DROP TABLE federated.t1; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/r/have_bug25714.require b/mysql-test/r/have_bug25714.require new file mode 100644 index 00000000000..5acc378dcf7 --- /dev/null +++ b/mysql-test/r/have_bug25714.require @@ -0,0 +1,2 @@ +have_bug25714_exe +1 diff --git a/mysql-test/t/federated_bug_25714.test b/mysql-test/t/federated_bug_25714.test new file mode 100644 index 00000000000..9c185181511 --- /dev/null +++ b/mysql-test/t/federated_bug_25714.test @@ -0,0 +1,47 @@ +--source include/have_bug25714.inc +source include/federated.inc; + + +connection slave; +--disable_warnings +DROP TABLE IF EXISTS federated.bug_13118_table; +--enable_warnings + +CREATE TABLE federated.t1 ( + `id` int auto_increment primary key, + `value` int + ) ENGINE=MyISAM; +INSERT INTO federated.t1 SET value=1; +INSERT INTO federated.t1 SET value=2; +INSERT INTO federated.t1 SET value=2; + +connection master; +--disable_warnings +DROP TABLE IF EXISTS federated.t1; +--enable_warnings + +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE federated.t1 ( + `id` int auto_increment primary key, + `value` int + ) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + +SELECT * from federated.t1; + +INSERT INTO federated.t1 SET value=4; + +SELECT LAST_INSERT_ID(); + +--exec $MYSQL_BUG25714 $SLAVE_MYPORT +--exec $MYSQL_BUG25714 $MASTER_MYPORT + +SELECT * from federated.t1; + +DROP TABLE federated.t1; +connection slave; +DROP TABLE federated.t1; + + +source include/federated_cleanup.inc; + diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 3cf9c2a8b99..b669be78ebb 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -1811,8 +1811,13 @@ int ha_federated::write_row(byte *buf) field, then store the last_insert_id() value from the foreign server */ if (auto_increment_update_required) + { update_auto_increment(); + /* mysql_insert() uses this for protocol return value */ + table->next_number_field->store(auto_increment_value, 1); + } + DBUG_RETURN(0); } @@ -1896,7 +1901,8 @@ void ha_federated::update_auto_increment(void) THD *thd= current_thd; DBUG_ENTER("ha_federated::update_auto_increment"); - thd->insert_id(mysql->last_used_con->insert_id); + ha_federated::info(HA_STATUS_AUTO); + thd->insert_id(auto_increment_value); DBUG_PRINT("info",("last_insert_id: %ld", (long) auto_increment_value)); DBUG_VOID_RETURN; @@ -2688,8 +2694,10 @@ int ha_federated::info(uint flag) block_size= 4096; } - if (result) - mysql_free_result(result); + if (flag & HA_STATUS_AUTO) + auto_increment_value= mysql->last_used_con->insert_id; + + mysql_free_result(result); DBUG_RETURN(0); diff --git a/tests/Makefile.am b/tests/Makefile.am index bd56570d8d4..1c39a3630dd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,7 +28,7 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \ CMakeLists.txt bin_PROGRAMS = mysql_client_test -noinst_PROGRAMS = insert_test select_test thread_test +noinst_PROGRAMS = insert_test select_test thread_test bug25714 INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(openssl_includes) @@ -45,6 +45,9 @@ select_test_SOURCES= select_test.c insert_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) select_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) +bug25714_SOURCES= bug25714.c +bug25714_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) + # Fix for mit-threads DEFS = -DUNDEF_THREADS_HACK diff --git a/tests/bug25714.c b/tests/bug25714.c new file mode 100644 index 00000000000..d163b8ad00e --- /dev/null +++ b/tests/bug25714.c @@ -0,0 +1,68 @@ +/* Copyright (C) 2007 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <mysql.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +int main (int argc, char **argv) +{ + MYSQL conn; + int OK; + + const char* query4= "INSERT INTO federated.t1 SET Value=54"; + const char* query5= "INSERT INTO federated.t1 SET Value=55"; + + if (argc != 2) + return -1; + + mysql_init(&conn); + if (!mysql_real_connect( + &conn, + "127.0.0.1", + "root", + "", + "test", + atoi(argv[1]), + NULL, + CLIENT_FOUND_ROWS)) + { + fprintf(stderr, "Failed to connect to database: Error: %s\n", + mysql_error(&conn)); + return 1; + } else { + printf("%s\n", mysql_error(&conn)); + } + + OK = mysql_real_query (&conn, query4, strlen(query4)); + + assert(0 == OK); + + printf("%ld inserted\n", + (long) mysql_insert_id(&conn)); + + OK = mysql_real_query (&conn, query5, strlen(query5)); + + assert(0 == OK); + + printf("%ld inserted\n", + (long) mysql_insert_id(&conn)); + + mysql_close(&conn); + + return 0; +}; |