mariadb/mysql-test/t/rpl_insert_id.test

436 lines
10 KiB
Text
Raw Normal View History

--echo #
--echo # Setup
--echo #
source include/master-slave.inc;
BUG#11316 mysqltest, problems when assigning value with '#' to $variable - Fixed problem, only detect comment if the # is on start of line AND starting line of the current command. - Wrote tests for most of the mysqltest commands, added stricter checking of correct syntax. client/mysqltest.c: Updated mysql test to do stricter checking of syntax. For example when the number of arguments to a command is known, everything else is "junk" => die. Better checking of argument types. Added better debug printouts. Added improved printouts when wrong syntax is detected. Fix two bugs where mysqltest could not detect end of comamnd properly, as described in bug#11316 Fix segfault when performing too many source commands. Fix segfault when doing too many while loop levels. Add printout of line number in die Remove lineno and \n in all strings passed to die function. Decrese BLOCK_STACK_DEPTH from 32 to 16, does any test use more than 1 level? mysql-test/mysql-test-run.pl: export MYSQL_TEST environment variable, used from msyqltest.test mysql-test/mysql-test-run.sh: export MYSQL_TEST environment variable, used from msyqltest.test mysql-test/r/mysqltest.result: Updated test results mysql-test/r/rpl_flush_log_loop.result: Updated test result. Approved by lars mysql-test/t/innodb-deadlock.test: Correct wrong syntax Superfluos ; mysql-test/t/innodb-lock.test: Correct wrong syntax Superfluos ; mysql-test/t/mysqltest.test: Add several new tests for mysqltest. Foxus on detecting wrong syntax in test files. Use exec with expected error to execute test scripts that will kill mysqltest Change some negative test that were previously commented out to use the above method. mysql-test/t/ndb_autodiscover2.test: Correct wrong syntax Superfluos ; mysql-test/t/rpl_change_master.test: Correct wrong syntax Superfluos ; mysql-test/t/rpl_deadlock.test: Correct wrong syntax Superfluos ; mysql-test/t/rpl_drop_temp.test: Correct wrong syntax Superfluos ; mysql-test/t/rpl_flush_log_loop.test: Fix after detecting wrong syntax, missing ; Discussed with lars. mysql-test/t/rpl_insert_id.test: Missing ; mysql-test/t/rpl_rotate_logs.test: Correct wrong syntax Superfluos ; mysql-test/t/rpl_until.test: Missing delimiter mysql-test/include/mysqltest_while.inc: New file to test too many while levels
2005-07-15 17:51:43 +02:00
source include/have_innodb.inc;
use test;
--disable_warnings
drop table if exists t1, t2, t3;
--enable_warnings
--echo #
--echo # See if queries that use both auto_increment and LAST_INSERT_ID()
--echo # are replicated well
--echo #
--echo # We also check how the foreign_key_check variable is replicated
--echo #
connection master;
create table t1(a int auto_increment, key(a));
create table t2(b int auto_increment, c int, key(b));
insert into t1 values (1),(2),(3);
insert into t1 values (null);
insert into t2 values (null,last_insert_id());
save_master_pos;
connection slave;
sync_with_master;
select * from t1;
select * from t2;
connection master;
#check if multi-line inserts,
#which set last_insert_id to the first id inserted,
#are replicated the same way
drop table t1;
drop table t2;
--disable_warnings
WorkLog#1323 Deprecate the use of TYPE=... Preferred syntax is ENGINE= include/mysqld_error.h: New warning for deprecated syntax sql/lex.h: Introduce ENGINE keyword Sort order of symbols sql/share/czech/errmsg.txt: New warning for deprecated syntax sql/share/danish/errmsg.txt: New warning for deprecated syntax sql/share/dutch/errmsg.txt: New warning for deprecated syntax sql/share/english/errmsg.txt: New warning for deprecated syntax sql/share/estonian/errmsg.txt: New warning for deprecated syntax sql/share/french/errmsg.txt: New warning for deprecated syntax sql/share/german/errmsg.txt: New warning for deprecated syntax sql/share/greek/errmsg.txt: New warning for deprecated syntax sql/share/hungarian/errmsg.txt: New warning for deprecated syntax sql/share/italian/errmsg.txt: New warning for deprecated syntax sql/share/japanese/errmsg.txt: New warning for deprecated syntax sql/share/korean/errmsg.txt: New warning for deprecated syntax sql/share/norwegian-ny/errmsg.txt: New warning for deprecated syntax sql/share/norwegian/errmsg.txt: New warning for deprecated syntax sql/share/polish/errmsg.txt: New warning for deprecated syntax sql/share/portuguese/errmsg.txt: New warning for deprecated syntax sql/share/romanian/errmsg.txt: New warning for deprecated syntax sql/share/russian/errmsg.txt: New warning for deprecated syntax sql/share/serbian/errmsg.txt: New warning for deprecated syntax sql/share/slovak/errmsg.txt: New warning for deprecated syntax sql/share/spanish/errmsg.txt: New warning for deprecated syntax sql/share/swedish/errmsg.txt: New warning for deprecated syntax sql/share/ukrainian/errmsg.txt: New warning for deprecated syntax sql/sql_show.cc: Change TYPE= with ENGINE= sql/sql_yacc.yy: Introduce ENGINE keyword, Deprecate TYPE= syntax, Introduce SHOW ENGINE syntax, Deprecate SHOW INNODB/BDB syntax. mysql-test/r/alias.result: Change occurances of TYPE= to ENGINE= mysql-test/r/alter_table.result: Change occurances of TYPE= to ENGINE= mysql-test/r/auto_increment.result: Change occurances of TYPE= to ENGINE= mysql-test/r/bdb-alter-table-1.result: Change occurances of TYPE= to ENGINE= mysql-test/r/bdb-crash.result: Change occurances of TYPE= to ENGINE= mysql-test/r/bdb-deadlock.result: Change occurances of TYPE= to ENGINE= mysql-test/r/bdb.result: Change occurances of TYPE= to ENGINE= mysql-test/r/bdb_cache.result: Change occurances of TYPE= to ENGINE= mysql-test/r/case.result: Change occurances of TYPE= to ENGINE= mysql-test/r/cast.result: Change occurances of TYPE= to ENGINE= mysql-test/r/constraints.result: Change occurances of TYPE= to ENGINE= mysql-test/r/create.result: Change occurances of TYPE= to ENGINE= mysql-test/r/ctype_collate.result: Change occurances of TYPE= to ENGINE= mysql-test/r/ctype_latin1_de.result: Change occurances of TYPE= to ENGINE= mysql-test/r/ctype_many.result: Change occurances of TYPE= to ENGINE= mysql-test/r/ctype_mb.result: Change occurances of TYPE= to ENGINE= mysql-test/r/ctype_recoding.result: Change occurances of TYPE= to ENGINE= mysql-test/r/ctype_ucs.result: Change occurances of TYPE= to ENGINE= mysql-test/r/delete.result: Change occurances of TYPE= to ENGINE= mysql-test/r/distinct.result: Change occurances of TYPE= to ENGINE= mysql-test/r/fulltext.result: Change occurances of TYPE= to ENGINE= mysql-test/r/fulltext2.result: Change occurances of TYPE= to ENGINE= mysql-test/r/fulltext_distinct.result: Change occurances of TYPE= to ENGINE= mysql-test/r/fulltext_left_join.result: Change occurances of TYPE= to ENGINE= mysql-test/r/func_compress.result: Change occurances of TYPE= to ENGINE= mysql-test/r/func_date_add.result: Change occurances of TYPE= to ENGINE= mysql-test/r/func_group.result: Change occurances of TYPE= to ENGINE= mysql-test/r/func_if.result: Change occurances of TYPE= to ENGINE= mysql-test/r/func_str.result: Change occurances of TYPE= to ENGINE= mysql-test/r/func_system.result: Change occurances of TYPE= to ENGINE= mysql-test/r/func_test.result: Change occurances of TYPE= to ENGINE= mysql-test/r/func_time.result: Change occurances of TYPE= to ENGINE= mysql-test/r/gis-rtree.result: Change occurances of TYPE= to ENGINE= mysql-test/r/group_by.result: Change occurances of TYPE= to ENGINE= mysql-test/r/handler.result: Change occurances of TYPE= to ENGINE= mysql-test/r/heap.result: Change occurances of TYPE= to ENGINE= mysql-test/r/heap_auto_increment.result: Change occurances of TYPE= to ENGINE= mysql-test/r/heap_btree.result: Change occurances of TYPE= to ENGINE= mysql-test/r/heap_hash.result: Change occurances of TYPE= to ENGINE= mysql-test/r/help.result: Change occurances of TYPE= to ENGINE= mysql-test/r/innodb-deadlock.result: Change occurances of TYPE= to ENGINE= mysql-test/r/innodb.result: Change occurances of TYPE= to ENGINE= mysql-test/r/innodb_cache.result: Change occurances of TYPE= to ENGINE= mysql-test/r/innodb_handler.result: Change occurances of TYPE= to ENGINE= mysql-test/r/insert_select.result: Change occurances of TYPE= to ENGINE= mysql-test/r/isam.result: Change occurances of TYPE= to ENGINE= mysql-test/r/join.result: Change occurances of TYPE= to ENGINE= mysql-test/r/join_crash.result: Change occurances of TYPE= to ENGINE= mysql-test/r/join_outer.result: Change occurances of TYPE= to ENGINE= mysql-test/r/key.result: Change occurances of TYPE= to ENGINE= mysql-test/r/lock.result: Change occurances of TYPE= to ENGINE= mysql-test/r/lock_tables_lost_commit.result: Change occurances of TYPE= to ENGINE= mysql-test/r/merge.result: Change occurances of TYPE= to ENGINE= mysql-test/r/mix_innodb_myisam_binlog.result: Change occurances of TYPE= to ENGINE= mysql-test/r/multi_update.result: Change occurances of TYPE= to ENGINE= mysql-test/r/myisam.result: Change occurances of TYPE= to ENGINE= mysql-test/r/null.result: Change occurances of TYPE= to ENGINE= mysql-test/r/null_key.result: Change occurances of TYPE= to ENGINE= mysql-test/r/order_by.result: Change occurances of TYPE= to ENGINE= mysql-test/r/query_cache.result: Change occurances of TYPE= to ENGINE= mysql-test/r/range.result: Change occurances of TYPE= to ENGINE= mysql-test/r/repair_part1.result: Change occurances of TYPE= to ENGINE= mysql-test/r/replace.result: Change occurances of TYPE= to ENGINE= mysql-test/r/rollback.result: Change occurances of TYPE= to ENGINE= mysql-test/r/rpl000006.result: Change occurances of TYPE= to ENGINE= mysql-test/r/rpl_flush_tables.result: Change occurances of TYPE= to ENGINE= mysql-test/r/rpl_insert_id.result: Change occurances of TYPE= to ENGINE= mysql-test/r/rpl_relayrotate.result: Change occurances of TYPE= to ENGINE= mysql-test/r/select.result: Change occurances of TYPE= to ENGINE= mysql-test/r/select_found.result: Change occurances of TYPE= to ENGINE= mysql-test/r/show_check.result: Change occurances of TYPE= to ENGINE= mysql-test/r/sql_mode.result: Change occurances of TYPE= to ENGINE= mysql-test/r/status.result: Change occurances of TYPE= to ENGINE= mysql-test/r/subselect.result: Change occurances of TYPE= to ENGINE= mysql-test/r/subselect2.result: Change occurances of TYPE= to ENGINE= mysql-test/r/subselect_innodb.result: Change occurances of TYPE= to ENGINE= mysql-test/r/symlink.result: Change occurances of TYPE= to ENGINE= mysql-test/r/temp_table.result: Change occurances of TYPE= to ENGINE= mysql-test/r/type_blob.result: Change occurances of TYPE= to ENGINE= mysql-test/r/type_datetime.result: Change occurances of TYPE= to ENGINE= mysql-test/r/type_enum.result: Change occurances of TYPE= to ENGINE= mysql-test/r/type_nchar.result: Change occurances of TYPE= to ENGINE= mysql-test/r/type_set.result: Change occurances of TYPE= to ENGINE= mysql-test/r/union.result: Change occurances of TYPE= to ENGINE= mysql-test/r/update.result: Change occurances of TYPE= to ENGINE= mysql-test/r/warnings.result: Change occurances of TYPE= to ENGINE= mysql-test/t/alias.test: Change occurances of TYPE= to ENGINE= mysql-test/t/alter_table.test: Change occurances of TYPE= to ENGINE= mysql-test/t/auto_increment.test: Change occurances of TYPE= to ENGINE= mysql-test/t/bdb-alter-table-1.test: Change occurances of TYPE= to ENGINE= mysql-test/t/bdb-crash.test: Change occurances of TYPE= to ENGINE= mysql-test/t/bdb-deadlock.test: Change occurances of TYPE= to ENGINE= mysql-test/t/bdb.test: Change occurances of TYPE= to ENGINE= mysql-test/t/bdb_cache.test: Change occurances of TYPE= to ENGINE= mysql-test/t/create.test: Change occurances of TYPE= to ENGINE= mysql-test/t/ctype_ucs.test: Change occurances of TYPE= to ENGINE= mysql-test/t/delete.test: Change occurances of TYPE= to ENGINE= mysql-test/t/distinct.test: Change occurances of TYPE= to ENGINE= mysql-test/t/fulltext.test: Change occurances of TYPE= to ENGINE= mysql-test/t/fulltext2.test: Change occurances of TYPE= to ENGINE= mysql-test/t/fulltext_distinct.test: Change occurances of TYPE= to ENGINE= mysql-test/t/fulltext_left_join.test: Change occurances of TYPE= to ENGINE= mysql-test/t/func_compress.test: Change occurances of TYPE= to ENGINE= mysql-test/t/func_date_add.test: Change occurances of TYPE= to ENGINE= mysql-test/t/func_group.test: Change occurances of TYPE= to ENGINE= mysql-test/t/func_if.test: Change occurances of TYPE= to ENGINE= mysql-test/t/func_str.test: Change occurances of TYPE= to ENGINE= mysql-test/t/func_test.test: Change occurances of TYPE= to ENGINE= mysql-test/t/func_time.test: Change occurances of TYPE= to ENGINE= mysql-test/t/gis-rtree.test: Change occurances of TYPE= to ENGINE= mysql-test/t/group_by.test: Change occurances of TYPE= to ENGINE= mysql-test/t/handler.test: Change occurances of TYPE= to ENGINE= mysql-test/t/heap.test: Change occurances of TYPE= to ENGINE= mysql-test/t/heap_auto_increment.test: Change occurances of TYPE= to ENGINE= mysql-test/t/heap_btree.test: Change occurances of TYPE= to ENGINE= mysql-test/t/heap_hash.test: Change occurances of TYPE= to ENGINE= mysql-test/t/help.test: Change occurances of TYPE= to ENGINE= mysql-test/t/innodb-deadlock.test: Change occurances of TYPE= to ENGINE= mysql-test/t/innodb.test: Change occurances of TYPE= to ENGINE= mysql-test/t/innodb_cache.test: Change occurances of TYPE= to ENGINE= mysql-test/t/innodb_handler.test: Change occurances of TYPE= to ENGINE= mysql-test/t/insert_select.test: Change occurances of TYPE= to ENGINE= mysql-test/t/isam.test: Change occurances of TYPE= to ENGINE= mysql-test/t/join.test: Change occurances of TYPE= to ENGINE= mysql-test/t/join_crash.test: Change occurances of TYPE= to ENGINE= mysql-test/t/join_outer.test: Change occurances of TYPE= to ENGINE= mysql-test/t/key.test: Change occurances of TYPE= to ENGINE= mysql-test/t/lock.test: Change occurances of TYPE= to ENGINE= mysql-test/t/lock_tables_lost_commit.test: Change occurances of TYPE= to ENGINE= mysql-test/t/merge.test: Change occurances of TYPE= to ENGINE= mysql-test/t/mix_innodb_myisam_binlog.test: Change occurances of TYPE= to ENGINE= mysql-test/t/multi_update.test: Change occurances of TYPE= to ENGINE= mysql-test/t/myisam.test: Change occurances of TYPE= to ENGINE= mysql-test/t/null.test: Change occurances of TYPE= to ENGINE= mysql-test/t/null_key.test: Change occurances of TYPE= to ENGINE= mysql-test/t/order_by.test: Change occurances of TYPE= to ENGINE= mysql-test/t/outfile.test: Change occurances of TYPE= to ENGINE= mysql-test/t/query_cache.test: Change occurances of TYPE= to ENGINE= mysql-test/t/query_cache_merge.test: Change occurances of TYPE= to ENGINE= mysql-test/t/range.test: Change occurances of TYPE= to ENGINE= mysql-test/t/repair_part1.test: Change occurances of TYPE= to ENGINE= mysql-test/t/replace.test: Change occurances of TYPE= to ENGINE= mysql-test/t/rollback.test: Change occurances of TYPE= to ENGINE= mysql-test/t/rpl000006.test: Change occurances of TYPE= to ENGINE= mysql-test/t/rpl_flush_tables.test: Change occurances of TYPE= to ENGINE= mysql-test/t/rpl_insert_id.test: Change occurances of TYPE= to ENGINE= mysql-test/t/rpl_relayrotate.test: Change occurances of TYPE= to ENGINE= mysql-test/t/select.test: Change occurances of TYPE= to ENGINE= mysql-test/t/select_found.test: Change occurances of TYPE= to ENGINE= mysql-test/t/show_check.test: Change occurances of TYPE= to ENGINE= mysql-test/t/sql_mode.test: Change occurances of TYPE= to ENGINE= mysql-test/t/status.test: Change occurances of TYPE= to ENGINE= mysql-test/t/subselect.test: Change occurances of TYPE= to ENGINE= mysql-test/t/subselect2.test: Change occurances of TYPE= to ENGINE= mysql-test/t/subselect_innodb.test: Change occurances of TYPE= to ENGINE= mysql-test/t/symlink.test: Change occurances of TYPE= to ENGINE= mysql-test/t/temp_table.test: Change occurances of TYPE= to ENGINE= mysql-test/t/type_datetime.test: Change occurances of TYPE= to ENGINE= mysql-test/t/type_set.test: Change occurances of TYPE= to ENGINE= mysql-test/t/union.test: Change occurances of TYPE= to ENGINE= mysql-test/t/update.test: Change occurances of TYPE= to ENGINE= mysql-test/t/warnings.test: Change occurances of TYPE= to ENGINE= New test for deprecated syntax
2003-12-10 05:31:42 +01:00
create table t1(a int auto_increment, key(a)) engine=innodb;
create table t2(b int auto_increment, c int, key(b), foreign key(b) references t1(a)) engine=innodb;
--enable_warnings
SET FOREIGN_KEY_CHECKS=0;
insert into t1 values (10);
insert into t1 values (null),(null),(null);
insert into t2 values (5,0);
insert into t2 values (null,last_insert_id());
SET FOREIGN_KEY_CHECKS=1;
save_master_pos;
connection slave;
sync_with_master;
select * from t1;
select * from t2;
connection master;
--echo #
--echo # check if INSERT SELECT in auto_increment is well replicated (bug #490)
--echo #
drop table t2;
drop table t1;
create table t1(a int auto_increment, key(a));
create table t2(b int auto_increment, c int, key(b));
insert into t1 values (10);
insert into t1 values (null),(null),(null);
insert into t2 values (5,0);
insert into t2 (c) select * from t1;
select * from t2;
save_master_pos;
connection slave;
sync_with_master;
select * from t1;
select * from t2;
connection master;
drop table t1;
drop table t2;
save_master_pos;
connection slave;
sync_with_master;
--echo #
--echo # Bug#8412: Error codes reported in binary log for CHARACTER SET,
--echo # FOREIGN_KEY_CHECKS
--echo #
connection master;
SET TIMESTAMP=1000000000;
CREATE TABLE t1 ( a INT UNIQUE );
SET FOREIGN_KEY_CHECKS=0;
--error 1062
INSERT INTO t1 VALUES (1),(1);
sync_slave_with_master;
Add new option "check-testcases" to mysql-test-run.pl Cleanup the sideeffects from most of the testcases with sideeffects. mysql-test/mysql-test-run.pl: Add option "check-testcases" to mysql-test-run.pl Will execute "include/check-testcase.test" once before each tescase and record the output into "var/tmp/check-testcase.result" After the teastcase it will run again and this time compare the output with previously recorded file. mysql-test/r/analyze.result: Drop table t1 at end of test mysql-test/r/create_select_tmp.result: Drop table t1 at end of test mysql-test/r/ctype_cp932.result: Drop table t1 at end of test mysql-test/r/ctype_recoding.result: Drop table t1 at end of test mysql-test/r/grant2.result: Drop user mysqltest_2 and mysqltest_A@'%' mysql-test/r/join_outer.result: Drop view v1 to cleanup mysql-test/r/ps_1general.result: Drop table t1 at end of test mysql-test/r/query_cache.result: Drop function "f1" mysql-test/r/read_only.result: Reset the "read_only" flag mysql-test/r/rpl000001.result: Remove user "blafasel2" mysql-test/r/rpl000017.result: Remove user "replicate" mysql-test/r/rpl_failed_optimize.result: Drop table t1 to cleanup mysql-test/r/rpl_flush_tables.result: Drop tables t3, t4, t5 mysql-test/r/rpl_ignore_revoke.result: Delete user "user_foo" mysql-test/r/rpl_insert_id.result: Drop table t1 to cleanup mysql-test/r/rpl_loaddata.result: Drop tyable t1 to cleanup mysql-test/r/rpl_loaddata_rule_m.result: Drop tyable t1 to cleanup mysql-test/r/rpl_loaddata_rule_s.result: Drop tyable t1 to cleanup mysql-test/r/rpl_misc_functions.result: Drop tyable t1 to cleanup mysql-test/r/rpl_multi_update3.result: Drop tyable t1 and t2 to cleanup mysql-test/r/rpl_replicate_do.result: Drop tyable t1 to cleanup mysql-test/r/rpl_skip_error.result: Drop tyable t1 to cleanup mysql-test/r/rpl_slave_status.result: Drop tyable t1 to cleanup mysql-test/r/sp-prelocking.result: Drop view v1 and tables t1, t2, t3 and t4 to cleanup mysql-test/r/sp-security.result: Delete users to cleanup Delete remaining traces in tables_priv and procs_priv mysql-test/r/subselect_innodb.result: Drop procedure p1 to cleanup mysql-test/r/trigger-compat.result: Drop trigger wl2818_trg1 and wl2818_trg2. Drop table t1, t2 Drop database mysqltest_db1 And the users "mysqltest_dfn@localhost" and "mysqltest_inv@localhost" mysql-test/r/type_bit.result: Drop tables t1 and t2 to cleanup mysql-test/r/variables.result: Set GLOBAL max_join_size to 10 as it originally was in variables-master.opt mysql-test/r/view_grant.result: Dop user "test@localhost" to cleanup mysql-test/t/analyze.test: Drop table t1 to cleanup mysql-test/t/create_select_tmp.test: Drop table t1 to cleanup mysql-test/t/ctype_cp932.test: Drop table t1 to cleanup mysql-test/t/ctype_recoding.test: Drop table t1 to cleanup mysql-test/t/fulltext_var.test: Restore the original ft_boolean_syntax mysql-test/t/grant2.test: Drop users "mysqltest_2" and "mysqltest_A@'%'" to cleanup mysql-test/t/innodb_cache.test: Reset query_cache_size to original value mysql-test/t/join_outer.test: Drop view v1 to cleanup mysql-test/t/ps_1general.test: Drop table t1 to cleanup mysql-test/t/query_cache.test: Drop function "f1" to cleanup mysql-test/t/read_only.test: Reset the readonly flag mysql-test/t/rpl000001.test: Delete user "blafasel2" to cleanup mysql-test/t/rpl000017.test: Delete user "replicate" to cleanup mysql-test/t/rpl_failed_optimize.test: Drop table t1 to cleanup mysql-test/t/rpl_flush_tables.test: Droip table t3, t4 and t5 to cleanup mysql-test/t/rpl_ignore_revoke.test: Delet user "user_foo" to cleanup mysql-test/t/rpl_insert_id.test: drop table t1 to cleanup mysql-test/t/rpl_loaddata.test: Drop table t1 to cleanup mysql-test/t/rpl_loaddata_rule_m.test: Drop table t1 to cleanup mysql-test/t/rpl_loaddata_rule_s.test: Drop table t1 to cleanup mysql-test/t/rpl_misc_functions.test: Drop table t1 to cleanup mysql-test/t/rpl_multi_update3.test: Drop table t1 and t2 to cleanup mysql-test/t/rpl_replicate_do.test: Drop table t1 to cleanup mysql-test/t/rpl_skip_error.test: Drop table t1 to cleanup mysql-test/t/rpl_slave_status.test: Drop table t1 to cleanup mysql-test/t/sp-prelocking.test: Drop table t1, t2 t3 and t4 to cleanup Drop view v1 mysql-test/t/sp-security.test: Delete test users from mysql.user, mysql.db, mysql.procs_priv and mysql.tables_priv Drop table t1 to cleanup mysql-test/t/subselect_innodb.test: Drop procedure p1 to cleanup mysql-test/t/trigger-compat.test: Drop trigger wl2818_trg1 and wl2818_trg2 to cleanup Drop table t1, t2 Drop users drop database mysqltest_db1 mysql-test/t/type_bit.test: drop table t1 and t2 to cleanup mysql-test/t/variables-master.opt: Increase max_join_size to 100. mysql-test/t/variables.test: Set max_join_size to 10, which was the original value in variables-master.opt mysql-test/t/view_grant.test: Drop the user "test@localhost" mysql-test/include/check-testcase.test: New BitKeeper file ``mysql-test/include/check-testcase.test''
2006-01-26 17:54:34 +01:00
connection master;
drop table t1;
sync_slave_with_master;
--echo #
--echo # Bug#14553: NULL in WHERE resets LAST_INSERT_ID
--echo #
connection master;
create table t1(a int auto_increment, key(a));
create table t2(a int);
insert into t1 (a) values (null);
insert into t2 (a) select a from t1 where a is null;
insert into t2 (a) select a from t1 where a is null;
select * from t2;
sync_slave_with_master;
connection slave;
select * from t2;
connection master;
drop table t1;
drop table t2;
sync_slave_with_master;
--echo #
--echo # End of 4.1 tests
--echo #
#
# BUG#15728: LAST_INSERT_ID function inside a stored function returns 0
#
# The solution is not to reset last_insert_id on enter to sub-statement.
#
connection master;
--disable_warnings
drop function if exists bug15728;
drop function if exists bug15728_insert;
drop table if exists t1, t2;
--enable_warnings
create table t1 (
id int not null auto_increment,
last_id int,
primary key (id)
);
create function bug15728() returns int(11)
return last_insert_id();
insert into t1 (last_id) values (0);
insert into t1 (last_id) values (last_insert_id());
insert into t1 (last_id) values (bug15728());
# Check that nested call replicates too.
create table t2 (
id int not null auto_increment,
last_id int,
primary key (id)
);
delimiter |;
create function bug15728_insert() returns int(11) modifies sql data
begin
insert into t2 (last_id) values (bug15728());
return bug15728();
end|
create trigger t1_bi before insert on t1 for each row
begin
declare res int;
select bug15728_insert() into res;
set NEW.last_id = res;
end|
delimiter ;|
insert into t1 (last_id) values (0);
drop trigger t1_bi;
# Check that nested call doesn't affect outer context.
select last_insert_id();
select bug15728_insert();
select last_insert_id();
insert into t1 (last_id) values (bug15728());
# This should be exactly one greater than in the previous call.
select last_insert_id();
save_master_pos;
connection slave;
sync_with_master;
select * from t1;
select * from t2;
connection master;
drop function bug15728;
drop function bug15728_insert;
drop table t1, t2;
Fix for BUG#20188 "REPLACE or ON DUPLICATE KEY UPDATE in auto_increment breaks binlog": if slave's table had a higher auto_increment counter than master's (even though all rows of the two tables were identical), then in some cases, REPLACE and INSERT ON DUPLICATE KEY UPDATE failed to replicate statement-based (it inserted different values on slave from on master). write_record() contained a "thd->next_insert_id=0" to force an adjustment of thd->next_insert_id after the update or replacement. But it is this assigment introduced indeterminism of the statement on the slave, thus the bug. For ON DUPLICATE, we replace that assignment by a call to handler::adjust_next_insert_id_after_explicit_value() which is deterministic (does not depend on slave table's autoinc counter). For REPLACE, this assignment can simply be removed (as REPLACE can't insert a number larger than thd->next_insert_id). We also move a too early restore_auto_increment() down to when we really know that we can restore the value. mysql-test/r/rpl_insert_id.result: result update, without the bugfix, slave's "3 350" were "4 350". mysql-test/t/rpl_insert_id.test: test for BUG#20188 "REPLACE or ON DUPLICATE KEY UPDATE in auto_increment breaks binlog". There is, in this order: - a test of the bug for the case of REPLACE - a test of basic ON DUPLICATE KEY UPDATE functionality which was not tested before - a test of the bug for the case of ON DUPLICATE KEY UPDATE sql/handler.cc: the adjustment of next_insert_id if inserting a big explicit value, is moved to a separate method to be used elsewhere. sql/handler.h: see handler.cc sql/sql_insert.cc: restore_auto_increment() means "I know I won't use this autogenerated autoincrement value, you are free to reuse it for next row". But we were calling restore_auto_increment() in the case of REPLACE: if write_row() fails inserting the row, we don't know that we won't use the value, as we are going to try again by doing internally an UPDATE of the existing row, or a DELETE of the existing row and then an INSERT. So I move restore_auto_increment() further down, when we know for sure we failed all possibilities for the row. Additionally, in case of REPLACE, we don't need to reset THD::next_insert_id: the value of thd->next_insert_id will be suitable for the next row. In case of ON DUPLICATE KEY UPDATE, resetting thd->next_insert_id is also wrong (breaks statement-based binlog), but cannot simply be removed, as thd->next_insert_id must be adjusted if the explicit value exceeds it. We now do the adjustment by calling handler::adjust_next_insert_id_after_explicit_value() (which, contrary to thd->next_insert_id=0, does not depend on the slave table's autoinc counter, and so is deterministic).
2006-07-05 14:41:35 +02:00
# test of BUG#20188 REPLACE or ON DUPLICATE KEY UPDATE in
# auto_increment breaks binlog
create table t1 (n int primary key auto_increment not null,
b int, unique(b));
# First, test that we do not call restore_auto_increment() too early
# in write_record():
set sql_log_bin=0;
insert into t1 values(null,100);
replace into t1 values(null,50),(null,100),(null,150);
select * from t1 order by n;
truncate table t1;
set sql_log_bin=1;
insert into t1 values(null,100);
select * from t1 order by n;
sync_slave_with_master;
# make slave's table autoinc counter bigger
insert into t1 values(null,200),(null,300);
delete from t1 where b <> 100;
# check that slave's table content is identical to master
select * from t1 order by n;
# only the auto_inc counter differs.
connection master;
replace into t1 values(null,100),(null,350);
select * from t1 order by n;
sync_slave_with_master;
select * from t1 order by n;
# Same test as for REPLACE, but for ON DUPLICATE KEY UPDATE
# We first check that if we update a row using a value larger than the
# table's counter, the counter for next row is bigger than the
# after-value of the updated row.
connection master;
insert into t1 values (NULL,400),(3,500),(NULL,600) on duplicate key UPDATE n=1000;
select * from t1 order by n;
sync_slave_with_master;
select * from t1 order by n;
# and now test for the bug:
connection master;
drop table t1;
create table t1 (n int primary key auto_increment not null,
b int, unique(b));
insert into t1 values(null,100);
select * from t1 order by n;
sync_slave_with_master;
insert into t1 values(null,200),(null,300);
delete from t1 where b <> 100;
select * from t1 order by n;
connection master;
insert into t1 values(null,100),(null,350) on duplicate key update n=2;
select * from t1 order by n;
sync_slave_with_master;
select * from t1 order by n;
connection master;
drop table t1;
BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID Non-upper-level INSERTs (the ones in the body of stored procedure, stored function, or trigger) into a table that have AUTO_INCREMENT column didn't affected the result of LAST_INSERT_ID() on this level. The problem was introduced with the fix of bug 6880, which in turn was introduced with the fix of bug 3117, where current insert_id value was remembered on the first call to LAST_INSERT_ID() (bug 3117) and was returned from that function until it was reset before the next _upper-level_ statement (bug 6880). The fix for bug#21726 brings back the behaviour of version 4.0, and implements the following: remember insert_id value at the beginning of the statement or expression (which at that point equals to the first insert_id value generated by the previous statement), and return that remembered value from LAST_INSERT_ID() or @@LAST_INSERT_ID. Thus, the value returned by LAST_INSERT_ID() is not affected by values generated by current statement, nor by LAST_INSERT_ID(expr) calls in this statement. Version 5.1 does not have this bug (it was fixed by WL 3146). mysql-test/r/rpl_insert_id.result: Add results for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. mysql-test/t/rpl_insert_id.test: Add test cases for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. sql/item_func.cc: Add implementation of Item_func_last_insert_id::fix_fields(), where we remember in THD::current_insert_id the first value generated during execution of the previous statement, which is returned then from Item_func_last_insert_id::val_int(). sql/item_func.h: Add declaration of Item_func_last_insert_id::fix_fields(). sql/log_event.cc: Do not set THD::last_insert_id_used on LAST_INSERT_ID_EVENT. Though we know the statement will call LAST_INSERT_ID(), it wasn't called yet. sql/set_var.cc: In sys_var_last_insert_id::value_ptr() remember in THD::current_insert_id the first value generated during execution of the previous statement, and return this value for @@LAST_INSERT_ID. sql/sql_class.cc: Reset THD::last_insert_id_used after each statement execution. sql/sql_class.h: Rather then remember current insert_id value on first invocation of THD::insert_id(), remember it in Item_func_last_insert_id::fix_fields(), sys_var_last_insert_id::value_ptr(), or mysql_execute_command(). Remove THD::insert_id(), as it lost its value now. sql/sql_insert.cc: THD::insert_id() is removed, use THD::last_insert_id directly. sql/sql_load.cc: THD::insert_id() is removed, using THD::last_insert_id directly is OK. sql/sql_parse.cc: Remember in THD::current_insert_id first generated insert id value of the previous statement in mysql_execute_command(). No need to reset THD::last_insert_id_used in mysql_reset_thd_for_next_command(), it will be reset after each statement. sql/sql_select.cc: If "IS NULL" is replaced with "= <LAST_INSERT_ID>", use right value, which is THD::current_insert_id, and also set THD::last_insert_id_used to issue binary log LAST_INSERT_ID_EVENT. sql/sql_update.cc: THD::insert_id() is removed, use THD::last_insert_id directly. tests/mysql_client_test.c: Add test case for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID.
2006-10-02 12:28:23 +02:00
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service. mysql-test/r/rpl_insert_id.result: results to check the bugfix; without the bugfix, you would see, in master and slave: "3,2" instead of "2,2" for the INSERT VALUES testcase, "11,6,..." instead of "6,6,..." for the INSERT SELECT testcase. mysql-test/t/rpl_insert_id.test: testing that BUG#24432 is fixed sql/log_event.cc: A trick to force the master to pretend it is old and features BUG#24432. To do fast lookups in the list of known bugs by version, we compute the 3 X.Y.Z numbers from the master's version string and cache that into a new member Format_description_log_event::server_version_split. We do this computation in the event's two constructors. A simple prevention against buffer overrun when reading the master's version from a binlog event (assume the event is corrupted on disk, and so the version string on disk is longer than ST_SERVER_VER_LEN (50), then we would not get a closing 0 at the end of the class member. sql/log_event.h: new member to hold the "split server version" (3 numbers X.Y.Z), and a method to compute this from the version string. sql/slave.cc: a function which tells, based on master's version (as found in the Format_description event in the relay log being executed), if master can have a certain bug. This function uses a list of bug_id / first_version_with_bug / first_version_with_fix. If the test is positive, a short error message is put into SHOW SLAVE STATUS, and a verbose message is put into the slave's error log. The caller is expected to stop the slave in this case. sql/slave.h: new function to test if the replication master has a bug sql/sql_insert.cc: Fix for BUG#24432:t he reason was a misplaced restore_auto_increment() (misplaced when fixing BUG#20188). Indeed, when updating the row, it is clear that the autogenerated auto_increment value will not be used for this row (and if by "chance" the autoinc value present in the updated row is >= to the not used autogenerated value, adjust_next_insert_id_after_explicit_value() will fix next_insert_id). We also add code for a fixed slave to detect that it is connected to a buggy master (in which case it cannot replicate so stops). mysql-test/r/rpl_known_bugs_detection.result: see that SHOW SLAVE STATUS prints information that slave found a bug in master, and does not execute the dangerous event (table stays empty). mysql-test/t/rpl_known_bugs_detection-master.opt: pass debug symbol to make the master pretend it has BUG#24432 mysql-test/t/rpl_known_bugs_detection.test: new test to see if bug detection by slave works
2007-02-08 15:53:14 +01:00
#
# BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values"
#
# testcase with INSERT VALUES
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
UNIQUE(b));
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
SELECT * FROM t1;
sync_slave_with_master;
SELECT * FROM t1;
connection master;
drop table t1;
# tescase with INSERT SELECT
CREATE TABLE t1 (
id bigint(20) unsigned NOT NULL auto_increment,
field_1 int(10) unsigned NOT NULL,
field_2 varchar(255) NOT NULL,
field_3 varchar(255) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY field_1 (field_1, field_2)
);
CREATE TABLE t2 (
field_a int(10) unsigned NOT NULL,
field_b varchar(255) NOT NULL,
field_c varchar(255) NOT NULL
);
INSERT INTO t2 (field_a, field_b, field_c) VALUES (1, 'a', '1a');
INSERT INTO t2 (field_a, field_b, field_c) VALUES (2, 'b', '2b');
INSERT INTO t2 (field_a, field_b, field_c) VALUES (3, 'c', '3c');
INSERT INTO t2 (field_a, field_b, field_c) VALUES (4, 'd', '4d');
INSERT INTO t2 (field_a, field_b, field_c) VALUES (5, 'e', '5e');
# Updating table t1 based on values from table t2
INSERT INTO t1 (field_1, field_2, field_3)
SELECT t2.field_a, t2.field_b, t2.field_c
FROM t2
ON DUPLICATE KEY UPDATE
t1.field_3 = t2.field_c;
# Inserting new record into t2
INSERT INTO t2 (field_a, field_b, field_c) VALUES (6, 'f', '6f');
# Updating t1 again
INSERT INTO t1 (field_1, field_2, field_3)
SELECT t2.field_a, t2.field_b, t2.field_c
FROM t2
ON DUPLICATE KEY UPDATE
t1.field_3 = t2.field_c;
SELECT * FROM t1;
sync_slave_with_master;
SELECT * FROM t1;
connection master;
drop table t1, t2;
BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID Non-upper-level INSERTs (the ones in the body of stored procedure, stored function, or trigger) into a table that have AUTO_INCREMENT column didn't affected the result of LAST_INSERT_ID() on this level. The problem was introduced with the fix of bug 6880, which in turn was introduced with the fix of bug 3117, where current insert_id value was remembered on the first call to LAST_INSERT_ID() (bug 3117) and was returned from that function until it was reset before the next _upper-level_ statement (bug 6880). The fix for bug#21726 brings back the behaviour of version 4.0, and implements the following: remember insert_id value at the beginning of the statement or expression (which at that point equals to the first insert_id value generated by the previous statement), and return that remembered value from LAST_INSERT_ID() or @@LAST_INSERT_ID. Thus, the value returned by LAST_INSERT_ID() is not affected by values generated by current statement, nor by LAST_INSERT_ID(expr) calls in this statement. Version 5.1 does not have this bug (it was fixed by WL 3146). mysql-test/r/rpl_insert_id.result: Add results for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. mysql-test/t/rpl_insert_id.test: Add test cases for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. sql/item_func.cc: Add implementation of Item_func_last_insert_id::fix_fields(), where we remember in THD::current_insert_id the first value generated during execution of the previous statement, which is returned then from Item_func_last_insert_id::val_int(). sql/item_func.h: Add declaration of Item_func_last_insert_id::fix_fields(). sql/log_event.cc: Do not set THD::last_insert_id_used on LAST_INSERT_ID_EVENT. Though we know the statement will call LAST_INSERT_ID(), it wasn't called yet. sql/set_var.cc: In sys_var_last_insert_id::value_ptr() remember in THD::current_insert_id the first value generated during execution of the previous statement, and return this value for @@LAST_INSERT_ID. sql/sql_class.cc: Reset THD::last_insert_id_used after each statement execution. sql/sql_class.h: Rather then remember current insert_id value on first invocation of THD::insert_id(), remember it in Item_func_last_insert_id::fix_fields(), sys_var_last_insert_id::value_ptr(), or mysql_execute_command(). Remove THD::insert_id(), as it lost its value now. sql/sql_insert.cc: THD::insert_id() is removed, use THD::last_insert_id directly. sql/sql_load.cc: THD::insert_id() is removed, using THD::last_insert_id directly is OK. sql/sql_parse.cc: Remember in THD::current_insert_id first generated insert id value of the previous statement in mysql_execute_command(). No need to reset THD::last_insert_id_used in mysql_reset_thd_for_next_command(), it will be reset after each statement. sql/sql_select.cc: If "IS NULL" is replaced with "= <LAST_INSERT_ID>", use right value, which is THD::current_insert_id, and also set THD::last_insert_id_used to issue binary log LAST_INSERT_ID_EVENT. sql/sql_update.cc: THD::insert_id() is removed, use THD::last_insert_id directly. tests/mysql_client_test.c: Add test case for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID.
2006-10-02 12:28:23 +02:00
#
# BUG#20339: stored procedure using LAST_INSERT_ID() does not
# replicate statement-based
#
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
# Reset result of LAST_INSERT_ID().
SELECT LAST_INSERT_ID(0);
CREATE TABLE t1 (
id INT NOT NULL DEFAULT 0,
last_id INT,
PRIMARY KEY (id)
);
CREATE TABLE t2 (
id INT NOT NULL AUTO_INCREMENT,
last_id INT,
PRIMARY KEY (id)
);
delimiter |;
CREATE PROCEDURE p1()
BEGIN
INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID());
INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID());
END|
delimiter ;|
CALL p1();
SELECT * FROM t1;
SELECT * FROM t2;
sync_slave_with_master;
SELECT * FROM t1;
SELECT * FROM t2;
connection master;
DROP PROCEDURE p1;
DROP TABLE t1, t2;
#
# BUG#21726: Incorrect result with multiple invocations of
# LAST_INSERT_ID
#
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP FUNCTION IF EXISTS f3;
BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID Non-upper-level INSERTs (the ones in the body of stored procedure, stored function, or trigger) into a table that have AUTO_INCREMENT column didn't affected the result of LAST_INSERT_ID() on this level. The problem was introduced with the fix of bug 6880, which in turn was introduced with the fix of bug 3117, where current insert_id value was remembered on the first call to LAST_INSERT_ID() (bug 3117) and was returned from that function until it was reset before the next _upper-level_ statement (bug 6880). The fix for bug#21726 brings back the behaviour of version 4.0, and implements the following: remember insert_id value at the beginning of the statement or expression (which at that point equals to the first insert_id value generated by the previous statement), and return that remembered value from LAST_INSERT_ID() or @@LAST_INSERT_ID. Thus, the value returned by LAST_INSERT_ID() is not affected by values generated by current statement, nor by LAST_INSERT_ID(expr) calls in this statement. Version 5.1 does not have this bug (it was fixed by WL 3146). mysql-test/r/rpl_insert_id.result: Add results for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. mysql-test/t/rpl_insert_id.test: Add test cases for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. sql/item_func.cc: Add implementation of Item_func_last_insert_id::fix_fields(), where we remember in THD::current_insert_id the first value generated during execution of the previous statement, which is returned then from Item_func_last_insert_id::val_int(). sql/item_func.h: Add declaration of Item_func_last_insert_id::fix_fields(). sql/log_event.cc: Do not set THD::last_insert_id_used on LAST_INSERT_ID_EVENT. Though we know the statement will call LAST_INSERT_ID(), it wasn't called yet. sql/set_var.cc: In sys_var_last_insert_id::value_ptr() remember in THD::current_insert_id the first value generated during execution of the previous statement, and return this value for @@LAST_INSERT_ID. sql/sql_class.cc: Reset THD::last_insert_id_used after each statement execution. sql/sql_class.h: Rather then remember current insert_id value on first invocation of THD::insert_id(), remember it in Item_func_last_insert_id::fix_fields(), sys_var_last_insert_id::value_ptr(), or mysql_execute_command(). Remove THD::insert_id(), as it lost its value now. sql/sql_insert.cc: THD::insert_id() is removed, use THD::last_insert_id directly. sql/sql_load.cc: THD::insert_id() is removed, using THD::last_insert_id directly is OK. sql/sql_parse.cc: Remember in THD::current_insert_id first generated insert id value of the previous statement in mysql_execute_command(). No need to reset THD::last_insert_id_used in mysql_reset_thd_for_next_command(), it will be reset after each statement. sql/sql_select.cc: If "IS NULL" is replaced with "= <LAST_INSERT_ID>", use right value, which is THD::current_insert_id, and also set THD::last_insert_id_used to issue binary log LAST_INSERT_ID_EVENT. sql/sql_update.cc: THD::insert_id() is removed, use THD::last_insert_id directly. tests/mysql_client_test.c: Add test case for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID.
2006-10-02 12:28:23 +02:00
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1 (
i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
j INT DEFAULT 0
);
CREATE TABLE t2 (i INT);
delimiter |;
CREATE PROCEDURE p1()
BEGIN
INSERT INTO t1 (i) VALUES (NULL);
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
INSERT INTO t1 (i) VALUES (NULL), (NULL);
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
END |
CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA
BEGIN
INSERT INTO t1 (i) VALUES (NULL);
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
INSERT INTO t1 (i) VALUES (NULL), (NULL);
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
RETURN 0;
END |
CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC
RETURN LAST_INSERT_ID() |
CREATE FUNCTION f3() RETURNS INT MODIFIES SQL DATA
BEGIN
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
RETURN 0;
END |
BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID Non-upper-level INSERTs (the ones in the body of stored procedure, stored function, or trigger) into a table that have AUTO_INCREMENT column didn't affected the result of LAST_INSERT_ID() on this level. The problem was introduced with the fix of bug 6880, which in turn was introduced with the fix of bug 3117, where current insert_id value was remembered on the first call to LAST_INSERT_ID() (bug 3117) and was returned from that function until it was reset before the next _upper-level_ statement (bug 6880). The fix for bug#21726 brings back the behaviour of version 4.0, and implements the following: remember insert_id value at the beginning of the statement or expression (which at that point equals to the first insert_id value generated by the previous statement), and return that remembered value from LAST_INSERT_ID() or @@LAST_INSERT_ID. Thus, the value returned by LAST_INSERT_ID() is not affected by values generated by current statement, nor by LAST_INSERT_ID(expr) calls in this statement. Version 5.1 does not have this bug (it was fixed by WL 3146). mysql-test/r/rpl_insert_id.result: Add results for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. mysql-test/t/rpl_insert_id.test: Add test cases for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. sql/item_func.cc: Add implementation of Item_func_last_insert_id::fix_fields(), where we remember in THD::current_insert_id the first value generated during execution of the previous statement, which is returned then from Item_func_last_insert_id::val_int(). sql/item_func.h: Add declaration of Item_func_last_insert_id::fix_fields(). sql/log_event.cc: Do not set THD::last_insert_id_used on LAST_INSERT_ID_EVENT. Though we know the statement will call LAST_INSERT_ID(), it wasn't called yet. sql/set_var.cc: In sys_var_last_insert_id::value_ptr() remember in THD::current_insert_id the first value generated during execution of the previous statement, and return this value for @@LAST_INSERT_ID. sql/sql_class.cc: Reset THD::last_insert_id_used after each statement execution. sql/sql_class.h: Rather then remember current insert_id value on first invocation of THD::insert_id(), remember it in Item_func_last_insert_id::fix_fields(), sys_var_last_insert_id::value_ptr(), or mysql_execute_command(). Remove THD::insert_id(), as it lost its value now. sql/sql_insert.cc: THD::insert_id() is removed, use THD::last_insert_id directly. sql/sql_load.cc: THD::insert_id() is removed, using THD::last_insert_id directly is OK. sql/sql_parse.cc: Remember in THD::current_insert_id first generated insert id value of the previous statement in mysql_execute_command(). No need to reset THD::last_insert_id_used in mysql_reset_thd_for_next_command(), it will be reset after each statement. sql/sql_select.cc: If "IS NULL" is replaced with "= <LAST_INSERT_ID>", use right value, which is THD::current_insert_id, and also set THD::last_insert_id_used to issue binary log LAST_INSERT_ID_EVENT. sql/sql_update.cc: THD::insert_id() is removed, use THD::last_insert_id directly. tests/mysql_client_test.c: Add test case for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID.
2006-10-02 12:28:23 +02:00
delimiter ;|
INSERT INTO t1 VALUES (NULL, -1);
CALL p1();
SELECT f1();
INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
(NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
INSERT INTO t1 VALUES (NULL, f2());
INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)),
(NULL, @@LAST_INSERT_ID);
# Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID".
INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());
UPDATE t1 SET j= -1 WHERE i IS NULL;
# Test statement-based replication of function calls.
INSERT INTO t1 (i) VALUES (NULL);
connection master1;
INSERT INTO t1 (i) VALUES (NULL);
connection master;
SELECT f3();
BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID Non-upper-level INSERTs (the ones in the body of stored procedure, stored function, or trigger) into a table that have AUTO_INCREMENT column didn't affected the result of LAST_INSERT_ID() on this level. The problem was introduced with the fix of bug 6880, which in turn was introduced with the fix of bug 3117, where current insert_id value was remembered on the first call to LAST_INSERT_ID() (bug 3117) and was returned from that function until it was reset before the next _upper-level_ statement (bug 6880). The fix for bug#21726 brings back the behaviour of version 4.0, and implements the following: remember insert_id value at the beginning of the statement or expression (which at that point equals to the first insert_id value generated by the previous statement), and return that remembered value from LAST_INSERT_ID() or @@LAST_INSERT_ID. Thus, the value returned by LAST_INSERT_ID() is not affected by values generated by current statement, nor by LAST_INSERT_ID(expr) calls in this statement. Version 5.1 does not have this bug (it was fixed by WL 3146). mysql-test/r/rpl_insert_id.result: Add results for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. mysql-test/t/rpl_insert_id.test: Add test cases for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. sql/item_func.cc: Add implementation of Item_func_last_insert_id::fix_fields(), where we remember in THD::current_insert_id the first value generated during execution of the previous statement, which is returned then from Item_func_last_insert_id::val_int(). sql/item_func.h: Add declaration of Item_func_last_insert_id::fix_fields(). sql/log_event.cc: Do not set THD::last_insert_id_used on LAST_INSERT_ID_EVENT. Though we know the statement will call LAST_INSERT_ID(), it wasn't called yet. sql/set_var.cc: In sys_var_last_insert_id::value_ptr() remember in THD::current_insert_id the first value generated during execution of the previous statement, and return this value for @@LAST_INSERT_ID. sql/sql_class.cc: Reset THD::last_insert_id_used after each statement execution. sql/sql_class.h: Rather then remember current insert_id value on first invocation of THD::insert_id(), remember it in Item_func_last_insert_id::fix_fields(), sys_var_last_insert_id::value_ptr(), or mysql_execute_command(). Remove THD::insert_id(), as it lost its value now. sql/sql_insert.cc: THD::insert_id() is removed, use THD::last_insert_id directly. sql/sql_load.cc: THD::insert_id() is removed, using THD::last_insert_id directly is OK. sql/sql_parse.cc: Remember in THD::current_insert_id first generated insert id value of the previous statement in mysql_execute_command(). No need to reset THD::last_insert_id_used in mysql_reset_thd_for_next_command(), it will be reset after each statement. sql/sql_select.cc: If "IS NULL" is replaced with "= <LAST_INSERT_ID>", use right value, which is THD::current_insert_id, and also set THD::last_insert_id_used to issue binary log LAST_INSERT_ID_EVENT. sql/sql_update.cc: THD::insert_id() is removed, use THD::last_insert_id directly. tests/mysql_client_test.c: Add test case for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID.
2006-10-02 12:28:23 +02:00
SELECT * FROM t1;
SELECT * FROM t2;
sync_slave_with_master;
SELECT * FROM t1;
SELECT * FROM t2;
connection master;
DROP PROCEDURE p1;
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP FUNCTION f3;
BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID Non-upper-level INSERTs (the ones in the body of stored procedure, stored function, or trigger) into a table that have AUTO_INCREMENT column didn't affected the result of LAST_INSERT_ID() on this level. The problem was introduced with the fix of bug 6880, which in turn was introduced with the fix of bug 3117, where current insert_id value was remembered on the first call to LAST_INSERT_ID() (bug 3117) and was returned from that function until it was reset before the next _upper-level_ statement (bug 6880). The fix for bug#21726 brings back the behaviour of version 4.0, and implements the following: remember insert_id value at the beginning of the statement or expression (which at that point equals to the first insert_id value generated by the previous statement), and return that remembered value from LAST_INSERT_ID() or @@LAST_INSERT_ID. Thus, the value returned by LAST_INSERT_ID() is not affected by values generated by current statement, nor by LAST_INSERT_ID(expr) calls in this statement. Version 5.1 does not have this bug (it was fixed by WL 3146). mysql-test/r/rpl_insert_id.result: Add results for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. mysql-test/t/rpl_insert_id.test: Add test cases for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID, and bug#20339: stored procedure using LAST_INSERT_ID() does not replicate statement-based. sql/item_func.cc: Add implementation of Item_func_last_insert_id::fix_fields(), where we remember in THD::current_insert_id the first value generated during execution of the previous statement, which is returned then from Item_func_last_insert_id::val_int(). sql/item_func.h: Add declaration of Item_func_last_insert_id::fix_fields(). sql/log_event.cc: Do not set THD::last_insert_id_used on LAST_INSERT_ID_EVENT. Though we know the statement will call LAST_INSERT_ID(), it wasn't called yet. sql/set_var.cc: In sys_var_last_insert_id::value_ptr() remember in THD::current_insert_id the first value generated during execution of the previous statement, and return this value for @@LAST_INSERT_ID. sql/sql_class.cc: Reset THD::last_insert_id_used after each statement execution. sql/sql_class.h: Rather then remember current insert_id value on first invocation of THD::insert_id(), remember it in Item_func_last_insert_id::fix_fields(), sys_var_last_insert_id::value_ptr(), or mysql_execute_command(). Remove THD::insert_id(), as it lost its value now. sql/sql_insert.cc: THD::insert_id() is removed, use THD::last_insert_id directly. sql/sql_load.cc: THD::insert_id() is removed, using THD::last_insert_id directly is OK. sql/sql_parse.cc: Remember in THD::current_insert_id first generated insert id value of the previous statement in mysql_execute_command(). No need to reset THD::last_insert_id_used in mysql_reset_thd_for_next_command(), it will be reset after each statement. sql/sql_select.cc: If "IS NULL" is replaced with "= <LAST_INSERT_ID>", use right value, which is THD::current_insert_id, and also set THD::last_insert_id_used to issue binary log LAST_INSERT_ID_EVENT. sql/sql_update.cc: THD::insert_id() is removed, use THD::last_insert_id directly. tests/mysql_client_test.c: Add test case for bug#21726: Incorrect result with multiple invocations of LAST_INSERT_ID.
2006-10-02 12:28:23 +02:00
DROP TABLE t1, t2;
sync_slave_with_master;
--echo
--echo # End of 5.0 tests
--echo
Fix for BUG#20188 "REPLACE or ON DUPLICATE KEY UPDATE in auto_increment breaks binlog": if slave's table had a higher auto_increment counter than master's (even though all rows of the two tables were identical), then in some cases, REPLACE and INSERT ON DUPLICATE KEY UPDATE failed to replicate statement-based (it inserted different values on slave from on master). write_record() contained a "thd->next_insert_id=0" to force an adjustment of thd->next_insert_id after the update or replacement. But it is this assigment introduced indeterminism of the statement on the slave, thus the bug. For ON DUPLICATE, we replace that assignment by a call to handler::adjust_next_insert_id_after_explicit_value() which is deterministic (does not depend on slave table's autoinc counter). For REPLACE, this assignment can simply be removed (as REPLACE can't insert a number larger than thd->next_insert_id). We also move a too early restore_auto_increment() down to when we really know that we can restore the value. mysql-test/r/rpl_insert_id.result: result update, without the bugfix, slave's "3 350" were "4 350". mysql-test/t/rpl_insert_id.test: test for BUG#20188 "REPLACE or ON DUPLICATE KEY UPDATE in auto_increment breaks binlog". There is, in this order: - a test of the bug for the case of REPLACE - a test of basic ON DUPLICATE KEY UPDATE functionality which was not tested before - a test of the bug for the case of ON DUPLICATE KEY UPDATE sql/handler.cc: the adjustment of next_insert_id if inserting a big explicit value, is moved to a separate method to be used elsewhere. sql/handler.h: see handler.cc sql/sql_insert.cc: restore_auto_increment() means "I know I won't use this autogenerated autoincrement value, you are free to reuse it for next row". But we were calling restore_auto_increment() in the case of REPLACE: if write_row() fails inserting the row, we don't know that we won't use the value, as we are going to try again by doing internally an UPDATE of the existing row, or a DELETE of the existing row and then an INSERT. So I move restore_auto_increment() further down, when we know for sure we failed all possibilities for the row. Additionally, in case of REPLACE, we don't need to reset THD::next_insert_id: the value of thd->next_insert_id will be suitable for the next row. In case of ON DUPLICATE KEY UPDATE, resetting thd->next_insert_id is also wrong (breaks statement-based binlog), but cannot simply be removed, as thd->next_insert_id must be adjusted if the explicit value exceeds it. We now do the adjustment by calling handler::adjust_next_insert_id_after_explicit_value() (which, contrary to thd->next_insert_id=0, does not depend on the slave table's autoinc counter, and so is deterministic).
2006-07-05 14:41:35 +02:00
2006-05-29 12:45:20 +02:00