Commit 059ad42f authored by unknown's avatar unknown

This patch removes unnecessary lock from the supremum record, takes

X-locks on duplicates also on LOAD DATA...REPLACE clause and
fixes a bug #6086 adding --disable_warnings and --enable_warnings around
the create table clauses in ctype_utf8 tests for InnoDB.


innobase/dict/dict0dict.c:
  Remove static.
innobase/include/dict0dict.h:
  Add prototype for a function dict_scan_to
innobase/row/row0ins.c:
  Add support for a LOAD DATA INFILE 'xxx' REPLACE INTO TABLE x. We should
  take X-locks on both REPLACE and LOAD DATA...REPLACE queries to duplicate
  records.
innobase/row/row0sel.c:
  If innodb_locks_unsafe_for_binlog options is used we do not lock
  gaps. Supremum record is really a dummy record i.e. gap, therefore 
  we do set locks there.
mysql-test/t/ctype_utf8.test:
  Fix bug #6086: Add --disable_warnings and --enable_warnings around the 
  create table where engine=innodb.
parent e82bcce7
...@@ -2244,7 +2244,7 @@ dict_foreign_add_to_cache( ...@@ -2244,7 +2244,7 @@ dict_foreign_add_to_cache(
Scans from pointer onwards. Stops if is at the start of a copy of Scans from pointer onwards. Stops if is at the start of a copy of
'string' where characters are compared without case sensitivity. Stops 'string' where characters are compared without case sensitivity. Stops
also at '\0'. */ also at '\0'. */
static
const char* const char*
dict_scan_to( dict_scan_to(
/*=========*/ /*=========*/
......
...@@ -891,6 +891,18 @@ dict_tables_have_same_db( ...@@ -891,6 +891,18 @@ dict_tables_have_same_db(
const char* name2); /* in: table name in the form const char* name2); /* in: table name in the form
dbname '/' tablename */ dbname '/' tablename */
/*************************************************************************
Scans from pointer onwards. Stops if is at the start of a copy of
'string' where characters are compared without case sensitivity. Stops
also at '\0'. */
const char*
dict_scan_to(
/*=========*/
/* out: scanned up to this */
const char* ptr, /* in: scan from */
const char* string);/* in: look for this */
/* Buffers for storing detailed information about the latest foreign key /* Buffers for storing detailed information about the latest foreign key
and unique key errors */ and unique key errors */
extern FILE* dict_foreign_err_file; extern FILE* dict_foreign_err_file;
......
...@@ -1482,9 +1482,9 @@ row_ins_scan_sec_index_for_duplicate( ...@@ -1482,9 +1482,9 @@ row_ins_scan_sec_index_for_duplicate(
ulint err = DB_SUCCESS; ulint err = DB_SUCCESS;
ibool moved; ibool moved;
mtr_t mtr; mtr_t mtr;
trx_t *trx; trx_t* trx;
ibool success; const char* ptr;
n_unique = dict_index_get_n_unique(index); n_unique = dict_index_get_n_unique(index);
/* If the secondary index is unique, but one of the fields in the /* If the secondary index is unique, but one of the fields in the
...@@ -1523,9 +1523,11 @@ row_ins_scan_sec_index_for_duplicate( ...@@ -1523,9 +1523,11 @@ row_ins_scan_sec_index_for_duplicate(
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
ut_ad(trx); ut_ad(trx);
dict_accept(*trx->mysql_query_str, "REPLACE", &success);
if (success) { ptr = dict_scan_to(*(trx->mysql_query_str),
"REPLACE");
if ( ptr && *ptr != '\0') {
/* The manual defines the REPLACE semantics that it /* The manual defines the REPLACE semantics that it
is either an INSERT or DELETE(s) for duplicate key is either an INSERT or DELETE(s) for duplicate key
...@@ -1605,7 +1607,7 @@ row_ins_duplicate_error_in_clust( ...@@ -1605,7 +1607,7 @@ row_ins_duplicate_error_in_clust(
page_t* page; page_t* page;
ulint n_unique; ulint n_unique;
trx_t* trx = thr_get_trx(thr); trx_t* trx = thr_get_trx(thr);
ibool success; const char* ptr;
UT_NOT_USED(mtr); UT_NOT_USED(mtr);
...@@ -1639,10 +1641,9 @@ row_ins_duplicate_error_in_clust( ...@@ -1639,10 +1641,9 @@ row_ins_duplicate_error_in_clust(
sure that in roll-forward we get the same duplicate sure that in roll-forward we get the same duplicate
errors as in original execution */ errors as in original execution */
dict_accept(*trx->mysql_query_str, "REPLACE", ptr = dict_scan_to(*(trx->mysql_query_str), "REPLACE");
&success);
if (success) { if (ptr && *ptr != '\0') {
/* The manual defines the REPLACE semantics /* The manual defines the REPLACE semantics
that it is either an INSERT or DELETE(s) that it is either an INSERT or DELETE(s)
...@@ -1683,15 +1684,11 @@ row_ins_duplicate_error_in_clust( ...@@ -1683,15 +1684,11 @@ row_ins_duplicate_error_in_clust(
/* The manual defines the REPLACE semantics that it /* The manual defines the REPLACE semantics that it
is either an INSERT or DELETE(s) for duplicate key is either an INSERT or DELETE(s) for duplicate key
+ INSERT. Therefore, we should take X-lock for + INSERT. Therefore, we should take X-lock for
duplicates. duplicates. */
*/
/* Is the first word in MySQL query REPLACE ? */ ptr = dict_scan_to(*(trx->mysql_query_str), "REPLACE");
dict_accept(*trx->mysql_query_str, "REPLACE", if (ptr && *ptr != '\0') {
&success);
if (success) {
err = row_ins_set_exclusive_rec_lock( err = row_ins_set_exclusive_rec_lock(
LOCK_REC_NOT_GAP, LOCK_REC_NOT_GAP,
......
...@@ -2794,7 +2794,7 @@ row_search_for_mysql( ...@@ -2794,7 +2794,7 @@ row_search_for_mysql(
rec_t* index_rec; rec_t* index_rec;
rec_t* clust_rec; rec_t* clust_rec;
rec_t* old_vers; rec_t* old_vers;
ulint err; ulint err = DB_SUCCESS;
ibool moved; ibool moved;
ibool cons_read_requires_clust_rec; ibool cons_read_requires_clust_rec;
ibool was_lock_wait; ibool was_lock_wait;
...@@ -3203,26 +3203,20 @@ row_search_for_mysql( ...@@ -3203,26 +3203,20 @@ row_search_for_mysql(
if (prebuilt->select_lock_type != LOCK_NONE if (prebuilt->select_lock_type != LOCK_NONE
&& set_also_gap_locks) { && set_also_gap_locks) {
/* Try to place a lock on the index record */ /* Try to place a lock on the index record */
/* If innodb_locks_unsafe_for_binlog option is used, /* If innodb_locks_unsafe_for_binlog option is used,
we lock only the record, i.e. next-key locking is we do not lock gaps. Supremum record is really
not used. a gap and therefore we do not set locks there. */
*/
if ( srv_locks_unsafe_for_binlog ) if ( srv_locks_unsafe_for_binlog == FALSE )
{
err = sel_set_rec_lock(rec, index,
prebuilt->select_lock_type,
LOCK_REC_NOT_GAP, thr);
}
else
{ {
err = sel_set_rec_lock(rec, index, err = sel_set_rec_lock(rec, index,
prebuilt->select_lock_type, prebuilt->select_lock_type,
LOCK_ORDINARY, thr); LOCK_ORDINARY, thr);
} }
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
goto lock_wait_or_error; goto lock_wait_or_error;
} }
......
...@@ -221,7 +221,9 @@ drop table t1; ...@@ -221,7 +221,9 @@ drop table t1;
# Bug 4521: unique key prefix interacts poorly with utf8 # Bug 4521: unique key prefix interacts poorly with utf8
# InnoDB: keys with prefix compression, case insensitive collation. # InnoDB: keys with prefix compression, case insensitive collation.
# #
--disable_warnings
create table t1 (c varchar(30) character set utf8, unique(c(10))) engine=innodb; create table t1 (c varchar(30) character set utf8, unique(c(10))) engine=innodb;
--enable_warnings
insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z'); insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z');
insert into t1 values ('aaaaaaaaaa'); insert into t1 values ('aaaaaaaaaa');
--error 1062 --error 1062
...@@ -269,7 +271,9 @@ drop table t1; ...@@ -269,7 +271,9 @@ drop table t1;
# Bug 4521: unique key prefix interacts poorly with utf8 # Bug 4521: unique key prefix interacts poorly with utf8
# InnoDB: fixed length keys, case insensitive collation # InnoDB: fixed length keys, case insensitive collation
# #
--disable_warnings
create table t1 (c char(3) character set utf8, unique (c(2))) engine=innodb; create table t1 (c char(3) character set utf8, unique (c(2))) engine=innodb;
--enable_warnings
insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z'); insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z');
insert into t1 values ('a'); insert into t1 values ('a');
insert into t1 values ('aa'); insert into t1 values ('aa');
...@@ -504,10 +508,12 @@ drop table t1; ...@@ -504,10 +508,12 @@ drop table t1;
# Bug#4594: column index make = failed for gbk, but like works # Bug#4594: column index make = failed for gbk, but like works
# Check InnoDB # Check InnoDB
# #
--disable_warnings
create table t1 ( create table t1 (
str varchar(255) character set utf8 not null, str varchar(255) character set utf8 not null,
key str (str(2)) key str (str(2))
) engine=innodb; ) engine=innodb;
--enable_warnings
INSERT INTO t1 VALUES ('str'); INSERT INTO t1 VALUES ('str');
INSERT INTO t1 VALUES ('str2'); INSERT INTO t1 VALUES ('str2');
select * from t1 where str='str'; select * from t1 where str='str';
...@@ -562,11 +568,13 @@ DROP TABLE t1; ...@@ -562,11 +568,13 @@ DROP TABLE t1;
# #
# Bug #5723: length(<varchar utf8 field>) returns varying results # Bug #5723: length(<varchar utf8 field>) returns varying results
# #
--disable_warnings
SET NAMES utf8; SET NAMES utf8;
CREATE TABLE t1 ( CREATE TABLE t1 (
subject varchar(255) character set utf8 collate utf8_unicode_ci, subject varchar(255) character set utf8 collate utf8_unicode_ci,
p varchar(15) character set utf8 p varchar(15) character set utf8
) ENGINE=InnoDB DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--enable_warnings
INSERT INTO t1 VALUES ('谷川俊二と申しますが、インターネット予約の会員登録をしましたところ、メールアドレスを間違えてしまい会員IDが受け取ることが出来ませんでした。間違えアドレスはtani-shun@n.vodafone.ne.jpを書き込みました。どうすればよいですか? その他、住所等は間違えありません。連絡ください。よろしくお願いします。m(__)m','040312-000057'); INSERT INTO t1 VALUES ('谷川俊二と申しますが、インターネット予約の会員登録をしましたところ、メールアドレスを間違えてしまい会員IDが受け取ることが出来ませんでした。間違えアドレスはtani-shun@n.vodafone.ne.jpを書き込みました。どうすればよいですか? その他、住所等は間違えありません。連絡ください。よろしくお願いします。m(__)m','040312-000057');
INSERT INTO t1 VALUES ('aaa','bbb'); INSERT INTO t1 VALUES ('aaa','bbb');
SELECT length(subject) FROM t1; SELECT length(subject) FROM t1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment