mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 05:52:27 +01:00
Auto merge
This commit is contained in:
commit
32aa144551
35 changed files with 897 additions and 376 deletions
|
@ -953,7 +953,8 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
|
|||
server_field.type <= (int) MYSQL_TYPE_BLOB) ?
|
||||
server_field.length / item->collation.collation->mbminlen :
|
||||
server_field.length / item->collation.collation->mbmaxlen;
|
||||
client_field->length= max_char_len * thd_cs->mbmaxlen;
|
||||
client_field->length= char_to_byte_length_safe(max_char_len,
|
||||
thd_cs->mbmaxlen);
|
||||
}
|
||||
client_field->type= server_field.type;
|
||||
client_field->flags= server_field.flags;
|
||||
|
|
|
@ -1034,5 +1034,48 @@ DROP TABLE t1;
|
|||
SET max_sort_length=DEFAULT;
|
||||
SET NAMES latin1;
|
||||
#
|
||||
# Bug#52520 Difference in tinytext utf column metadata
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
s1 TINYTEXT CHARACTER SET utf16,
|
||||
s2 TEXT CHARACTER SET utf16,
|
||||
s3 MEDIUMTEXT CHARACTER SET utf16,
|
||||
s4 LONGTEXT CHARACTER SET utf16
|
||||
);
|
||||
SET NAMES utf8, @@character_set_results=NULL;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 255 0 Y 16 0 54
|
||||
def test t1 t1 s2 s2 252 65535 0 Y 16 0 54
|
||||
def test t1 t1 s3 s3 252 16777215 0 Y 16 0 54
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 54
|
||||
def HEX(s1) 253 6120 0 Y 0 0 33
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
SET NAMES latin1;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 127 0 Y 16 0 8
|
||||
def test t1 t1 s2 s2 252 32767 0 Y 16 0 8
|
||||
def test t1 t1 s3 s3 252 8388607 0 Y 16 0 8
|
||||
def test t1 t1 s4 s4 252 2147483647 0 Y 16 0 8
|
||||
def HEX(s1) 253 2040 0 Y 0 0 8
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
SET NAMES utf8;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 381 0 Y 16 0 33
|
||||
def test t1 t1 s2 s2 252 98301 0 Y 16 0 33
|
||||
def test t1 t1 s3 s3 252 25165821 0 Y 16 0 33
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 33
|
||||
def HEX(s1) 253 6120 0 Y 0 0 33
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
CREATE TABLE t2 AS SELECT CONCAT(s1) FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`CONCAT(s1)` varchar(255) CHARACTER SET utf16 DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 5.5 tests
|
||||
#
|
||||
|
|
|
@ -1048,5 +1048,48 @@ DROP TABLE t1;
|
|||
SET max_sort_length=DEFAULT;
|
||||
SET NAMES latin1;
|
||||
#
|
||||
# Bug#52520 Difference in tinytext utf column metadata
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
s1 TINYTEXT CHARACTER SET utf32,
|
||||
s2 TEXT CHARACTER SET utf32,
|
||||
s3 MEDIUMTEXT CHARACTER SET utf32,
|
||||
s4 LONGTEXT CHARACTER SET utf32
|
||||
);
|
||||
SET NAMES utf8mb4, @@character_set_results=NULL;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 255 0 Y 16 0 60
|
||||
def test t1 t1 s2 s2 252 65535 0 Y 16 0 60
|
||||
def test t1 t1 s3 s3 252 16777215 0 Y 16 0 60
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 60
|
||||
def HEX(s1) 253 8160 0 Y 0 0 45
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
SET NAMES latin1;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 63 0 Y 16 0 8
|
||||
def test t1 t1 s2 s2 252 16383 0 Y 16 0 8
|
||||
def test t1 t1 s3 s3 252 4194303 0 Y 16 0 8
|
||||
def test t1 t1 s4 s4 252 1073741823 0 Y 16 0 8
|
||||
def HEX(s1) 253 2040 0 Y 0 0 8
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
SET NAMES utf8mb4;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 252 0 Y 16 0 45
|
||||
def test t1 t1 s2 s2 252 65532 0 Y 16 0 45
|
||||
def test t1 t1 s3 s3 252 16777212 0 Y 16 0 45
|
||||
def test t1 t1 s4 s4 252 4294967292 0 Y 16 0 45
|
||||
def HEX(s1) 253 8160 0 Y 0 0 45
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
CREATE TABLE t2 AS SELECT CONCAT(s1) FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`CONCAT(s1)` varchar(255) CHARACTER SET utf32 DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 5.5 tests
|
||||
#
|
||||
|
|
|
@ -2041,3 +2041,52 @@ predicted_order hex(utf8_encoding)
|
|||
101 E0B78AE2808DE0B6BB
|
||||
DROP TABLE t1;
|
||||
End of 5.4 tests
|
||||
#
|
||||
# Start of 5.5 tests
|
||||
#
|
||||
#
|
||||
# Bug#52520 Difference in tinytext utf column metadata
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
s1 TINYTEXT CHARACTER SET utf8,
|
||||
s2 TEXT CHARACTER SET utf8,
|
||||
s3 MEDIUMTEXT CHARACTER SET utf8,
|
||||
s4 LONGTEXT CHARACTER SET utf8
|
||||
);
|
||||
SET NAMES utf8, @@character_set_results=NULL;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 255 0 Y 16 0 33
|
||||
def test t1 t1 s2 s2 252 65535 0 Y 16 0 33
|
||||
def test t1 t1 s3 s3 252 16777215 0 Y 16 0 33
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 33
|
||||
def HEX(s1) 253 4590 0 Y 0 0 33
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
SET NAMES latin1;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 255 0 Y 16 0 8
|
||||
def test t1 t1 s2 s2 252 65535 0 Y 16 0 8
|
||||
def test t1 t1 s3 s3 252 16777215 0 Y 16 0 8
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 8
|
||||
def HEX(s1) 253 1530 0 Y 0 0 8
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
SET NAMES utf8;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 765 0 Y 16 0 33
|
||||
def test t1 t1 s2 s2 252 196605 0 Y 16 0 33
|
||||
def test t1 t1 s3 s3 252 50331645 0 Y 16 0 33
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 33
|
||||
def HEX(s1) 253 4590 0 Y 0 0 33
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
CREATE TABLE t2 AS SELECT CONCAT(s1) FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`CONCAT(s1)` varchar(255) CHARACTER SET utf8 DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 5.5 tests
|
||||
#
|
||||
|
|
|
@ -2471,6 +2471,49 @@ abc𐐀def
|
|||
𐐀
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#52520 Difference in tinytext utf column metadata
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
s1 TINYTEXT CHARACTER SET utf8mb4,
|
||||
s2 TEXT CHARACTER SET utf8mb4,
|
||||
s3 MEDIUMTEXT CHARACTER SET utf8mb4,
|
||||
s4 LONGTEXT CHARACTER SET utf8mb4
|
||||
);
|
||||
SET NAMES utf8mb4, @@character_set_results=NULL;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 255 0 Y 16 0 45
|
||||
def test t1 t1 s2 s2 252 65535 0 Y 16 0 45
|
||||
def test t1 t1 s3 s3 252 16777215 0 Y 16 0 45
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 45
|
||||
def HEX(s1) 253 8160 0 Y 0 0 45
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
SET NAMES latin1;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 255 0 Y 16 0 8
|
||||
def test t1 t1 s2 s2 252 65535 0 Y 16 0 8
|
||||
def test t1 t1 s3 s3 252 16777215 0 Y 16 0 8
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 8
|
||||
def HEX(s1) 253 2040 0 Y 0 0 8
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
SET NAMES utf8mb4;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 s1 s1 252 1020 0 Y 16 0 45
|
||||
def test t1 t1 s2 s2 252 262140 0 Y 16 0 45
|
||||
def test t1 t1 s3 s3 252 67108860 0 Y 16 0 45
|
||||
def test t1 t1 s4 s4 252 4294967295 0 Y 16 0 45
|
||||
def HEX(s1) 253 8160 0 Y 0 0 45
|
||||
s1 s2 s3 s4 HEX(s1)
|
||||
CREATE TABLE t2 AS SELECT CONCAT(s1) FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`CONCAT(s1)` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 5.5 tests
|
||||
#
|
||||
#
|
||||
|
|
|
@ -2648,7 +2648,7 @@ create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
|
|||
create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
|
||||
insert into t1 values (0x41),(0x4120),(0x4100);
|
||||
insert into t2 values (0x41),(0x4120),(0x4100);
|
||||
ERROR 23000: Duplicate entry 'A\x00' for key 'PRIMARY'
|
||||
ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
|
||||
insert into t2 values (0x41),(0x4120);
|
||||
insert into t3 values (0x41),(0x4120),(0x4100);
|
||||
ERROR 23000: Duplicate entry 'A ' for key 'PRIMARY'
|
||||
|
|
43
mysql-test/suite/innodb/r/innodb_bug53592.result
Normal file
43
mysql-test/suite/innodb/r/innodb_bug53592.result
Normal file
|
@ -0,0 +1,43 @@
|
|||
set old_alter_table=0;
|
||||
create table bug53592(a int) engine=innodb row_format=compact;
|
||||
alter table bug53592 add column b text charset utf8;
|
||||
alter table bug53592 add column c blob not null;
|
||||
create index bug53592_b on bug53592(b(81));
|
||||
create unique index bug53592_c on bug53592(c(1));
|
||||
replace into bug53592 values (),();
|
||||
Warnings:
|
||||
Warning 1364 Field 'c' doesn't have a default value
|
||||
check table bug53592;
|
||||
Table Op Msg_type Msg_text
|
||||
test.bug53592 check status OK
|
||||
drop table bug53592;
|
||||
set old_alter_table=1;
|
||||
create table bug53592(a int) engine=innodb row_format=compact;
|
||||
alter table bug53592 add column b text charset utf8;
|
||||
alter table bug53592 add column c blob not null;
|
||||
create index bug53592_b on bug53592(b(81));
|
||||
create unique index bug53592_c on bug53592(c(1));
|
||||
replace into bug53592 values (),();
|
||||
Warnings:
|
||||
Warning 1364 Field 'c' doesn't have a default value
|
||||
check table bug53592;
|
||||
Table Op Msg_type Msg_text
|
||||
test.bug53592 check status OK
|
||||
drop table bug53592;
|
||||
CREATE TABLE bug53592_1(
|
||||
col1 int, col2 int,
|
||||
PRIMARY KEY (col1, col2)
|
||||
) ENGINE=InnoDB;
|
||||
CREATE TABLE bug53592_2 (
|
||||
col int PRIMARY KEY,
|
||||
FOREIGN KEY (col) REFERENCES bug53592_1 (col1)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO bug53592_1 VALUES (1, 2);
|
||||
INSERT INTO bug53592_1 VALUES (3, 4);
|
||||
INSERT INTO bug53592_2 VALUES (1);
|
||||
INSERT INTO bug53592_2 VALUES (3);
|
||||
UPDATE bug53592_1 SET col1 = 3 WHERE col2 = 2;
|
||||
ERROR 23000: Upholding foreign key constraints for table 'bug53592_1', entry '3-2', key 1 would lead to a duplicate entry
|
||||
drop table bug53592_2;
|
||||
drop table bug53592_1;
|
11
mysql-test/suite/innodb/r/innodb_bug53674.result
Normal file
11
mysql-test/suite/innodb/r/innodb_bug53674.result
Normal file
|
@ -0,0 +1,11 @@
|
|||
create table bug53674(a int)engine=innodb;
|
||||
insert into bug53674 values (1),(2);
|
||||
start transaction;
|
||||
select * from bug53674 for update;
|
||||
a
|
||||
1
|
||||
2
|
||||
select * from bug53674 where a=(select a from bug53674 where a > 1);
|
||||
a
|
||||
2
|
||||
drop table bug53674;
|
82
mysql-test/suite/innodb/t/innodb_bug53592.test
Normal file
82
mysql-test/suite/innodb/t/innodb_bug53592.test
Normal file
|
@ -0,0 +1,82 @@
|
|||
# Testcase for Bug #53592 - "crash replacing duplicates into
|
||||
# table after fast alter table added unique key". The fix is to make
|
||||
# sure index number lookup should go through "index translation table".
|
||||
|
||||
--source include/have_innodb.inc
|
||||
|
||||
# Use FIC for index creation
|
||||
set old_alter_table=0;
|
||||
|
||||
create table bug53592(a int) engine=innodb row_format=compact;
|
||||
|
||||
alter table bug53592 add column b text charset utf8;
|
||||
|
||||
alter table bug53592 add column c blob not null;
|
||||
|
||||
# Create a non-unique nonclustered index
|
||||
create index bug53592_b on bug53592(b(81));
|
||||
|
||||
# Create a unique index, this unique index should have smaller
|
||||
# index number than bug53592_b, since unique index ranks higher
|
||||
# than regular index does
|
||||
create unique index bug53592_c on bug53592(c(1));
|
||||
|
||||
# This will trigger a dup key error and will require fetching
|
||||
# the index number through a index structure for the error reporting.
|
||||
# To get the correct index number, the code should go through index
|
||||
# translation table. Otherwise, it will get the wrong index
|
||||
# number and later trigger a server crash.
|
||||
replace into bug53592 values (),();
|
||||
|
||||
check table bug53592;
|
||||
|
||||
drop table bug53592;
|
||||
|
||||
# Running the same set of test when "old_alter_table" is turned on
|
||||
set old_alter_table=1;
|
||||
|
||||
create table bug53592(a int) engine=innodb row_format=compact;
|
||||
|
||||
alter table bug53592 add column b text charset utf8;
|
||||
|
||||
alter table bug53592 add column c blob not null;
|
||||
|
||||
# Create a non-unique nonclustered index
|
||||
create index bug53592_b on bug53592(b(81));
|
||||
|
||||
# Create a unique index
|
||||
create unique index bug53592_c on bug53592(c(1));
|
||||
|
||||
# This will trigger a dup key error and will require fetching
|
||||
# the index number through a index structure for the error reporting.
|
||||
# To get the correct index number, the code should go through index
|
||||
# translation table. Otherwise, it will get the wrong index
|
||||
# number and later trigger a server crash.
|
||||
replace into bug53592 values (),();
|
||||
|
||||
check table bug53592;
|
||||
drop table bug53592;
|
||||
|
||||
# Test a dup key reported by foreign key constriant.
|
||||
CREATE TABLE bug53592_1(
|
||||
col1 int, col2 int,
|
||||
PRIMARY KEY (col1, col2)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE bug53592_2 (
|
||||
col int PRIMARY KEY,
|
||||
FOREIGN KEY (col) REFERENCES bug53592_1 (col1)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO bug53592_1 VALUES (1, 2);
|
||||
INSERT INTO bug53592_1 VALUES (3, 4);
|
||||
|
||||
INSERT INTO bug53592_2 VALUES (1);
|
||||
INSERT INTO bug53592_2 VALUES (3);
|
||||
|
||||
--error ER_FOREIGN_DUPLICATE_KEY
|
||||
UPDATE bug53592_1 SET col1 = 3 WHERE col2 = 2;
|
||||
|
||||
drop table bug53592_2;
|
||||
drop table bug53592_1;
|
1
mysql-test/suite/innodb/t/innodb_bug53674-master.opt
Normal file
1
mysql-test/suite/innodb/t/innodb_bug53674-master.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--log-bin --innodb-locks-unsafe-for-binlog --binlog-format=mixed
|
8
mysql-test/suite/innodb/t/innodb_bug53674.test
Normal file
8
mysql-test/suite/innodb/t/innodb_bug53674.test
Normal file
|
@ -0,0 +1,8 @@
|
|||
-- source include/have_innodb.inc
|
||||
|
||||
create table bug53674(a int)engine=innodb;
|
||||
insert into bug53674 values (1),(2);
|
||||
start transaction;
|
||||
select * from bug53674 for update;
|
||||
select * from bug53674 where a=(select a from bug53674 where a > 1);
|
||||
drop table bug53674;
|
|
@ -723,6 +723,27 @@ DROP TABLE t1;
|
|||
SET max_sort_length=DEFAULT;
|
||||
SET NAMES latin1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#52520 Difference in tinytext utf column metadata
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
s1 TINYTEXT CHARACTER SET utf16,
|
||||
s2 TEXT CHARACTER SET utf16,
|
||||
s3 MEDIUMTEXT CHARACTER SET utf16,
|
||||
s4 LONGTEXT CHARACTER SET utf16
|
||||
);
|
||||
--enable_metadata
|
||||
SET NAMES utf8, @@character_set_results=NULL;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
SET NAMES latin1;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
SET NAMES utf8;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
--disable_metadata
|
||||
CREATE TABLE t2 AS SELECT CONCAT(s1) FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
#
|
||||
## TODO: add tests for all engines
|
||||
|
|
|
@ -779,6 +779,27 @@ DROP TABLE t1;
|
|||
SET max_sort_length=DEFAULT;
|
||||
SET NAMES latin1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#52520 Difference in tinytext utf column metadata
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
s1 TINYTEXT CHARACTER SET utf32,
|
||||
s2 TEXT CHARACTER SET utf32,
|
||||
s3 MEDIUMTEXT CHARACTER SET utf32,
|
||||
s4 LONGTEXT CHARACTER SET utf32
|
||||
);
|
||||
--enable_metadata
|
||||
SET NAMES utf8mb4, @@character_set_results=NULL;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
SET NAMES latin1;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
SET NAMES utf8mb4;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
--disable_metadata
|
||||
CREATE TABLE t2 AS SELECT CONCAT(s1) FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # End of 5.5 tests
|
||||
--echo #
|
||||
|
|
|
@ -1480,3 +1480,31 @@ DROP TABLE t1;
|
|||
|
||||
--echo End of 5.4 tests
|
||||
|
||||
--echo #
|
||||
--echo # Start of 5.5 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # Bug#52520 Difference in tinytext utf column metadata
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
s1 TINYTEXT CHARACTER SET utf8,
|
||||
s2 TEXT CHARACTER SET utf8,
|
||||
s3 MEDIUMTEXT CHARACTER SET utf8,
|
||||
s4 LONGTEXT CHARACTER SET utf8
|
||||
);
|
||||
--enable_metadata
|
||||
SET NAMES utf8, @@character_set_results=NULL;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
SET NAMES latin1;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
SET NAMES utf8;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
--disable_metadata
|
||||
CREATE TABLE t2 AS SELECT CONCAT(s1) FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # End of 5.5 tests
|
||||
--echo #
|
||||
|
|
|
@ -1789,6 +1789,27 @@ SELECT hex(subject), length(subject), char_length(subject), octet_length(subject
|
|||
SELECT subject FROM t1 ORDER BY 1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#52520 Difference in tinytext utf column metadata
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
s1 TINYTEXT CHARACTER SET utf8mb4,
|
||||
s2 TEXT CHARACTER SET utf8mb4,
|
||||
s3 MEDIUMTEXT CHARACTER SET utf8mb4,
|
||||
s4 LONGTEXT CHARACTER SET utf8mb4
|
||||
);
|
||||
--enable_metadata
|
||||
SET NAMES utf8mb4, @@character_set_results=NULL;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
SET NAMES latin1;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
SET NAMES utf8mb4;
|
||||
SELECT *, HEX(s1) FROM t1;
|
||||
--disable_metadata
|
||||
CREATE TABLE t2 AS SELECT CONCAT(s1) FROM t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # End of 5.5 tests
|
||||
--echo #
|
||||
|
|
33
sql/field.cc
33
sql/field.cc
|
@ -9956,6 +9956,39 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
maximum possible character length for blob.
|
||||
|
||||
This method is used in Item_field::set_field to calculate
|
||||
max_length for Item.
|
||||
|
||||
For example:
|
||||
CREATE TABLE t2 SELECT CONCAT(tinyblob_utf8_column) FROM t1;
|
||||
must create a "VARCHAR(255) CHARACTER SET utf8" column.
|
||||
|
||||
@return
|
||||
length
|
||||
*/
|
||||
|
||||
uint32 Field_blob::char_length()
|
||||
{
|
||||
switch (packlength)
|
||||
{
|
||||
case 1:
|
||||
return 255;
|
||||
case 2:
|
||||
return 65535;
|
||||
case 3:
|
||||
return 16777215;
|
||||
case 4:
|
||||
return (uint32) 4294967295U;
|
||||
default:
|
||||
DBUG_ASSERT(0); // we should never go here
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
maximum possible display length for blob.
|
||||
|
||||
|
|
|
@ -499,7 +499,7 @@ public:
|
|||
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
|
||||
int *err);
|
||||
/* The max. number of characters */
|
||||
inline uint32 char_length() const
|
||||
virtual uint32 char_length()
|
||||
{
|
||||
return field_length / charset()->mbmaxlen;
|
||||
}
|
||||
|
@ -1813,6 +1813,7 @@ public:
|
|||
bool has_charset(void) const
|
||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||
uint32 max_display_length();
|
||||
uint32 char_length();
|
||||
uint is_equal(Create_field *new_field);
|
||||
inline bool in_read_set() { return bitmap_is_set(table->read_set, field_index); }
|
||||
inline bool in_write_set() { return bitmap_is_set(table->write_set, field_index); }
|
||||
|
|
16
sql/item.h
16
sql/item.h
|
@ -34,6 +34,15 @@ void item_init(void); /* Init item functions */
|
|||
class Item_field;
|
||||
class user_var_entry;
|
||||
|
||||
|
||||
static inline uint32
|
||||
char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg)
|
||||
{
|
||||
ulonglong tmp= ((ulonglong) char_length_arg) * mbmaxlen_arg;
|
||||
return (tmp > UINT_MAX32) ? (uint32) UINT_MAX32 : (uint32) tmp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
"Declared Type Collation"
|
||||
A combination of collation and its derivation.
|
||||
|
@ -1171,11 +1180,14 @@ public:
|
|||
{ return max_length / collation.collation->mbmaxlen; }
|
||||
void fix_length_and_charset(uint32 max_char_length_arg, CHARSET_INFO *cs)
|
||||
{
|
||||
max_length= max_char_length_arg * cs->mbmaxlen;
|
||||
max_length= char_to_byte_length_safe(max_char_length_arg, cs->mbmaxlen);
|
||||
collation.collation= cs;
|
||||
}
|
||||
void fix_char_length(uint32 max_char_length_arg)
|
||||
{ max_length= max_char_length_arg * collation.collation->mbmaxlen; }
|
||||
{
|
||||
max_length= char_to_byte_length_safe(max_char_length_arg,
|
||||
collation.collation->mbmaxlen);
|
||||
}
|
||||
void fix_length_and_charset_datetime(uint32 max_char_length_arg)
|
||||
{
|
||||
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
|
||||
|
|
|
@ -747,8 +747,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
|
|||
else
|
||||
{
|
||||
/* With conversion */
|
||||
ulonglong max_length;
|
||||
uint32 field_length;
|
||||
uint32 field_length, max_length;
|
||||
int2store(pos, thd_charset->number);
|
||||
/*
|
||||
For TEXT/BLOB columns, field_length describes the maximum data
|
||||
|
@ -771,9 +770,8 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
|
|||
field.type <= MYSQL_TYPE_BLOB) ?
|
||||
field.length / item->collation.collation->mbminlen :
|
||||
field.length / item->collation.collation->mbmaxlen;
|
||||
max_length*= thd_charset->mbmaxlen;
|
||||
field_length= (max_length > UINT_MAX32) ?
|
||||
UINT_MAX32 : (uint32) max_length;
|
||||
field_length= char_to_byte_length_safe(max_length,
|
||||
thd_charset->mbmaxlen);
|
||||
int4store(pos + 2, field_length);
|
||||
}
|
||||
pos[6]= field.type;
|
||||
|
|
|
@ -131,8 +131,10 @@ enum {
|
|||
LINE_FOR_MASTER_SSL_VERIFY_SERVER_CERT= 15,
|
||||
/* 6.0 added value of master_heartbeat_period */
|
||||
LINE_FOR_MASTER_HEARTBEAT_PERIOD= 16,
|
||||
/* MySQL Cluster 6.3 added master_bind */
|
||||
LINE_FOR_MASTER_BIND = 17,
|
||||
/* 6.0 added value of master_ignore_server_id */
|
||||
LINE_FOR_REPLICATE_IGNORE_SERVER_IDS= 17,
|
||||
LINE_FOR_REPLICATE_IGNORE_SERVER_IDS= 18,
|
||||
/* Number of lines currently used when saving master info file */
|
||||
LINES_IN_MASTER_INFO= LINE_FOR_REPLICATE_IGNORE_SERVER_IDS
|
||||
};
|
||||
|
@ -240,6 +242,7 @@ file '%s')", fname);
|
|||
int ssl= 0, ssl_verify_server_cert= 0;
|
||||
float master_heartbeat_period= 0.0;
|
||||
char *first_non_digit;
|
||||
char dummy_buf[HOSTNAME_LENGTH+1];
|
||||
|
||||
/*
|
||||
Starting from 4.1.x master.info has new format. Now its
|
||||
|
@ -328,6 +331,13 @@ file '%s')", fname);
|
|||
if (lines >= LINE_FOR_MASTER_HEARTBEAT_PERIOD &&
|
||||
init_floatvar_from_file(&master_heartbeat_period, &mi->file, 0.0))
|
||||
goto errwithmsg;
|
||||
/*
|
||||
Starting from MySQL Cluster 6.3 master_bind might be in the file
|
||||
(this is just a reservation to avoid future upgrade problems)
|
||||
*/
|
||||
if (lines >= LINE_FOR_MASTER_BIND &&
|
||||
init_strvar_from_file(dummy_buf, sizeof(dummy_buf), &mi->file, ""))
|
||||
goto errwithmsg;
|
||||
/*
|
||||
Starting from 6.0 list of server_id of ignorable servers might be
|
||||
in the file
|
||||
|
@ -480,14 +490,14 @@ int flush_master_info(Master_info* mi,
|
|||
my_sprintf(heartbeat_buf, (heartbeat_buf, "%.3f", mi->heartbeat_period));
|
||||
my_b_seek(file, 0L);
|
||||
my_b_printf(file,
|
||||
"%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n",
|
||||
"%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n%s\n",
|
||||
LINES_IN_MASTER_INFO,
|
||||
mi->master_log_name, llstr(mi->master_log_pos, lbuf),
|
||||
mi->host, mi->user,
|
||||
mi->password, mi->port, mi->connect_retry,
|
||||
(int)(mi->ssl), mi->ssl_ca, mi->ssl_capath, mi->ssl_cert,
|
||||
mi->ssl_cipher, mi->ssl_key, mi->ssl_verify_server_cert,
|
||||
heartbeat_buf, ignore_server_ids_buf);
|
||||
heartbeat_buf, "", ignore_server_ids_buf);
|
||||
my_free(ignore_server_ids_buf, MYF(0));
|
||||
err= flush_io_cache(file);
|
||||
if (sync_masterinfo_period && !err &&
|
||||
|
|
|
@ -3564,39 +3564,6 @@ next_datadir_item:
|
|||
return(err);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
If we need crash recovery, and we have called
|
||||
fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
|
||||
we can call this function to print an error message of orphaned .ibd files
|
||||
for which there is not a data dictionary entry with a matching table name
|
||||
and space id. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_print_orphaned_tablespaces(void)
|
||||
/*================================*/
|
||||
{
|
||||
fil_space_t* space;
|
||||
|
||||
mutex_enter(&fil_system->mutex);
|
||||
|
||||
space = UT_LIST_GET_FIRST(fil_system->space_list);
|
||||
|
||||
while (space) {
|
||||
if (space->purpose == FIL_TABLESPACE && space->id != 0
|
||||
&& !space->mark) {
|
||||
fputs("InnoDB: Warning: tablespace ", stderr);
|
||||
ut_print_filename(stderr, space->name);
|
||||
fprintf(stderr, " of id %lu has no matching table in\n"
|
||||
"InnoDB: the InnoDB data dictionary.\n",
|
||||
(ulong) space->id);
|
||||
}
|
||||
|
||||
space = UT_LIST_GET_NEXT(space_list, space);
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Returns TRUE if a single-table tablespace does not exist in the memory cache,
|
||||
or is being deleted there.
|
||||
|
|
|
@ -6866,7 +6866,7 @@ ha_innobase::create(
|
|||
(int) form->s->primary_key :
|
||||
-1);
|
||||
|
||||
/* Our function row_get_mysql_key_number_for_index assumes
|
||||
/* Our function innobase_get_mysql_key_number_for_index assumes
|
||||
the primary key is always number 0, if it exists */
|
||||
|
||||
ut_a(primary_key_no == -1 || primary_key_no == 0);
|
||||
|
@ -7582,6 +7582,84 @@ ha_innobase::read_time(
|
|||
return(ranges + (double) rows / (double) total_rows * time_for_scan);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Calculates the key number used inside MySQL for an Innobase index. We will
|
||||
first check the "index translation table" for a match of the index to get
|
||||
the index number. If there does not exist an "index translation table",
|
||||
or not able to find the index in the translation table, then we will fall back
|
||||
to the traditional way of looping through dict_index_t list to find a
|
||||
match. In this case, we have to take into account if we generated a
|
||||
default clustered index for the table
|
||||
@return the key number used inside MySQL */
|
||||
static
|
||||
unsigned int
|
||||
innobase_get_mysql_key_number_for_index(
|
||||
/*====================================*/
|
||||
INNOBASE_SHARE* share, /*!< in: share structure for index
|
||||
translation table. */
|
||||
const TABLE* table, /*!< in: table in MySQL data
|
||||
dictionary */
|
||||
dict_table_t* ib_table,/*!< in: table in Innodb data
|
||||
dictionary */
|
||||
const dict_index_t* index) /*!< in: index */
|
||||
{
|
||||
const dict_index_t* ind;
|
||||
unsigned int i;
|
||||
|
||||
ut_a(index);
|
||||
|
||||
/* If index does not belong to the table of share structure. Search
|
||||
index->table instead */
|
||||
if (index->table != ib_table
|
||||
&& innobase_strcasecmp(index->table->name, share->table_name)) {
|
||||
i = 0;
|
||||
ind = dict_table_get_first_index(index->table);
|
||||
|
||||
while (index != ind) {
|
||||
ind = dict_table_get_next_index(ind);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (row_table_got_default_clust_index(index->table)) {
|
||||
ut_a(i > 0);
|
||||
i--;
|
||||
}
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
/* If index translation table exists, we will first check
|
||||
the index through index translation table for a match. */
|
||||
if (share->idx_trans_tbl.index_mapping) {
|
||||
for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
|
||||
if (share->idx_trans_tbl.index_mapping[i] == index) {
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print an error message if we cannot find the index
|
||||
** in the "index translation table". */
|
||||
sql_print_error("Cannot find index %s in InnoDB index "
|
||||
"translation table.", index->name);
|
||||
}
|
||||
|
||||
/* If we do not have an "index translation table", or not able
|
||||
to find the index in the translation table, we'll directly find
|
||||
matching index with information from mysql TABLE structure and
|
||||
InnoDB dict_index_t list */
|
||||
for (i = 0; i < table->s->keys; i++) {
|
||||
ind = dict_table_get_index_on_name(
|
||||
ib_table, table->key_info[i].name);
|
||||
|
||||
if (index == ind) {
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
|
||||
ut_error;
|
||||
|
||||
return(0);
|
||||
}
|
||||
/*********************************************************************//**
|
||||
Returns statistics information of the table to the MySQL interpreter,
|
||||
in various fields of the handle object. */
|
||||
|
@ -7851,8 +7929,8 @@ ha_innobase::info(
|
|||
err_index = trx_get_error_info(prebuilt->trx);
|
||||
|
||||
if (err_index) {
|
||||
errkey = (unsigned int)
|
||||
row_get_mysql_key_number_for_index(err_index);
|
||||
errkey = innobase_get_mysql_key_number_for_index(
|
||||
share, table, ib_table, err_index);
|
||||
} else {
|
||||
errkey = (unsigned int) prebuilt->trx->error_key_num;
|
||||
}
|
||||
|
|
|
@ -1982,7 +1982,7 @@ i_s_dict_fill_sys_tables(
|
|||
|
||||
table_id = ut_conv_dulint_to_longlong(table->id);
|
||||
|
||||
OK(fields[SYS_TABLE_ID]->store(table_id));
|
||||
OK(fields[SYS_TABLE_ID]->store(table_id, TRUE));
|
||||
|
||||
OK(field_store_string(fields[SYS_TABLE_NAME], table->name));
|
||||
|
||||
|
@ -2247,7 +2247,7 @@ i_s_dict_fill_sys_tablestats(
|
|||
|
||||
table_id = ut_conv_dulint_to_longlong(table->id);
|
||||
|
||||
OK(fields[SYS_TABLESTATS_ID]->store(table_id));
|
||||
OK(fields[SYS_TABLESTATS_ID]->store(table_id, TRUE));
|
||||
|
||||
OK(field_store_string(fields[SYS_TABLESTATS_NAME], table->name));
|
||||
|
||||
|
@ -2259,7 +2259,7 @@ i_s_dict_fill_sys_tablestats(
|
|||
"Uninitialized"));
|
||||
}
|
||||
|
||||
OK(fields[SYS_TABLESTATS_NROW]->store(table->stat_n_rows));
|
||||
OK(fields[SYS_TABLESTATS_NROW]->store(table->stat_n_rows, TRUE));
|
||||
|
||||
OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(
|
||||
table->stat_clustered_index_size));
|
||||
|
@ -2270,7 +2270,7 @@ i_s_dict_fill_sys_tablestats(
|
|||
OK(fields[SYS_TABLESTATS_MODIFIED]->store(
|
||||
table->stat_modified_counter));
|
||||
|
||||
OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc));
|
||||
OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, TRUE));
|
||||
|
||||
OK(fields[SYS_TABLESTATS_MYSQL_OPEN_HANDLE]->store(
|
||||
table->n_mysql_handles_opened));
|
||||
|
@ -2511,11 +2511,11 @@ i_s_dict_fill_sys_indexes(
|
|||
table_id = ut_conv_dulint_to_longlong(tableid);
|
||||
index_id = ut_conv_dulint_to_longlong(index->id);
|
||||
|
||||
OK(fields[SYS_INDEX_ID]->store(index_id));
|
||||
OK(fields[SYS_INDEX_ID]->store(index_id, TRUE));
|
||||
|
||||
OK(field_store_string(fields[SYS_INDEX_NAME], index->name));
|
||||
|
||||
OK(fields[SYS_INDEX_TABLE_ID]->store(table_id));
|
||||
OK(fields[SYS_INDEX_TABLE_ID]->store(table_id, TRUE));
|
||||
|
||||
OK(fields[SYS_INDEX_TYPE]->store(index->type));
|
||||
|
||||
|
@ -2752,7 +2752,7 @@ i_s_dict_fill_sys_columns(
|
|||
|
||||
table_id = ut_conv_dulint_to_longlong(tableid);
|
||||
|
||||
OK(fields[SYS_COLUMN_TABLE_ID]->store(table_id));
|
||||
OK(fields[SYS_COLUMN_TABLE_ID]->store(table_id, TRUE));
|
||||
|
||||
OK(field_store_string(fields[SYS_COLUMN_NAME], col_name));
|
||||
|
||||
|
@ -2962,7 +2962,7 @@ i_s_dict_fill_sys_fields(
|
|||
|
||||
index_id = ut_conv_dulint_to_longlong(indexid);
|
||||
|
||||
OK(fields[SYS_FIELD_INDEX_ID]->store(index_id));
|
||||
OK(fields[SYS_FIELD_INDEX_ID]->store(index_id, TRUE));
|
||||
|
||||
OK(field_store_string(fields[SYS_FIELD_NAME], field->name));
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ Created 5/24/1996 Heikki Tuuri
|
|||
|
||||
|
||||
enum db_err {
|
||||
DB_SUCCESS_LOCKED_REC = 9, /*!< like DB_SUCCESS, but a new
|
||||
explicit record lock was created */
|
||||
DB_SUCCESS = 10,
|
||||
|
||||
/* The following are error codes */
|
||||
|
|
|
@ -506,16 +506,6 @@ UNIV_INTERN
|
|||
ulint
|
||||
fil_load_single_table_tablespaces(void);
|
||||
/*===================================*/
|
||||
/********************************************************************//**
|
||||
If we need crash recovery, and we have called
|
||||
fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
|
||||
we can call this function to print an error message of orphaned .ibd files
|
||||
for which there is not a data dictionary entry with a matching table name
|
||||
and space id. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_print_orphaned_tablespaces(void);
|
||||
/*================================*/
|
||||
/*******************************************************************//**
|
||||
Returns TRUE if a single-table tablespace does not exist in the memory cache,
|
||||
or is being deleted there.
|
||||
|
|
|
@ -340,11 +340,12 @@ lock_sec_rec_modify_check_and_lock(
|
|||
que_thr_t* thr, /*!< in: query thread */
|
||||
mtr_t* mtr); /*!< in/out: mini-transaction */
|
||||
/*********************************************************************//**
|
||||
Like the counterpart for a clustered index below, but now we read a
|
||||
Like lock_clust_rec_read_check_and_lock(), but reads a
|
||||
secondary index record.
|
||||
@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
|
||||
or DB_QUE_THR_SUSPENDED */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
enum db_err
|
||||
lock_sec_rec_read_check_and_lock(
|
||||
/*=============================*/
|
||||
ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
|
||||
|
@ -371,9 +372,10 @@ if the query thread should anyway be suspended for some reason; if not, then
|
|||
puts the transaction and the query thread to the lock wait state and inserts a
|
||||
waiting request for a record lock to the lock queue. Sets the requested mode
|
||||
lock on the record.
|
||||
@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
|
||||
or DB_QUE_THR_SUSPENDED */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
enum db_err
|
||||
lock_clust_rec_read_check_and_lock(
|
||||
/*===============================*/
|
||||
ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
|
||||
|
|
|
@ -253,15 +253,6 @@ row_table_got_default_clust_index(
|
|||
/*==============================*/
|
||||
const dict_table_t* table); /*!< in: table */
|
||||
/*********************************************************************//**
|
||||
Calculates the key number used inside MySQL for an Innobase index. We have
|
||||
to take into account if we generated a default clustered index for the table
|
||||
@return the key number used inside MySQL */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
row_get_mysql_key_number_for_index(
|
||||
/*===============================*/
|
||||
const dict_index_t* index); /*!< in: index */
|
||||
/*********************************************************************//**
|
||||
Does an update or delete of a row for MySQL.
|
||||
@return error code or DB_SUCCESS */
|
||||
UNIV_INTERN
|
||||
|
@ -273,27 +264,26 @@ row_update_for_mysql(
|
|||
row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
|
||||
handle */
|
||||
/*********************************************************************//**
|
||||
This can only be used when srv_locks_unsafe_for_binlog is TRUE or
|
||||
session is using a READ COMMITTED isolation level. Before
|
||||
calling this function we must use trx_reset_new_rec_lock_info() and
|
||||
trx_register_new_rec_lock() to store the information which new record locks
|
||||
really were set. This function removes a newly set lock under prebuilt->pcur,
|
||||
and also under prebuilt->clust_pcur. Currently, this is only used and tested
|
||||
in the case of an UPDATE or a DELETE statement, where the row lock is of the
|
||||
LOCK_X type.
|
||||
Thus, this implements a 'mini-rollback' that releases the latest record
|
||||
locks we set.
|
||||
@return error code or DB_SUCCESS */
|
||||
This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
|
||||
session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
|
||||
Before calling this function row_search_for_mysql() must have
|
||||
initialized prebuilt->new_rec_locks to store the information which new
|
||||
record locks really were set. This function removes a newly set
|
||||
clustered index record lock under prebuilt->pcur or
|
||||
prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that
|
||||
releases the latest clustered index record lock we set.
|
||||
@return error code or DB_SUCCESS */
|
||||
UNIV_INTERN
|
||||
int
|
||||
row_unlock_for_mysql(
|
||||
/*=================*/
|
||||
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
|
||||
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL
|
||||
handle */
|
||||
ibool has_latches_on_recs);/*!< TRUE if called so that we have
|
||||
the latches on the records under pcur
|
||||
and clust_pcur, and we do not need to
|
||||
reposition the cursors. */
|
||||
ibool has_latches_on_recs);/*!< in: TRUE if called
|
||||
so that we have the latches on
|
||||
the records under pcur and
|
||||
clust_pcur, and we do not need
|
||||
to reposition the cursors. */
|
||||
/*********************************************************************//**
|
||||
Creates an query graph node of 'update' type to be used in the MySQL
|
||||
interface.
|
||||
|
@ -711,18 +701,17 @@ struct row_prebuilt_struct {
|
|||
ulint new_rec_locks; /*!< normally 0; if
|
||||
srv_locks_unsafe_for_binlog is
|
||||
TRUE or session is using READ
|
||||
COMMITTED isolation level, in a
|
||||
cursor search, if we set a new
|
||||
record lock on an index, this is
|
||||
incremented; this is used in
|
||||
releasing the locks under the
|
||||
cursors if we are performing an
|
||||
UPDATE and we determine after
|
||||
retrieving the row that it does
|
||||
not need to be locked; thus,
|
||||
these can be used to implement a
|
||||
'mini-rollback' that releases
|
||||
the latest record locks */
|
||||
COMMITTED or READ UNCOMMITTED
|
||||
isolation level, set in
|
||||
row_search_for_mysql() if we set a new
|
||||
record lock on the secondary
|
||||
or clustered index; this is
|
||||
used in row_unlock_for_mysql()
|
||||
when releasing the lock under
|
||||
the cursor if we determine
|
||||
after retrieving the row that
|
||||
it does not need to be locked
|
||||
('mini-rollback') */
|
||||
ulint mysql_prefix_len;/*!< byte offset of the end of
|
||||
the last requested column */
|
||||
ulint mysql_row_len; /*!< length in bytes of a row in the
|
||||
|
|
|
@ -622,11 +622,12 @@ struct rw_lock_struct {
|
|||
unsigned cline:14; /*!< Line where created */
|
||||
unsigned last_s_line:14; /*!< Line number where last time s-locked */
|
||||
unsigned last_x_line:14; /*!< Line number where last time x-locked */
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint magic_n; /*!< RW_LOCK_MAGIC_N */
|
||||
};
|
||||
|
||||
/** Value of rw_lock_struct::magic_n */
|
||||
#define RW_LOCK_MAGIC_N 22643
|
||||
#endif /* UNIV_DEBUG */
|
||||
};
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
/** The structure for storing debug info of an rw-lock */
|
||||
|
|
|
@ -1733,11 +1733,11 @@ lock_rec_create(
|
|||
Enqueues a waiting request for a lock which cannot be granted immediately.
|
||||
Checks for deadlocks.
|
||||
@return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or
|
||||
DB_SUCCESS; DB_SUCCESS means that there was a deadlock, but another
|
||||
transaction was chosen as a victim, and we got the lock immediately:
|
||||
no need to wait then */
|
||||
DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that
|
||||
there was a deadlock, but another transaction was chosen as a victim,
|
||||
and we got the lock immediately: no need to wait then */
|
||||
static
|
||||
ulint
|
||||
enum db_err
|
||||
lock_rec_enqueue_waiting(
|
||||
/*=====================*/
|
||||
ulint type_mode,/*!< in: lock mode this
|
||||
|
@ -1809,7 +1809,7 @@ lock_rec_enqueue_waiting(
|
|||
|
||||
if (trx->wait_lock == NULL) {
|
||||
|
||||
return(DB_SUCCESS);
|
||||
return(DB_SUCCESS_LOCKED_REC);
|
||||
}
|
||||
|
||||
trx->que_state = TRX_QUE_LOCK_WAIT;
|
||||
|
@ -1925,6 +1925,16 @@ somebody_waits:
|
|||
return(lock_rec_create(type_mode, block, heap_no, index, trx));
|
||||
}
|
||||
|
||||
/** Record locking request status */
|
||||
enum lock_rec_req_status {
|
||||
/** Failed to acquire a lock */
|
||||
LOCK_REC_FAIL,
|
||||
/** Succeeded in acquiring a lock (implicit or already acquired) */
|
||||
LOCK_REC_SUCCESS,
|
||||
/** Explicitly created a new lock */
|
||||
LOCK_REC_SUCCESS_CREATED
|
||||
};
|
||||
|
||||
/*********************************************************************//**
|
||||
This is a fast routine for locking a record in the most common cases:
|
||||
there are no explicit locks on the page, or there is just one lock, owned
|
||||
|
@ -1932,9 +1942,9 @@ by this transaction, and of the right type_mode. This is a low-level function
|
|||
which does NOT look at implicit locks! Checks lock compatibility within
|
||||
explicit locks. This function sets a normal next-key lock, or in the case of
|
||||
a page supremum record, a gap type lock.
|
||||
@return TRUE if locking succeeded */
|
||||
@return whether the locking succeeded */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
enum lock_rec_req_status
|
||||
lock_rec_lock_fast(
|
||||
/*===============*/
|
||||
ibool impl, /*!< in: if TRUE, no lock is set
|
||||
|
@ -1973,19 +1983,19 @@ lock_rec_lock_fast(
|
|||
lock_rec_create(mode, block, heap_no, index, trx);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
return(LOCK_REC_SUCCESS_CREATED);
|
||||
}
|
||||
|
||||
if (lock_rec_get_next_on_page(lock)) {
|
||||
|
||||
return(FALSE);
|
||||
return(LOCK_REC_FAIL);
|
||||
}
|
||||
|
||||
if (lock->trx != trx
|
||||
|| lock->type_mode != (mode | LOCK_REC)
|
||||
|| lock_rec_get_n_bits(lock) <= heap_no) {
|
||||
|
||||
return(FALSE);
|
||||
return(LOCK_REC_FAIL);
|
||||
}
|
||||
|
||||
if (!impl) {
|
||||
|
@ -1994,10 +2004,11 @@ lock_rec_lock_fast(
|
|||
|
||||
if (!lock_rec_get_nth_bit(lock, heap_no)) {
|
||||
lock_rec_set_nth_bit(lock, heap_no);
|
||||
return(LOCK_REC_SUCCESS_CREATED);
|
||||
}
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
return(LOCK_REC_SUCCESS);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -2005,9 +2016,10 @@ This is the general, and slower, routine for locking a record. This is a
|
|||
low-level function which does NOT look at implicit locks! Checks lock
|
||||
compatibility within explicit locks. This function sets a normal next-key
|
||||
lock, or in the case of a page supremum record, a gap type lock.
|
||||
@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
|
||||
or DB_QUE_THR_SUSPENDED */
|
||||
static
|
||||
ulint
|
||||
enum db_err
|
||||
lock_rec_lock_slow(
|
||||
/*===============*/
|
||||
ibool impl, /*!< in: if TRUE, no lock is set
|
||||
|
@ -2024,7 +2036,6 @@ lock_rec_lock_slow(
|
|||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
trx_t* trx;
|
||||
ulint err;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
|
||||
|
@ -2043,27 +2054,23 @@ lock_rec_lock_slow(
|
|||
/* The trx already has a strong enough lock on rec: do
|
||||
nothing */
|
||||
|
||||
err = DB_SUCCESS;
|
||||
} else if (lock_rec_other_has_conflicting(mode, block, heap_no, trx)) {
|
||||
|
||||
/* If another transaction has a non-gap conflicting request in
|
||||
the queue, as this transaction does not have a lock strong
|
||||
enough already granted on the record, we have to wait. */
|
||||
|
||||
err = lock_rec_enqueue_waiting(mode, block, heap_no,
|
||||
index, thr);
|
||||
} else {
|
||||
if (!impl) {
|
||||
/* Set the requested lock on the record */
|
||||
return(lock_rec_enqueue_waiting(mode, block, heap_no,
|
||||
index, thr));
|
||||
} else if (!impl) {
|
||||
/* Set the requested lock on the record */
|
||||
|
||||
lock_rec_add_to_queue(LOCK_REC | mode, block,
|
||||
heap_no, index, trx);
|
||||
}
|
||||
|
||||
err = DB_SUCCESS;
|
||||
lock_rec_add_to_queue(LOCK_REC | mode, block,
|
||||
heap_no, index, trx);
|
||||
return(DB_SUCCESS_LOCKED_REC);
|
||||
}
|
||||
|
||||
return(err);
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -2072,9 +2079,10 @@ possible, enqueues a waiting lock request. This is a low-level function
|
|||
which does NOT look at implicit locks! Checks lock compatibility within
|
||||
explicit locks. This function sets a normal next-key lock, or in the case
|
||||
of a page supremum record, a gap type lock.
|
||||
@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
|
||||
or DB_QUE_THR_SUSPENDED */
|
||||
static
|
||||
ulint
|
||||
enum db_err
|
||||
lock_rec_lock(
|
||||
/*==========*/
|
||||
ibool impl, /*!< in: if TRUE, no lock is set
|
||||
|
@ -2090,8 +2098,6 @@ lock_rec_lock(
|
|||
dict_index_t* index, /*!< in: index of record */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
ulint err;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
|
||||
|| lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
|
||||
|
@ -2103,18 +2109,20 @@ lock_rec_lock(
|
|||
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
|
||||
|| mode - (LOCK_MODE_MASK & mode) == 0);
|
||||
|
||||
if (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) {
|
||||
|
||||
/* We try a simplified and faster subroutine for the most
|
||||
common cases */
|
||||
|
||||
err = DB_SUCCESS;
|
||||
} else {
|
||||
err = lock_rec_lock_slow(impl, mode, block,
|
||||
heap_no, index, thr);
|
||||
/* We try a simplified and faster subroutine for the most
|
||||
common cases */
|
||||
switch (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) {
|
||||
case LOCK_REC_SUCCESS:
|
||||
return(DB_SUCCESS);
|
||||
case LOCK_REC_SUCCESS_CREATED:
|
||||
return(DB_SUCCESS_LOCKED_REC);
|
||||
case LOCK_REC_FAIL:
|
||||
return(lock_rec_lock_slow(impl, mode, block,
|
||||
heap_no, index, thr));
|
||||
}
|
||||
|
||||
return(err);
|
||||
ut_error;
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -5072,7 +5080,14 @@ lock_rec_insert_check_and_lock(
|
|||
|
||||
lock_mutex_exit_kernel();
|
||||
|
||||
if ((err == DB_SUCCESS) && !dict_index_is_clust(index)) {
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
err = DB_SUCCESS;
|
||||
/* fall through */
|
||||
case DB_SUCCESS:
|
||||
if (dict_index_is_clust(index)) {
|
||||
break;
|
||||
}
|
||||
/* Update the page max trx id field */
|
||||
page_update_max_trx_id(block,
|
||||
buf_block_get_page_zip(block),
|
||||
|
@ -5195,6 +5210,10 @@ lock_clust_rec_modify_check_and_lock(
|
|||
|
||||
ut_ad(lock_rec_queue_validate(block, rec, index, offsets));
|
||||
|
||||
if (UNIV_UNLIKELY(err == DB_SUCCESS_LOCKED_REC)) {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
@ -5261,22 +5280,27 @@ lock_sec_rec_modify_check_and_lock(
|
|||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
if (err == DB_SUCCESS || err == DB_SUCCESS_LOCKED_REC) {
|
||||
/* Update the page max trx id field */
|
||||
/* It might not be necessary to do this if
|
||||
err == DB_SUCCESS (no new lock created),
|
||||
but it should not cost too much performance. */
|
||||
page_update_max_trx_id(block,
|
||||
buf_block_get_page_zip(block),
|
||||
thr_get_trx(thr)->id, mtr);
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Like the counterpart for a clustered index below, but now we read a
|
||||
Like lock_clust_rec_read_check_and_lock(), but reads a
|
||||
secondary index record.
|
||||
@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
|
||||
or DB_QUE_THR_SUSPENDED */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
enum db_err
|
||||
lock_sec_rec_read_check_and_lock(
|
||||
/*=============================*/
|
||||
ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
|
||||
|
@ -5297,8 +5321,8 @@ lock_sec_rec_read_check_and_lock(
|
|||
LOCK_REC_NOT_GAP */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
ulint err;
|
||||
ulint heap_no;
|
||||
enum db_err err;
|
||||
ulint heap_no;
|
||||
|
||||
ut_ad(!dict_index_is_clust(index));
|
||||
ut_ad(block->frame == page_align(rec));
|
||||
|
@ -5349,9 +5373,10 @@ if the query thread should anyway be suspended for some reason; if not, then
|
|||
puts the transaction and the query thread to the lock wait state and inserts a
|
||||
waiting request for a record lock to the lock queue. Sets the requested mode
|
||||
lock on the record.
|
||||
@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
|
||||
or DB_QUE_THR_SUSPENDED */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
enum db_err
|
||||
lock_clust_rec_read_check_and_lock(
|
||||
/*===============================*/
|
||||
ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
|
||||
|
@ -5372,8 +5397,8 @@ lock_clust_rec_read_check_and_lock(
|
|||
LOCK_REC_NOT_GAP */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
ulint err;
|
||||
ulint heap_no;
|
||||
enum db_err err;
|
||||
ulint heap_no;
|
||||
|
||||
ut_ad(dict_index_is_clust(index));
|
||||
ut_ad(block->frame == page_align(rec));
|
||||
|
@ -5444,17 +5469,22 @@ lock_clust_rec_read_check_and_lock_alt(
|
|||
mem_heap_t* tmp_heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
ulint ret;
|
||||
ulint err;
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, &tmp_heap);
|
||||
ret = lock_clust_rec_read_check_and_lock(flags, block, rec, index,
|
||||
err = lock_clust_rec_read_check_and_lock(flags, block, rec, index,
|
||||
offsets, mode, gap_mode, thr);
|
||||
if (tmp_heap) {
|
||||
mem_heap_free(tmp_heap);
|
||||
}
|
||||
return(ret);
|
||||
|
||||
if (UNIV_UNLIKELY(err == DB_SUCCESS_LOCKED_REC)) {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
|
|
|
@ -1121,9 +1121,9 @@ nonstandard_exit_func:
|
|||
/*********************************************************************//**
|
||||
Sets a shared lock on a record. Used in locking possible duplicate key
|
||||
records and also in checking foreign key constraints.
|
||||
@return DB_SUCCESS or error code */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
|
||||
static
|
||||
ulint
|
||||
enum db_err
|
||||
row_ins_set_shared_rec_lock(
|
||||
/*========================*/
|
||||
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
|
||||
|
@ -1134,7 +1134,7 @@ row_ins_set_shared_rec_lock(
|
|||
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
ulint err;
|
||||
enum db_err err;
|
||||
|
||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
||||
|
||||
|
@ -1152,9 +1152,9 @@ row_ins_set_shared_rec_lock(
|
|||
/*********************************************************************//**
|
||||
Sets a exclusive lock on a record. Used in locking possible duplicate key
|
||||
records
|
||||
@return DB_SUCCESS or error code */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
|
||||
static
|
||||
ulint
|
||||
enum db_err
|
||||
row_ins_set_exclusive_rec_lock(
|
||||
/*===========================*/
|
||||
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
|
||||
|
@ -1165,7 +1165,7 @@ row_ins_set_exclusive_rec_lock(
|
|||
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
ulint err;
|
||||
enum db_err err;
|
||||
|
||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
||||
|
||||
|
@ -1205,7 +1205,6 @@ row_ins_check_foreign_constraint(
|
|||
dict_index_t* check_index;
|
||||
ulint n_fields_cmp;
|
||||
btr_pcur_t pcur;
|
||||
ibool moved;
|
||||
int cmp;
|
||||
ulint err;
|
||||
ulint i;
|
||||
|
@ -1336,13 +1335,13 @@ run_again:
|
|||
|
||||
/* Scan index records and check if there is a matching record */
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
const rec_t* rec = btr_pcur_get_rec(&pcur);
|
||||
const buf_block_t* block = btr_pcur_get_block(&pcur);
|
||||
|
||||
if (page_rec_is_infimum(rec)) {
|
||||
|
||||
goto next_rec;
|
||||
continue;
|
||||
}
|
||||
|
||||
offsets = rec_get_offsets(rec, check_index,
|
||||
|
@ -1353,12 +1352,13 @@ run_again:
|
|||
err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, block,
|
||||
rec, check_index,
|
||||
offsets, thr);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
break;
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
continue;
|
||||
default:
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
goto next_rec;
|
||||
}
|
||||
|
||||
cmp = cmp_dtuple_rec(entry, rec, offsets);
|
||||
|
@ -1369,9 +1369,12 @@ run_again:
|
|||
err = row_ins_set_shared_rec_lock(
|
||||
LOCK_ORDINARY, block,
|
||||
rec, check_index, offsets, thr);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto end_scan;
|
||||
}
|
||||
} else {
|
||||
/* Found a matching record. Lock only
|
||||
|
@ -1382,15 +1385,18 @@ run_again:
|
|||
LOCK_REC_NOT_GAP, block,
|
||||
rec, check_index, offsets, thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
if (check_ref) {
|
||||
err = DB_SUCCESS;
|
||||
|
||||
break;
|
||||
goto end_scan;
|
||||
} else if (foreign->type != 0) {
|
||||
/* There is an ON UPDATE or ON DELETE
|
||||
condition: check them in a separate
|
||||
|
@ -1416,7 +1422,7 @@ run_again:
|
|||
err = DB_FOREIGN_DUPLICATE_KEY;
|
||||
}
|
||||
|
||||
break;
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
/* row_ins_foreign_check_on_constraint
|
||||
|
@ -1429,49 +1435,41 @@ run_again:
|
|||
thr, foreign, rec, entry);
|
||||
|
||||
err = DB_ROW_IS_REFERENCED;
|
||||
break;
|
||||
goto end_scan;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ut_a(cmp < 0);
|
||||
|
||||
if (cmp < 0) {
|
||||
err = row_ins_set_shared_rec_lock(
|
||||
LOCK_GAP, block,
|
||||
rec, check_index, offsets, thr);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
break;
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
if (check_ref) {
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, rec, entry);
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_ref) {
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, rec, entry);
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
break;
|
||||
goto end_scan;
|
||||
}
|
||||
} while (btr_pcur_move_to_next(&pcur, &mtr));
|
||||
|
||||
ut_a(cmp == 0);
|
||||
next_rec:
|
||||
moved = btr_pcur_move_to_next(&pcur, &mtr);
|
||||
|
||||
if (!moved) {
|
||||
if (check_ref) {
|
||||
rec = btr_pcur_get_rec(&pcur);
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, rec, entry);
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (check_ref) {
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, btr_pcur_get_rec(&pcur), entry);
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
end_scan:
|
||||
btr_pcur_close(&pcur);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
@ -1719,9 +1717,13 @@ row_ins_scan_sec_index_for_duplicate(
|
|||
rec, index, offsets, thr);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
err = DB_SUCCESS;
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
if (page_rec_is_supremum(rec)) {
|
||||
|
@ -1738,17 +1740,15 @@ row_ins_scan_sec_index_for_duplicate(
|
|||
|
||||
thr_get_trx(thr)->error_info = index;
|
||||
|
||||
break;
|
||||
goto end_scan;
|
||||
}
|
||||
} else {
|
||||
ut_a(cmp < 0);
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
if (cmp < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ut_a(cmp == 0);
|
||||
} while (btr_pcur_move_to_next(&pcur, &mtr));
|
||||
|
||||
end_scan:
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
@ -1837,7 +1837,11 @@ row_ins_duplicate_error_in_clust(
|
|||
cursor->index, offsets, thr);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
@ -1877,7 +1881,11 @@ row_ins_duplicate_error_in_clust(
|
|||
rec, cursor->index, offsets, thr);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
|
|
@ -1430,27 +1430,26 @@ run_again:
|
|||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
This can only be used when srv_locks_unsafe_for_binlog is TRUE or
|
||||
this session is using a READ COMMITTED isolation level. Before
|
||||
calling this function we must use trx_reset_new_rec_lock_info() and
|
||||
trx_register_new_rec_lock() to store the information which new record locks
|
||||
really were set. This function removes a newly set lock under prebuilt->pcur,
|
||||
and also under prebuilt->clust_pcur. Currently, this is only used and tested
|
||||
in the case of an UPDATE or a DELETE statement, where the row lock is of the
|
||||
LOCK_X type.
|
||||
Thus, this implements a 'mini-rollback' that releases the latest record
|
||||
locks we set.
|
||||
@return error code or DB_SUCCESS */
|
||||
This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
|
||||
session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
|
||||
Before calling this function row_search_for_mysql() must have
|
||||
initialized prebuilt->new_rec_locks to store the information which new
|
||||
record locks really were set. This function removes a newly set
|
||||
clustered index record lock under prebuilt->pcur or
|
||||
prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that
|
||||
releases the latest clustered index record lock we set.
|
||||
@return error code or DB_SUCCESS */
|
||||
UNIV_INTERN
|
||||
int
|
||||
row_unlock_for_mysql(
|
||||
/*=================*/
|
||||
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
|
||||
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL
|
||||
handle */
|
||||
ibool has_latches_on_recs)/*!< TRUE if called so that we have
|
||||
the latches on the records under pcur
|
||||
and clust_pcur, and we do not need to
|
||||
reposition the cursors. */
|
||||
ibool has_latches_on_recs)/*!< in: TRUE if called so
|
||||
that we have the latches on
|
||||
the records under pcur and
|
||||
clust_pcur, and we do not need
|
||||
to reposition the cursors. */
|
||||
{
|
||||
btr_pcur_t* pcur = prebuilt->pcur;
|
||||
btr_pcur_t* clust_pcur = prebuilt->clust_pcur;
|
||||
|
@ -1647,37 +1646,6 @@ row_table_got_default_clust_index(
|
|||
return(dict_index_get_nth_col(clust_index, 0)->mtype == DATA_SYS);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Calculates the key number used inside MySQL for an Innobase index. We have
|
||||
to take into account if we generated a default clustered index for the table
|
||||
@return the key number used inside MySQL */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
row_get_mysql_key_number_for_index(
|
||||
/*===============================*/
|
||||
const dict_index_t* index) /*!< in: index */
|
||||
{
|
||||
const dict_index_t* ind;
|
||||
ulint i;
|
||||
|
||||
ut_a(index);
|
||||
|
||||
i = 0;
|
||||
ind = dict_table_get_first_index(index->table);
|
||||
|
||||
while (index != ind) {
|
||||
ind = dict_table_get_next_index(ind);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (row_table_got_default_clust_index(index->table)) {
|
||||
ut_a(i > 0);
|
||||
i--;
|
||||
}
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Locks the data dictionary in shared mode from modifications, for performing
|
||||
foreign key check, rollback, or other operation invisible to MySQL. */
|
||||
|
|
|
@ -863,8 +863,14 @@ row_sel_get_clust_rec(
|
|||
clust_rec, index, offsets,
|
||||
node->row_lock_mode, lock_type, thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS:
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
/* Declare the variable uninitialized in Valgrind.
|
||||
It should be set to DB_SUCCESS at func_exit. */
|
||||
UNIV_MEM_INVALID(&err, sizeof err);
|
||||
break;
|
||||
default:
|
||||
goto err_exit;
|
||||
}
|
||||
} else {
|
||||
|
@ -934,9 +940,9 @@ err_exit:
|
|||
|
||||
/*********************************************************************//**
|
||||
Sets a lock on a record.
|
||||
@return DB_SUCCESS or error code */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
enum db_err
|
||||
sel_set_rec_lock(
|
||||
/*=============*/
|
||||
const buf_block_t* block, /*!< in: buffer block of rec */
|
||||
|
@ -948,8 +954,8 @@ sel_set_rec_lock(
|
|||
LOC_REC_NOT_GAP */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
trx_t* trx;
|
||||
ulint err;
|
||||
trx_t* trx;
|
||||
enum db_err err;
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
|
@ -1482,11 +1488,15 @@ rec_loop:
|
|||
node->row_lock_mode,
|
||||
lock_type, thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
err = DB_SUCCESS;
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
/* Note that in this case we will store in pcur
|
||||
the PREDECESSOR of the record we are waiting
|
||||
the lock for */
|
||||
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
@ -1538,8 +1548,12 @@ skip_lock:
|
|||
rec, index, offsets,
|
||||
node->row_lock_mode, lock_type, thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
err = DB_SUCCESS;
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
@ -2801,9 +2815,9 @@ row_sel_build_prev_vers_for_mysql(
|
|||
Retrieves the clustered index record corresponding to a record in a
|
||||
non-clustered index. Does the necessary locking. Used in the MySQL
|
||||
interface.
|
||||
@return DB_SUCCESS or error code */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
|
||||
static
|
||||
ulint
|
||||
enum db_err
|
||||
row_sel_get_clust_rec_for_mysql(
|
||||
/*============================*/
|
||||
row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */
|
||||
|
@ -2830,7 +2844,7 @@ row_sel_get_clust_rec_for_mysql(
|
|||
dict_index_t* clust_index;
|
||||
const rec_t* clust_rec;
|
||||
rec_t* old_vers;
|
||||
ulint err;
|
||||
enum db_err err;
|
||||
trx_t* trx;
|
||||
|
||||
*out_rec = NULL;
|
||||
|
@ -2889,6 +2903,7 @@ row_sel_get_clust_rec_for_mysql(
|
|||
|
||||
clust_rec = NULL;
|
||||
|
||||
err = DB_SUCCESS;
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
@ -2904,8 +2919,11 @@ row_sel_get_clust_rec_for_mysql(
|
|||
0, btr_pcur_get_block(prebuilt->clust_pcur),
|
||||
clust_rec, clust_index, *offsets,
|
||||
prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS:
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
break;
|
||||
default:
|
||||
goto err_exit;
|
||||
}
|
||||
} else {
|
||||
|
@ -2965,6 +2983,8 @@ row_sel_get_clust_rec_for_mysql(
|
|||
rec, sec_index, clust_rec, clust_index));
|
||||
#endif
|
||||
}
|
||||
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
func_exit:
|
||||
|
@ -2977,7 +2997,6 @@ func_exit:
|
|||
btr_pcur_store_position(prebuilt->clust_pcur, mtr);
|
||||
}
|
||||
|
||||
err = DB_SUCCESS;
|
||||
err_exit:
|
||||
return(err);
|
||||
}
|
||||
|
@ -3702,8 +3721,12 @@ shortcut_fails_too_big_rec:
|
|||
prebuilt->select_lock_type,
|
||||
LOCK_GAP, thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
err = DB_SUCCESS;
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
@ -3801,8 +3824,12 @@ rec_loop:
|
|||
prebuilt->select_lock_type,
|
||||
LOCK_ORDINARY, thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
err = DB_SUCCESS;
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
@ -3932,8 +3959,11 @@ wrong_offs:
|
|||
prebuilt->select_lock_type, LOCK_GAP,
|
||||
thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
@ -3968,8 +3998,11 @@ wrong_offs:
|
|||
prebuilt->select_lock_type, LOCK_GAP,
|
||||
thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
@ -4039,15 +4072,21 @@ no_gap_lock:
|
|||
|
||||
switch (err) {
|
||||
const rec_t* old_vers;
|
||||
case DB_SUCCESS:
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
|
||||
|| trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED) {
|
||||
/* Note that a record of
|
||||
prebuilt->index was locked. */
|
||||
prebuilt->new_rec_locks = 1;
|
||||
}
|
||||
err = DB_SUCCESS;
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
case DB_LOCK_WAIT:
|
||||
/* Never unlock rows that were part of a conflict. */
|
||||
prebuilt->new_rec_locks = 0;
|
||||
|
||||
if (UNIV_LIKELY(prebuilt->row_read_type
|
||||
!= ROW_READ_TRY_SEMI_CONSISTENT)
|
||||
|| unique_search
|
||||
|
@ -4077,7 +4116,6 @@ no_gap_lock:
|
|||
if (UNIV_LIKELY(trx->wait_lock != NULL)) {
|
||||
lock_cancel_waiting_and_release(
|
||||
trx->wait_lock);
|
||||
prebuilt->new_rec_locks = 0;
|
||||
} else {
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
|
@ -4089,9 +4127,6 @@ no_gap_lock:
|
|||
ULINT_UNDEFINED,
|
||||
&heap);
|
||||
err = DB_SUCCESS;
|
||||
/* Note that a record of
|
||||
prebuilt->index was locked. */
|
||||
prebuilt->new_rec_locks = 1;
|
||||
break;
|
||||
}
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
@ -4228,27 +4263,30 @@ requires_clust_rec:
|
|||
err = row_sel_get_clust_rec_for_mysql(prebuilt, index, rec,
|
||||
thr, &clust_rec,
|
||||
&offsets, &heap, &mtr);
|
||||
if (err != DB_SUCCESS) {
|
||||
switch (err) {
|
||||
case DB_SUCCESS:
|
||||
if (clust_rec == NULL) {
|
||||
/* The record did not exist in the read view */
|
||||
ut_ad(prebuilt->select_lock_type == LOCK_NONE);
|
||||
|
||||
goto next_rec;
|
||||
}
|
||||
break;
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
ut_a(clust_rec != NULL);
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED) {
|
||||
/* Note that the clustered index record
|
||||
was locked. */
|
||||
prebuilt->new_rec_locks = 2;
|
||||
}
|
||||
err = DB_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
|
||||
if (clust_rec == NULL) {
|
||||
/* The record did not exist in the read view */
|
||||
ut_ad(prebuilt->select_lock_type == LOCK_NONE);
|
||||
|
||||
goto next_rec;
|
||||
}
|
||||
|
||||
if ((srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
|
||||
&& prebuilt->select_lock_type != LOCK_NONE) {
|
||||
/* Note that both the secondary index record
|
||||
and the clustered index record were locked. */
|
||||
ut_ad(prebuilt->new_rec_locks == 1);
|
||||
prebuilt->new_rec_locks = 2;
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) {
|
||||
|
||||
/* The record is delete marked: we can skip it */
|
||||
|
|
|
@ -278,7 +278,7 @@ rw_lock_create_func(
|
|||
lock->level = level;
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
lock->magic_n = RW_LOCK_MAGIC_N;
|
||||
ut_d(lock->magic_n = RW_LOCK_MAGIC_N);
|
||||
|
||||
lock->cfile_name = cfile_name;
|
||||
lock->cline = (unsigned int) cline;
|
||||
|
@ -293,10 +293,8 @@ rw_lock_create_func(
|
|||
|
||||
mutex_enter(&rw_lock_list_mutex);
|
||||
|
||||
if (UT_LIST_GET_LEN(rw_lock_list) > 0) {
|
||||
ut_a(UT_LIST_GET_FIRST(rw_lock_list)->magic_n
|
||||
== RW_LOCK_MAGIC_N);
|
||||
}
|
||||
ut_ad(UT_LIST_GET_FIRST(rw_lock_list) == NULL
|
||||
|| UT_LIST_GET_FIRST(rw_lock_list)->magic_n == RW_LOCK_MAGIC_N);
|
||||
|
||||
UT_LIST_ADD_FIRST(list, rw_lock_list, lock);
|
||||
|
||||
|
@ -316,8 +314,6 @@ rw_lock_free_func(
|
|||
ut_ad(rw_lock_validate(lock));
|
||||
ut_a(lock->lock_word == X_LOCK_DECR);
|
||||
|
||||
lock->magic_n = 0;
|
||||
|
||||
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
|
||||
mutex_free(rw_lock_get_mutex(lock));
|
||||
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||
|
@ -327,16 +323,16 @@ rw_lock_free_func(
|
|||
|
||||
os_event_free(lock->wait_ex_event);
|
||||
|
||||
if (UT_LIST_GET_PREV(list, lock)) {
|
||||
ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
|
||||
}
|
||||
if (UT_LIST_GET_NEXT(list, lock)) {
|
||||
ut_a(UT_LIST_GET_NEXT(list, lock)->magic_n == RW_LOCK_MAGIC_N);
|
||||
}
|
||||
ut_ad(UT_LIST_GET_PREV(list, lock) == NULL
|
||||
|| UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
|
||||
ut_ad(UT_LIST_GET_NEXT(list, lock) == NULL
|
||||
|| UT_LIST_GET_NEXT(list, lock)->magic_n == RW_LOCK_MAGIC_N);
|
||||
|
||||
UT_LIST_REMOVE(list, rw_lock_list, lock);
|
||||
|
||||
mutex_exit(&rw_lock_list_mutex);
|
||||
|
||||
ut_d(lock->magic_n = 0);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
|
@ -358,7 +354,7 @@ rw_lock_validate(
|
|||
waiters = rw_lock_get_waiters(lock);
|
||||
lock_word = lock->lock_word;
|
||||
|
||||
ut_a(lock->magic_n == RW_LOCK_MAGIC_N);
|
||||
ut_ad(lock->magic_n == RW_LOCK_MAGIC_N);
|
||||
ut_a(waiters == 0 || waiters == 1);
|
||||
ut_a(lock_word > -X_LOCK_DECR ||(-lock_word) % X_LOCK_DECR == 0);
|
||||
|
||||
|
|
|
@ -637,6 +637,8 @@ ut_strerr(
|
|||
switch (num) {
|
||||
case DB_SUCCESS:
|
||||
return("Success");
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
return("Success, record lock created");
|
||||
case DB_ERROR:
|
||||
return("Generic error");
|
||||
case DB_INTERRUPTED:
|
||||
|
|
|
@ -121,62 +121,43 @@
|
|||
%define distro_specific 0
|
||||
%endif
|
||||
%if %{distro_specific}
|
||||
%if %(test -f /etc/enterprise-release && echo 1 || echo 0)
|
||||
%define elver %(rpm -qf --qf '%%{version}\\n' /etc/enterprise-release | sed -e 's/^\\([0-9]*\\).*/\\1/g')
|
||||
%if "%elver" == "4"
|
||||
%define distro_description Oracle Enterprise Linux 4
|
||||
%define distro_releasetag el4
|
||||
%if %(test -f /etc/redhat-release && echo 1 || echo 0)
|
||||
%define rhelver %(rpm -qf --qf '%%{version}\\n' /etc/redhat-release | sed -e 's/^\\([0-9]*\\).*/\\1/g')
|
||||
%if "%rhelver" == "4"
|
||||
%define distro_description Red Hat Enterprise Linux 4
|
||||
%define distro_releasetag rhel4
|
||||
%define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
|
||||
%define distro_requires chkconfig coreutils grep procps shadow-utils
|
||||
%else
|
||||
%if "%elver" == "5"
|
||||
%define distro_description Oracle Enterprise Linux 5
|
||||
%define distro_releasetag el5
|
||||
%if "%rhelver" == "5"
|
||||
%define distro_description Red Hat Enterprise Linux 5
|
||||
%define distro_releasetag rhel5
|
||||
%define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
|
||||
%define distro_requires chkconfig coreutils grep procps shadow-utils
|
||||
%else
|
||||
%{error:Oracle Enterprise Linux %{elver} is unsupported}
|
||||
%{error:Red Hat Enterprise Linux %{rhelver} is unsupported}
|
||||
%endif
|
||||
%endif
|
||||
%else
|
||||
%if %(test -f /etc/redhat-release && echo 1 || echo 0)
|
||||
%define rhelver %(rpm -qf --qf '%%{version}\\n' /etc/redhat-release | sed -e 's/^\\([0-9]*\\).*/\\1/g')
|
||||
%if "%rhelver" == "4"
|
||||
%define distro_description Red Hat Enterprise Linux 4
|
||||
%define distro_releasetag rhel4
|
||||
%define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
|
||||
%define distro_requires chkconfig coreutils grep procps shadow-utils
|
||||
%if %(test -f /etc/SuSE-release && echo 1 || echo 0)
|
||||
%define susever %(rpm -qf --qf '%%{version}\\n' /etc/SuSE-release)
|
||||
%if "%susever" == "10"
|
||||
%define distro_description SUSE Linux Enterprise Server 10
|
||||
%define distro_releasetag sles10
|
||||
%define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client readline-devel zlib-devel
|
||||
%define distro_requires aaa_base coreutils grep procps pwdutils
|
||||
%else
|
||||
%if "%rhelver" == "5"
|
||||
%define distro_description Red Hat Enterprise Linux 5
|
||||
%define distro_releasetag rhel5
|
||||
%define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
|
||||
%define distro_requires chkconfig coreutils grep procps shadow-utils
|
||||
%if "%susever" == "11"
|
||||
%define distro_description SUSE Linux Enterprise Server 11
|
||||
%define distro_releasetag sles11
|
||||
%define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client procps pwdutils readline-devel zlib-devel
|
||||
%define distro_requires aaa_base coreutils grep procps pwdutils
|
||||
%else
|
||||
%{error:Red Hat Enterprise Linux %{rhelver} is unsupported}
|
||||
%{error:SuSE %{susever} is unsupported}
|
||||
%endif
|
||||
%endif
|
||||
%else
|
||||
%if %(test -f /etc/SuSE-release && echo 1 || echo 0)
|
||||
%define susever %(rpm -qf --qf '%%{version}\\n' /etc/SuSE-release)
|
||||
%if "%susever" == "10"
|
||||
%define distro_description SUSE Linux Enterprise Server 10
|
||||
%define distro_releasetag sles10
|
||||
%define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client readline-devel zlib-devel
|
||||
%define distro_requires aaa_base coreutils grep procps pwdutils
|
||||
%else
|
||||
%if "%susever" == "11"
|
||||
%define distro_description SUSE Linux Enterprise Server 11
|
||||
%define distro_releasetag sles11
|
||||
%define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client procps pwdutils readline-devel zlib-devel
|
||||
%define distro_requires aaa_base coreutils grep procps pwdutils
|
||||
%else
|
||||
%{error:SuSE %{susever} is unsupported}
|
||||
%endif
|
||||
%endif
|
||||
%else
|
||||
%{error:Unsupported distribution}
|
||||
%endif
|
||||
%{error:Unsupported distribution}
|
||||
%endif
|
||||
%endif
|
||||
%else
|
||||
|
|
Loading…
Reference in a new issue