mariadb/mysql-test/t/ndb_replace.test
dlenev@mysql.com d4450e6696 Fix for bug#18437 "Wrong values inserted with a before update trigger on
NDB table".

SQL-layer was not marking fields which were used in triggers as such. As
result these fields were not always properly retrieved/stored by handler
layer. So one might got wrong values or lost changes in triggers for NDB,
Federated and possibly InnoDB tables.
This fix solves the problem by marking fields used in triggers
appropriately.

Also this patch contains the following cleanup of ha_ndbcluster code:

We no longer rely on reading LEX::sql_command value in handler in order
to determine if we can enable optimization which allows us to handle REPLACE
statement in more efficient way by doing replaces directly in write_row()
method without reporting error to SQL-layer.
Instead we rely on SQL-layer informing us whether this optimization
applicable by calling handler::extra() method with
HA_EXTRA_WRITE_CAN_REPLACE flag.
As result we no longer apply this optimzation in cases when it should not
be used (e.g. if we have on delete triggers on table) and use in some
additional cases when it is applicable (e.g. for LOAD DATA REPLACE).

Finally this patch includes fix for bug#20728 "REPLACE does not work
correctly for NDB table with PK and unique index".
  
This was yet another problem which was caused by improper field mark-up.
During row replacement fields which weren't explicity used in REPLACE
statement were not marked as fields to be saved (updated) so they have
retained values from old row version. The fix is to mark all table
fields as set for REPLACE statement. Note that in 5.1 we already solve
this problem by notifying handler that it should save values from all
fields only in case when real replacement happens.
2006-07-02 01:51:10 +04:00

104 lines
3.3 KiB
Text

-- source include/have_ndb.inc
-- source include/not_embedded.inc
#
# Test of REPLACE with NDB
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
CREATE TABLE t1 (
gesuchnr int(11) DEFAULT '0' NOT NULL,
benutzer_id int(11) DEFAULT '0' NOT NULL,
PRIMARY KEY (gesuchnr,benutzer_id)
) engine=ndbcluster;
replace into t1 (gesuchnr,benutzer_id) values (2,1);
replace into t1 (gesuchnr,benutzer_id) values (1,1);
replace into t1 (gesuchnr,benutzer_id) values (1,1);
insert into t1 (gesuchnr, benutzer_id) value (3,2);
replace into t1 (gesuchnr,benutzer_id) values (1,1);
replace into t1 (gesuchnr,benutzer_id) values (1,1);
--error 1062
insert into t1 (gesuchnr,benutzer_id) values (1,1);
replace into t1 (gesuchnr,benutzer_id) values (1,1);
select * from t1 order by gesuchnr;
drop table t1;
# End of 4.1 tests
# bug#17431
CREATE TABLE t1(i INT PRIMARY KEY AUTO_INCREMENT,
j INT,
k INT,
UNIQUE INDEX(j)
) ENGINE = ndb;
INSERT INTO t1 VALUES (1,1,23),(2,2,24);
REPLACE INTO t1 (j,k) VALUES (1,42);
REPLACE INTO t1 (i,j) VALUES (17,2);
SELECT * from t1 ORDER BY i;
DROP TABLE t1;
# bug#19906
CREATE TABLE t2 (a INT(11) NOT NULL,
b INT(11) NOT NULL,
c INT(11) NOT NULL,
x TEXT,
y TEXT,
z TEXT,
id INT(10) unsigned NOT NULL AUTO_INCREMENT,
i INT(11) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY a (a,b,c)
) ENGINE=ndbcluster;
REPLACE INTO t2 (a,b,c,x,y,z,i) VALUES (1,1,1,'a','a','a',1),(1,1,1,'b','b','b',2), (1,1,1,'c','c','c',3);
SELECT * FROM t2 ORDER BY id;
REPLACE INTO t2(a,b,c,x,y,z,i) values (1,1,1,'a','a','a',1);
REPLACE INTO t2(a,b,c,x,y,z,i) values (1,1,1,'b','b','b',2);
SELECT * FROM t2 ORDER BY id;
DROP TABLE t2;
#
# Bug #20728 "REPLACE does not work correctly for NDB table with PK and
# unique index"
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (pk int primary key, apk int unique, data int) engine=ndbcluster;
# Test for plain replace which updates pk
insert into t1 values (1, 1, 1), (2, 2, 2), (3, 3, 3);
replace into t1 (pk, apk) values (4, 1), (5, 2);
select * from t1 order by pk;
delete from t1;
# Another test for plain replace which doesn't touch pk
insert into t1 values (1, 1, 1), (2, 2, 2), (3, 3, 3);
replace into t1 (pk, apk) values (1, 4), (2, 5);
select * from t1 order by pk;
delete from t1;
# Test for load data replace which updates pk
insert into t1 values (1, 1, 1), (4, 4, 4), (6, 6, 6);
load data infile '../std_data_ln/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
select * from t1 order by pk;
delete from t1;
# Now test for load data replace which doesn't touch pk
insert into t1 values (1, 1, 1), (3, 3, 3), (5, 5, 5);
load data infile '../std_data_ln/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
select * from t1 order by pk;
delete from t1;
# Finally test for both types of replace ... select
insert into t1 values (1, 1, 1), (2, 2, 2), (3, 3, 3);
replace into t1 (pk, apk) select 4, 1;
replace into t1 (pk, apk) select 2, 4;
select * from t1 order by pk;
# Clean-up
drop table t1;
--echo End of 5.0 tests.