Merge 10.2 into 10.3

This commit is contained in:
Marko Mäkelä 2019-04-27 20:41:31 +03:00
commit 4d59f45260
39 changed files with 547 additions and 78 deletions

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2000, 2014, Oracle and/or its affiliates. Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Copyright (c) 2009, 2014, MariaDB Copyright (c) 2009, 2019, MariaDB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -233,9 +233,8 @@ bool print_annotate_event(PRINT_EVENT_INFO *print_event_info)
bool error= 0; bool error= 0;
if (annotate_event) if (annotate_event)
{ {
error= annotate_event->print(result_file, print_event_info); annotate_event->print(result_file, print_event_info);
delete annotate_event; // the event should not be printed more than once free_annotate_event();
annotate_event= 0;
} }
return error; return error;
} }
@ -1553,8 +1552,6 @@ end:
} }
} }
if (remote_opt)
ev->temp_buf= 0;
if (destroy_evt) /* destroy it later if not set (ignored table map) */ if (destroy_evt) /* destroy it later if not set (ignored table map) */
delete ev; delete ev;
} }

View File

@ -558,9 +558,9 @@ datafile_read(datafile_cur_t *cursor)
return(XB_FIL_CUR_EOF); return(XB_FIL_CUR_EOF);
} }
if (!os_file_read(IORequestRead, if (os_file_read(IORequestRead,
cursor->file, cursor->buf, cursor->buf_offset, cursor->file, cursor->buf, cursor->buf_offset,
to_read)) { to_read) != DB_SUCCESS) {
return(XB_FIL_CUR_ERROR); return(XB_FIL_CUR_ERROR);
} }

View File

@ -196,7 +196,7 @@ log_online_read_bitmap_page(
ut_a(bitmap_file->offset % MODIFIED_PAGE_BLOCK_SIZE == 0); ut_a(bitmap_file->offset % MODIFIED_PAGE_BLOCK_SIZE == 0);
success = os_file_read(IORequestRead, success = os_file_read(IORequestRead,
bitmap_file->file, page, bitmap_file->offset, bitmap_file->file, page, bitmap_file->offset,
MODIFIED_PAGE_BLOCK_SIZE); MODIFIED_PAGE_BLOCK_SIZE) == DB_SUCCESS;
if (UNIV_UNLIKELY(!success)) { if (UNIV_UNLIKELY(!success)) {

View File

@ -252,7 +252,7 @@ xb_fil_cur_open(
if (!node->space->crypt_data if (!node->space->crypt_data
&& os_file_read(IORequestRead, && os_file_read(IORequestRead,
node->handle, cursor->buf, 0, node->handle, cursor->buf, 0,
page_size.physical())) { page_size.physical()) == DB_SUCCESS) {
mutex_enter(&fil_system.mutex); mutex_enter(&fil_system.mutex);
if (!node->space->crypt_data) { if (!node->space->crypt_data) {
node->space->crypt_data node->space->crypt_data
@ -441,8 +441,8 @@ read_retry:
cursor->buf_offset = offset; cursor->buf_offset = offset;
cursor->buf_page_no = (ulint)(offset / page_size); cursor->buf_page_no = (ulint)(offset / page_size);
if (!os_file_read(IORequestRead, cursor->file, cursor->buf, offset, if (os_file_read(IORequestRead, cursor->file, cursor->buf, offset,
(ulint) to_read)) { (ulint) to_read) != DB_SUCCESS) {
ret = XB_FIL_CUR_ERROR; ret = XB_FIL_CUR_ERROR;
goto func_exit; goto func_exit;
} }

View File

@ -3297,10 +3297,10 @@ static dberr_t xb_assign_undo_space_start()
page = static_cast<byte*>(ut_align(buf, srv_page_size)); page = static_cast<byte*>(ut_align(buf, srv_page_size));
retry: retry:
if (!os_file_read(IORequestRead, file, page, if (os_file_read(IORequestRead, file, page,
TRX_SYS_PAGE_NO << srv_page_size_shift, TRX_SYS_PAGE_NO << srv_page_size_shift,
srv_page_size)) { srv_page_size) != DB_SUCCESS) {
msg("Reading TRX_SYS page failed.\n"); msg("Reading TRX_SYS page failed.");
error = DB_ERROR; error = DB_ERROR;
goto func_exit; goto func_exit;
} }
@ -4604,7 +4604,7 @@ xb_space_create_file(
free(buf); free(buf);
if (!ret) { if (ret != DB_SUCCESS) {
msg("mariabackup: could not write the first page to %s", msg("mariabackup: could not write the first page to %s",
path); path);
os_file_close(*file); os_file_close(*file);
@ -4900,7 +4900,7 @@ xtrabackup_apply_delta(
<< page_size_shift); << page_size_shift);
success = os_file_read(IORequestRead, src_file, success = os_file_read(IORequestRead, src_file,
incremental_buffer, offset, page_size); incremental_buffer, offset, page_size);
if (!success) { if (success != DB_SUCCESS) {
goto error; goto error;
} }
@ -4933,7 +4933,7 @@ xtrabackup_apply_delta(
success = os_file_read(IORequestRead, src_file, success = os_file_read(IORequestRead, src_file,
incremental_buffer, incremental_buffer,
offset, page_in_buffer * page_size); offset, page_in_buffer * page_size);
if (!success) { if (success != DB_SUCCESS) {
goto error; goto error;
} }
@ -4981,7 +4981,7 @@ xtrabackup_apply_delta(
success = os_file_write(IORequestWrite, success = os_file_write(IORequestWrite,
dst_path, dst_file, buf, off, page_size); dst_path, dst_file, buf, off, page_size);
if (!success) { if (success != DB_SUCCESS) {
goto error; goto error;
} }
} }

View File

@ -151,3 +151,43 @@ create table t2 like t1;
insert into t2 select * from t1; insert into t2 select * from t1;
delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
drop table t1,t2; drop table t1,t2;
#
# MDEV-16240: Assertion `0' failed in
# row_sel_convert_mysql_key_to_innobase
#
SET @save_sql_mode=@@sql_mode;
set sql_mode='';
CREATE TABLE `t3` (
`f1` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE current_timestamp(),
`f2` datetime DEFAULT '2000-01-01 00:00:00' ON UPDATE current_timestamp(),
`f3` TIMESTAMP NULL DEFAULT '2000-01-01 00:00:00',
`pk` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`f4` datetime DEFAULT current_timestamp(),
PRIMARY KEY (`pk`),
UNIQUE KEY `f2k` (`f2`),
KEY `f4k` (`f4`)
) ENGINE=InnoDB;
INSERT INTO `t3` VALUES ('2018-05-18 15:08:07','2018-05-18 17:08:07','0000-00-00 00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00'),('0000-00-00 00:00:00','0000-00-00 00:00:00','1999-12-31 23:00:00','2002-07-03 23:04:40','0000-00-00 00:00:00');
CREATE VIEW `v1` AS
SELECT `t3`.`pk` AS `pk`,
`t3`.`f3` AS `f3`,
`t3`.`f4` AS `f4`,
`t3`.`f2` AS `f2`,
`t3`.`f1` AS `f1`
FROM `t3`;
CREATE TABLE `t4` (
`f1` datetime DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`f3` timestamp NULL DEFAULT NULL,
`f2` timestamp NULL DEFAULT '1999-12-31 23:00:00' ON UPDATE current_timestamp(),
`pk` int(11) NOT NULL,
`f4` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`pk`)
) ENGINE=InnoDB;
INSERT INTO `t4` VALUES ('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,1,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,3,'2018-05-18 15:08:06'),('0000-00-00 00:00:00','0000-00-00 00:00:00',NULL,1976,'0000-00-00 00:00:00'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2000,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2001,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2002,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2003,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2004,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2005,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2018,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2019,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2024,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','1999-12-31 23:00:00',2025,'2018-05-18 15:08:06'),('0000-00-00 00:00:00',NULL,'2018-05-18 15:08:06',2026,'2018-05-18 15:08:06'),('2018-05-18 17:08:07','0000-00-00 00:00:00','0000-00-00 00:00:00',2027,'0000-00-00 00:00:00');
UPDATE `v1` t1, `t4` t2
SET t1.`f2` = 6452736 WHERE t1.`f4` = 6272000;
ERROR 23000: Duplicate entry '0000-00-00 00:00:00' for key 'f2k'
DROP VIEW v1;
DROP TABLE t3,t4;
SET @@sql_mode=@save_sql_mode;
# End of 10.2 tests

View File

@ -173,3 +173,52 @@ delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
drop table t1,t2; drop table t1,t2;
--echo #
--echo # MDEV-16240: Assertion `0' failed in
--echo # row_sel_convert_mysql_key_to_innobase
--echo #
SET @save_sql_mode=@@sql_mode;
set sql_mode='';
CREATE TABLE `t3` (
`f1` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE current_timestamp(),
`f2` datetime DEFAULT '2000-01-01 00:00:00' ON UPDATE current_timestamp(),
`f3` TIMESTAMP NULL DEFAULT '2000-01-01 00:00:00',
`pk` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`f4` datetime DEFAULT current_timestamp(),
PRIMARY KEY (`pk`),
UNIQUE KEY `f2k` (`f2`),
KEY `f4k` (`f4`)
) ENGINE=InnoDB;
INSERT INTO `t3` VALUES ('2018-05-18 15:08:07','2018-05-18 17:08:07','0000-00-00 00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00'),('0000-00-00 00:00:00','0000-00-00 00:00:00','1999-12-31 23:00:00','2002-07-03 23:04:40','0000-00-00 00:00:00');
CREATE VIEW `v1` AS
SELECT `t3`.`pk` AS `pk`,
`t3`.`f3` AS `f3`,
`t3`.`f4` AS `f4`,
`t3`.`f2` AS `f2`,
`t3`.`f1` AS `f1`
FROM `t3`;
CREATE TABLE `t4` (
`f1` datetime DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`f3` timestamp NULL DEFAULT NULL,
`f2` timestamp NULL DEFAULT '1999-12-31 23:00:00' ON UPDATE current_timestamp(),
`pk` int(11) NOT NULL,
`f4` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`pk`)
) ENGINE=InnoDB;
INSERT INTO `t4` VALUES ('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,1,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,3,'2018-05-18 15:08:06'),('0000-00-00 00:00:00','0000-00-00 00:00:00',NULL,1976,'0000-00-00 00:00:00'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2000,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2001,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2002,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2003,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2004,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2005,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2018,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2019,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2024,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','1999-12-31 23:00:00',2025,'2018-05-18 15:08:06'),('0000-00-00 00:00:00',NULL,'2018-05-18 15:08:06',2026,'2018-05-18 15:08:06'),('2018-05-18 17:08:07','0000-00-00 00:00:00','0000-00-00 00:00:00',2027,'0000-00-00 00:00:00');
--error ER_DUP_ENTRY
UPDATE `v1` t1, `t4` t2
SET t1.`f2` = 6452736 WHERE t1.`f4` = 6272000;
DROP VIEW v1;
DROP TABLE t3,t4;
SET @@sql_mode=@save_sql_mode;
--echo # End of 10.2 tests

Binary file not shown.

View File

@ -684,6 +684,24 @@ world.city 563256876
DROP TABLE test.test; DROP TABLE test.test;
DROP TABLE world.city; DROP TABLE world.city;
DROP DATABASE world; DROP DATABASE world;
# < CASE 7 >
# Test Case for MDEV-17260
#
RESET MASTER;
CREATE TABLE t1 ( f INT PRIMARY KEY ) ENGINE=innodb;
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6);
# 6- Rows must be present
SELECT COUNT(*) FROM t1;
COUNT(*)
6
FLUSH LOGS;
DELETE FROM t1;
FLUSH LOGS;
# 0- Rows must be present
include/assert.inc [Table t1 should have 0 rows.]
# 6- Rows must be present upon restoring from flashback
include/assert.inc [Table t1 should have six rows.]
DROP TABLE t1;
SET binlog_format=statement; SET binlog_format=statement;
Warnings: Warnings:
Warning 1105 MariaDB Galera and flashback do not support binlog format: STATEMENT Warning 1105 MariaDB Galera and flashback do not support binlog format: STATEMENT

View File

@ -335,8 +335,36 @@ DROP TABLE test.test;
DROP TABLE world.city; DROP TABLE world.city;
DROP DATABASE world; DROP DATABASE world;
## Clear --echo # < CASE 7 >
--echo # Test Case for MDEV-17260
--echo #
RESET MASTER;
CREATE TABLE t1 ( f INT PRIMARY KEY ) ENGINE=innodb;
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6);
--echo # 6- Rows must be present
SELECT COUNT(*) FROM t1;
FLUSH LOGS;
DELETE FROM t1;
FLUSH LOGS;
--echo # 0- Rows must be present
--let $assert_cond= COUNT(*) = 0 FROM t1
--let $assert_text= Table t1 should have 0 rows.
--source include/assert.inc
--exec $MYSQL_BINLOG -vv -B --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002> $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_7.sql
--exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_7.sql;"
--echo # 6- Rows must be present upon restoring from flashback
--let $assert_cond= COUNT(*) = 6 FROM t1
--let $assert_text= Table t1 should have six rows.
--source include/assert.inc
DROP TABLE t1;
## Clear
SET binlog_format=statement; SET binlog_format=statement;
--error ER_FLASHBACK_NOT_SUPPORTED --error ER_FLASHBACK_NOT_SUPPORTED
SET GLOBAL binlog_format=statement; SET GLOBAL binlog_format=statement;

View File

@ -94,3 +94,33 @@ NULL
29 29
DROP TABLE t; DROP TABLE t;
SET DEBUG_SYNC = 'RESET'; SET DEBUG_SYNC = 'RESET';
#
# Bug#28825718 - ASSERTION FAILURE: TRX0REC.CC:NNN:N_IDX > 0 WHILE DOING REPLACE/INSERT
#
CREATE TABLE t1(a INT PRIMARY KEY, b INT, c INT GENERATED ALWAYS AS(b+1) VIRTUAL) ENGINE=InnoDB;
INSERT INTO t1(a, b) VALUES(1, 1);
connect con1,localhost,root,,;
SET DEBUG_SYNC = 'row_log_apply_after SIGNAL s1 WAIT_FOR s2';
SET lock_wait_timeout = 1;
ALTER TABLE t1 ADD UNIQUE INDEX(c, b);
connection default;
SET DEBUG_SYNC = 'now WAIT_FOR s1';
SET DEBUG_SYNC = 'row_ins_sec_index_enter SIGNAL s2 WAIT_FOR s3';
INSERT INTO t1(a, b) VALUES(2, 2);
connection con1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
SET DEBUG_SYNC = 'now SIGNAL s3';
disconnect con1;
connection default;
SET DEBUG_SYNC = 'RESET';
ALTER TABLE t1 ADD KEY(b);
INSERT INTO t1(a, b) VALUES(3, 3);
SELECT * FROM t1;
a b c
1 1 2
2 2 3
3 3 4
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;

View File

@ -60,7 +60,6 @@ SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR
--send ALTER TABLE t FORCE --send ALTER TABLE t FORCE
connection con1; connection con1;
SET DEBUG_SYNC = 'now WAIT_FOR start_create'; SET DEBUG_SYNC = 'now WAIT_FOR start_create';
start transaction; start transaction;
update t set a=1 where a = 0; update t set a=1 where a = 0;
@ -280,4 +279,37 @@ disconnect con1;
} }
SET DEBUG_SYNC = 'RESET'; SET DEBUG_SYNC = 'RESET';
--echo #
--echo # Bug#28825718 - ASSERTION FAILURE: TRX0REC.CC:NNN:N_IDX > 0 WHILE DOING REPLACE/INSERT
--echo #
CREATE TABLE t1(a INT PRIMARY KEY, b INT, c INT GENERATED ALWAYS AS(b+1) VIRTUAL) ENGINE=InnoDB;
INSERT INTO t1(a, b) VALUES(1, 1);
connect (con1,localhost,root,,);
SET DEBUG_SYNC = 'row_log_apply_after SIGNAL s1 WAIT_FOR s2';
SET lock_wait_timeout = 1;
--send ALTER TABLE t1 ADD UNIQUE INDEX(c, b)
connection default;
SET DEBUG_SYNC = 'now WAIT_FOR s1';
SET DEBUG_SYNC = 'row_ins_sec_index_enter SIGNAL s2 WAIT_FOR s3';
--send INSERT INTO t1(a, b) VALUES(2, 2)
connection con1;
--error ER_LOCK_WAIT_TIMEOUT
reap;
SET DEBUG_SYNC = 'now SIGNAL s3';
disconnect con1;
connection default;
reap;
SET DEBUG_SYNC = 'RESET';
ALTER TABLE t1 ADD KEY(b);
INSERT INTO t1(a, b) VALUES(3, 3);
SELECT * FROM t1;
CHECK TABLE t1;
DROP TABLE t1;
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc

View File

@ -383,3 +383,28 @@ select * from t1;
id hexid id hexid
100 64 100 64
drop table t1; drop table t1;
#
# MDEV-15881 Assertion `is_valid_value_slow()' failed in Datetime::Datetime or corrupt data after ALTER with indexed persistent column
#
CREATE TABLE t1 (i INT, d1 DATE, d2 DATE NOT NULL, t TIMESTAMP, KEY(t)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,'2023-03-16','2023-03-15','2012-12-12 12:12:12');
ALTER TABLE t1 MODIFY t FLOAT AS (i) PERSISTENT;
SELECT i, d1, d2 FROM t1 INTO OUTFILE 'load_t1';
DELETE FROM t1;
LOAD DATA INFILE 'load_t1' INTO TABLE t1 (i,d1,d2);
SELECT * FROM t1 WHERE d2 < d1;
i d1 d2 t
1 2023-03-16 2023-03-15 1
DROP TABLE t1;
CREATE TABLE t1 (
i INT DEFAULT NULL,
d1 DATE DEFAULT NULL,
d2 DATE NOT NULL,
t FLOAT GENERATED ALWAYS AS (i) STORED,
KEY (t)
) ENGINE=MyISAM;
LOAD DATA INFILE 'load_t1' INTO TABLE t1 (i,d1,d2);
SELECT * FROM t1 WHERE d2 < d1;
i d1 d2 t
1 2023-03-16 2023-03-15 1
DROP TABLE t1;

View File

@ -409,3 +409,19 @@ Warning 1918 Encountered illegal value '\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7' when c
# #
# End of 10.1 tests # End of 10.1 tests
# #
#
# Start of 10.2 tests
#
#
# MDEV-16518 MYSQL57_GENERATED_FIELD: The code in TABLE_SHARE::init_from_binary_frm_image() is not safe
#
SHOW TABLES;
Tables_in_test
t1
SHOW CREATE TABLE t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
ALTER TABLE t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
#
# End of 10.2 tests
#

View File

@ -272,3 +272,31 @@ create table t1 ( id int primary key,
insert into t1 (id) select 100; insert into t1 (id) select 100;
select * from t1; select * from t1;
drop table t1; drop table t1;
--echo #
--echo # MDEV-15881 Assertion `is_valid_value_slow()' failed in Datetime::Datetime or corrupt data after ALTER with indexed persistent column
--echo #
CREATE TABLE t1 (i INT, d1 DATE, d2 DATE NOT NULL, t TIMESTAMP, KEY(t)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,'2023-03-16','2023-03-15','2012-12-12 12:12:12');
ALTER TABLE t1 MODIFY t FLOAT AS (i) PERSISTENT;
SELECT i, d1, d2 FROM t1 INTO OUTFILE 'load_t1';
DELETE FROM t1;
LOAD DATA INFILE 'load_t1' INTO TABLE t1 (i,d1,d2);
SELECT * FROM t1 WHERE d2 < d1;
DROP TABLE t1;
CREATE TABLE t1 (
i INT DEFAULT NULL,
d1 DATE DEFAULT NULL,
d2 DATE NOT NULL,
t FLOAT GENERATED ALWAYS AS (i) STORED,
KEY (t)
) ENGINE=MyISAM;
LOAD DATA INFILE 'load_t1' INTO TABLE t1 (i,d1,d2);
SELECT * FROM t1 WHERE d2 < d1;
DROP TABLE t1;
# Cleanup
--let $datadir= `SELECT @@datadir`
--remove_file $datadir/test/load_t1

View File

@ -371,3 +371,26 @@ SELECT COLUMN_GET(@aaa, 'price' AS DOUBLE) aaa;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --echo #
--echo #
--echo # Start of 10.2 tests
--echo #
--echo #
--echo # MDEV-16518 MYSQL57_GENERATED_FIELD: The code in TABLE_SHARE::init_from_binary_frm_image() is not safe
--echo #
--copy_file std_data/frm/mdev16518.frm $MYSQLD_DATADIR/test/t1.frm
SHOW TABLES;
--replace_result $MYSQLD_DATADIR ./
--error ER_NOT_FORM_FILE
SHOW CREATE TABLE t1;
--replace_result $MYSQLD_DATADIR ./
--error ER_NOT_FORM_FILE
ALTER TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.frm
--echo #
--echo # End of 10.2 tests
--echo #

View File

@ -2841,8 +2841,7 @@ int handler::ha_rnd_pos(uchar *buf, uchar *pos)
DBUG_ENTER("handler::ha_rnd_pos"); DBUG_ENTER("handler::ha_rnd_pos");
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
m_lock_type != F_UNLCK); m_lock_type != F_UNLCK);
/* TODO: Find out how to solve ha_rnd_pos when finding duplicate update. */ DBUG_ASSERT(inited == RND);
/* DBUG_ASSERT(inited == RND); */
TABLE_IO_WAIT(tracker, m_psi, PSI_TABLE_FETCH_ROW, MAX_KEY, 0, TABLE_IO_WAIT(tracker, m_psi, PSI_TABLE_FETCH_ROW, MAX_KEY, 0,
{ result= rnd_pos(buf, pos); }) { result= rnd_pos(buf, pos); })
@ -3521,6 +3520,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong nr; ulonglong nr;
int error; int error;
MY_BITMAP *old_read_set; MY_BITMAP *old_read_set;
bool rnd_inited= (inited == RND);
if (rnd_inited && ha_rnd_end())
return;
old_read_set= table->prepare_for_keyread(table->s->next_number_index); old_read_set= table->prepare_for_keyread(table->s->next_number_index);
@ -3530,6 +3533,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
DBUG_ASSERT(0); DBUG_ASSERT(0);
(void) extra(HA_EXTRA_NO_KEYREAD); (void) extra(HA_EXTRA_NO_KEYREAD);
*first_value= ULONGLONG_MAX; *first_value= ULONGLONG_MAX;
if (rnd_inited && ha_rnd_init_with_error(0))
{
//TODO: it would be nice to return here an error
}
return; return;
} }
@ -3576,6 +3583,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
ha_index_end(); ha_index_end();
table->restore_column_maps_after_keyread(old_read_set); table->restore_column_maps_after_keyread(old_read_set);
*first_value= nr; *first_value= nr;
if (rnd_inited && ha_rnd_init_with_error(0))
{
//TODO: it would be nice to return here an error
}
return; return;
} }

View File

@ -5844,12 +5844,16 @@ Ordered_key::cmp_keys_by_row_data_and_rownum(Ordered_key *key,
} }
void Ordered_key::sort_keys() bool Ordered_key::sort_keys()
{ {
if (tbl->file->ha_rnd_init_with_error(0))
return TRUE;
my_qsort2(key_buff, (size_t) key_buff_elements, sizeof(rownum_t), my_qsort2(key_buff, (size_t) key_buff_elements, sizeof(rownum_t),
(qsort2_cmp) &cmp_keys_by_row_data_and_rownum, (void*) this); (qsort2_cmp) &cmp_keys_by_row_data_and_rownum, (void*) this);
/* Invalidate the current row position. */ /* Invalidate the current row position. */
cur_key_idx= HA_POS_ERROR; cur_key_idx= HA_POS_ERROR;
tbl->file->ha_rnd_end();
return FALSE;
} }
@ -6297,7 +6301,8 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
/* Sort the keys in each of the indexes. */ /* Sort the keys in each of the indexes. */
for (uint i= 0; i < merge_keys_count; i++) for (uint i= 0; i < merge_keys_count; i++)
merge_keys[i]->sort_keys(); if (merge_keys[i]->sort_keys())
return TRUE;
if (init_queue(&pq, merge_keys_count, 0, FALSE, if (init_queue(&pq, merge_keys_count, 0, FALSE,
subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL, subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL,

View File

@ -1283,7 +1283,7 @@ public:
++cur_key_idx; ++cur_key_idx;
} }
void sort_keys(); bool sort_keys();
double null_selectivity(); double null_selectivity();
/* /*

View File

@ -13477,6 +13477,12 @@ Rows_log_event::write_row(rpl_group_info *rgi,
if (table->file->ha_table_flags() & HA_DUPLICATE_POS) if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
{ {
DBUG_PRINT("info",("Locating offending record using rnd_pos()")); DBUG_PRINT("info",("Locating offending record using rnd_pos()"));
if ((error= table->file->ha_rnd_init_with_error(0)))
{
DBUG_RETURN(error);
}
error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref); error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
if (unlikely(error)) if (unlikely(error))
{ {
@ -13484,6 +13490,7 @@ Rows_log_event::write_row(rpl_group_info *rgi,
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
table->file->ha_rnd_end();
} }
else else
{ {

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2010, 2018, MariaDB Corporation Copyright (c) 2010, 2019, MariaDB Corporation
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -881,7 +881,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
{ {
if (duplic != DUP_ERROR || ignore) if (duplic != DUP_ERROR || ignore)
{
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (table->file->ha_table_flags() & HA_DUPLICATE_POS &&
table->file->ha_rnd_init_with_error(0))
goto abort;
}
/** /**
This is a simple check for the case when the table has a trigger This is a simple check for the case when the table has a trigger
that reads from it, or when the statement invokes a stored function that reads from it, or when the statement invokes a stored function
@ -944,7 +949,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
{ {
DBUG_PRINT("info", ("iteration %llu", iteration)); DBUG_PRINT("info", ("iteration %llu", iteration));
if (iteration && bulk_parameters_set(thd)) if (iteration && bulk_parameters_set(thd))
goto abort; {
error= 1;
goto values_loop_end;
}
while ((values= its++)) while ((values= its++))
{ {
@ -1101,7 +1109,11 @@ values_loop_end:
error=1; error=1;
} }
if (duplic != DUP_ERROR || ignore) if (duplic != DUP_ERROR || ignore)
{
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
table->file->ha_rnd_end();
}
transactional_table= table->file->has_transactions(); transactional_table= table->file->has_transactions();
@ -1744,6 +1756,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
goto err; goto err;
if (table->file->ha_table_flags() & HA_DUPLICATE_POS) if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
{ {
DBUG_ASSERT(table->file->inited == handler::RND);
if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref)) if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref))
goto err; goto err;
} }
@ -3271,6 +3284,9 @@ bool Delayed_insert::handle_inserts(void)
max_rows= ULONG_MAX; // Do as much as possible max_rows= ULONG_MAX; // Do as much as possible
} }
if (table->file->ha_rnd_init_with_error(0))
goto err;
/* /*
We can't use row caching when using the binary log because if We can't use row caching when using the binary log because if
we get a crash, then binary log will contain rows that are not yet we get a crash, then binary log will contain rows that are not yet
@ -3445,6 +3461,8 @@ bool Delayed_insert::handle_inserts(void)
} }
} }
table->file->ha_rnd_end();
if (WSREP((&thd))) if (WSREP((&thd)))
thd_proc_info(&thd, "Insert done"); thd_proc_info(&thd, "Insert done");
else else
@ -3742,7 +3760,12 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.ignore || info.handle_duplicates != DUP_ERROR) if (info.ignore || info.handle_duplicates != DUP_ERROR)
{
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (table->file->ha_table_flags() & HA_DUPLICATE_POS &&
table->file->ha_rnd_init_with_error(0))
DBUG_RETURN(1);
}
if (info.handle_duplicates == DUP_REPLACE && if (info.handle_duplicates == DUP_REPLACE &&
(!table->triggers || !table->triggers->has_delete_triggers())) (!table->triggers || !table->triggers->has_delete_triggers()))
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
@ -3919,6 +3942,9 @@ bool select_insert::prepare_eof()
if (likely(!error) && unlikely(thd->is_error())) if (likely(!error) && unlikely(thd->is_error()))
error= thd->get_stmt_da()->sql_errno(); error= thd->get_stmt_da()->sql_errno();
if (info.ignore || info.handle_duplicates != DUP_ERROR)
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
table->file->ha_rnd_end();
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
@ -4030,6 +4056,11 @@ void select_insert::abort_result_set() {
if (thd->locked_tables_mode <= LTM_LOCK_TABLES) if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
table->file->ha_end_bulk_insert(); table->file->ha_end_bulk_insert();
if (table->file->inited)
table->file->ha_rnd_end();
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
/* /*
If at least one row has been inserted/modified and will stay in If at least one row has been inserted/modified and will stay in
the table (the table doesn't have transactions) we must write to the table (the table doesn't have transactions) we must write to
@ -4450,7 +4481,12 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
restore_record(table,s->default_values); // Get empty record restore_record(table,s->default_values); // Get empty record
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.ignore || info.handle_duplicates != DUP_ERROR) if (info.ignore || info.handle_duplicates != DUP_ERROR)
{
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (table->file->ha_table_flags() & HA_DUPLICATE_POS &&
table->file->ha_rnd_init_with_error(0))
DBUG_RETURN(1);
}
if (info.handle_duplicates == DUP_REPLACE && if (info.handle_duplicates == DUP_REPLACE &&
(!table->triggers || !table->triggers->has_delete_triggers())) (!table->triggers || !table->triggers->has_delete_triggers()))
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
@ -4631,9 +4667,6 @@ bool select_create::send_eof()
*/ */
exit_done= 1; // Avoid double calls exit_done= 1; // Avoid double calls
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
send_ok_packet(); send_ok_packet();
if (m_plock) if (m_plock)
@ -4709,13 +4742,6 @@ void select_create::abort_result_set()
thd->locked_tables_list.unlock_locked_table(thd, thd->locked_tables_list.unlock_locked_table(thd,
create_info->mdl_ticket); create_info->mdl_ticket);
} }
if (m_plock)
{
mysql_unlock_tables(thd, *m_plock);
*m_plock= NULL;
m_plock= NULL;
}
if (table) if (table)
{ {
bool tmp_table= table->s->tmp_table; bool tmp_table= table->s->tmp_table;
@ -4726,9 +4752,21 @@ void select_create::abort_result_set()
thd->restore_tmp_table_share(saved_tmp_table_share); thd->restore_tmp_table_share(saved_tmp_table_share);
} }
if (table->file->inited &&
(info.ignore || info.handle_duplicates != DUP_ERROR) &&
(table->file->ha_table_flags() & HA_DUPLICATE_POS))
table->file->ha_rnd_end();
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
table->auto_increment_field_not_null= FALSE; table->auto_increment_field_not_null= FALSE;
if (m_plock)
{
mysql_unlock_tables(thd, *m_plock);
*m_plock= NULL;
m_plock= NULL;
}
drop_open_table(thd, table, &create_table->db, &create_table->table_name); drop_open_table(thd, table, &create_table->db, &create_table->table_name);
table=0; // Safety table=0; // Safety
if (thd->log_current_statement && mysql_bin_log.is_open()) if (thd->log_current_statement && mysql_bin_log.is_open())

View File

@ -663,6 +663,10 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list,
thd->abort_on_warning= !ignore && thd->is_strict_mode(); thd->abort_on_warning= !ignore && thd->is_strict_mode();
if ((table_list->table->file->ha_table_flags() & HA_DUPLICATE_POS) &&
(error= table_list->table->file->ha_rnd_init_with_error(0)))
goto err;
thd_progress_init(thd, 2); thd_progress_init(thd, 2);
if (table_list->table->validate_default_values_of_unset_fields(thd)) if (table_list->table->validate_default_values_of_unset_fields(thd))
{ {
@ -682,6 +686,9 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list,
set_fields, set_values, read_info, set_fields, set_values, read_info,
*ex->enclosed, skip_lines, ignore); *ex->enclosed, skip_lines, ignore);
if (table_list->table->file->ha_table_flags() & HA_DUPLICATE_POS)
table_list->table->file->ha_rnd_end();
thd_proc_info(thd, "End bulk insert"); thd_proc_info(thd, "End bulk insert");
if (likely(!error)) if (likely(!error))
thd_progress_next_stage(thd); thd_progress_next_stage(thd);

View File

@ -615,7 +615,8 @@ void init_update_queries(void)
CF_CAN_GENERATE_ROW_EVENTS | CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE | CF_OPTIMIZER_TRACE |
CF_CAN_BE_EXPLAINED | CF_CAN_BE_EXPLAINED |
CF_INSERTS_DATA | CF_SP_BULK_SAFE; CF_INSERTS_DATA | CF_SP_BULK_SAFE |
CF_SP_BULK_OPTIMIZED;
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS | CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE | CF_OPTIMIZER_TRACE |

View File

@ -20967,6 +20967,15 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
} }
/* Prepare table for random positioning */
bool rnd_inited= (table->file->inited == handler::RND);
if (!rnd_inited &&
((error= table->file->ha_index_end()) ||
(error= table->file->ha_rnd_init(0))))
{
table->file->print_error(error, MYF(0));
DBUG_RETURN(NESTED_LOOP_ERROR);
}
if (unlikely(table->file->ha_rnd_pos(table->record[1],table->file->dup_ref))) if (unlikely(table->file->ha_rnd_pos(table->record[1],table->file->dup_ref)))
{ {
table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->file->print_error(error,MYF(0)); /* purecov: inspected */
@ -20980,6 +20989,13 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
} }
if (!rnd_inited &&
((error= table->file->ha_rnd_end()) ||
(error= table->file->ha_index_init(0, 0))))
{
table->file->print_error(error, MYF(0));
DBUG_RETURN(NESTED_LOOP_ERROR);
}
} }
if (unlikely(join->thd->check_killed())) if (unlikely(join->thd->check_killed()))
{ {

View File

@ -256,6 +256,14 @@ static void prepare_record_for_error_message(int error, TABLE *table)
bitmap_union(table->read_set, &unique_map); bitmap_union(table->read_set, &unique_map);
/* Tell the engine about the new set. */ /* Tell the engine about the new set. */
table->file->column_bitmaps_signal(); table->file->column_bitmaps_signal();
if ((error= table->file->ha_index_or_rnd_end()) ||
(error= table->file->ha_rnd_init(0)))
{
table->file->print_error(error, MYF(0));
DBUG_VOID_RETURN;
}
/* Read record that is identified by table->file->ref. */ /* Read record that is identified by table->file->ref. */
(void) table->file->ha_rnd_pos(table->record[1], table->file->ref); (void) table->file->ha_rnd_pos(table->record[1], table->file->ref);
/* Copy the newly read columns into the new record. */ /* Copy the newly read columns into the new record. */

View File

@ -1895,7 +1895,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
goto err; goto err;
vcol_info= new (&share->mem_root) Virtual_column_info(); vcol_info= new (&share->mem_root) Virtual_column_info();
vcol_info_length= uint2korr(vcol_screen_pos + 1); vcol_info_length= uint2korr(vcol_screen_pos + 1);
DBUG_ASSERT(vcol_info_length); if (!vcol_info_length) // Expect non-empty expression
goto err;
vcol_info->stored_in_db= vcol_screen_pos[3]; vcol_info->stored_in_db= vcol_screen_pos[3];
vcol_info->utf8= 0; vcol_info->utf8= 0;
vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;; vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;;

View File

@ -1045,6 +1045,7 @@ BtrBulk::finish(dberr_t err)
ut_ad(!sync_check_iterate(dict_sync_check())); ut_ad(!sync_check_iterate(dict_sync_check()));
ut_ad(err != DB_SUCCESS || btr_validate_index(m_index, NULL, false)); ut_ad(err == DB_SUCCESS
|| btr_validate_index(m_index, NULL, false) == DB_SUCCESS);
return(err); return(err);
} }

View File

@ -508,7 +508,7 @@ bool fil_node_t::read_page0(bool first)
/* Align the memory for file i/o if we might have O_DIRECT set */ /* Align the memory for file i/o if we might have O_DIRECT set */
byte* page = static_cast<byte*>(ut_align(buf2, psize)); byte* page = static_cast<byte*>(ut_align(buf2, psize));
IORequest request(IORequest::READ); IORequest request(IORequest::READ);
if (!os_file_read(request, handle, page, 0, psize)) { if (os_file_read(request, handle, page, 0, psize) != DB_SUCCESS) {
ib::error() << "Unable to read first page of file " << name; ib::error() << "Unable to read first page of file " << name;
ut_free(buf2); ut_free(buf2);
return false; return false;

View File

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc. Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
@ -10814,7 +10814,7 @@ innodb_base_col_setup_for_stored(
for (uint i= 0; i < field->table->s->fields; ++i) { for (uint i= 0; i < field->table->s->fields; ++i) {
const Field* base_field = field->table->field[i]; const Field* base_field = field->table->field[i];
if (!base_field->vcol_info if (base_field->stored_in_db()
&& bitmap_is_set(&field->table->tmp_set, i)) { && bitmap_is_set(&field->table->tmp_set, i)) {
ulint z; ulint z;
for (z = 0; z < table->n_cols; z++) { for (z = 0; z < table->n_cols; z++) {

View File

@ -1734,14 +1734,10 @@ innobase_col_check_fk(
{ {
dict_s_col_list::const_iterator it; dict_s_col_list::const_iterator it;
for (it = s_cols->begin(); for (it = s_cols->begin(); it != s_cols->end(); ++it) {
it != s_cols->end(); ++it) { for (ulint j = it->num_base; j--; ) {
dict_s_col_t s_col = *it; if (!strcmp(col_name, dict_table_get_col_name(
table, it->base_col[j]->ind))) {
for (ulint j = 0; j < s_col.num_base; j++) {
if (strcmp(col_name, dict_table_get_col_name(
table,
s_col.base_col[j]->ind)) == 0) {
return(true); return(true);
} }
} }

View File

@ -30,12 +30,13 @@ Created 5/24/1996 Heikki Tuuri
/* Do not include univ.i because univ.i includes this. */ /* Do not include univ.i because univ.i includes this. */
enum dberr_t { enum dberr_t {
DB_SUCCESS,
DB_SUCCESS_LOCKED_REC = 9, /*!< like DB_SUCCESS, but a new DB_SUCCESS_LOCKED_REC = 9, /*!< like DB_SUCCESS, but a new
explicit record lock was created */ explicit record lock was created */
DB_SUCCESS = 10,
/* The following are error codes */ /* The following are error codes */
DB_ERROR, DB_ERROR = 11,
DB_INTERRUPTED, DB_INTERRUPTED,
DB_OUT_OF_MEMORY, DB_OUT_OF_MEMORY,
DB_OUT_OF_FILE_SPACE, DB_OUT_OF_FILE_SPACE,

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation. Copyright (c) 2015, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -193,9 +193,7 @@ enum roll_node_state {
struct roll_node_t{ struct roll_node_t{
que_common_t common; /*!< node type: QUE_NODE_ROLLBACK */ que_common_t common; /*!< node type: QUE_NODE_ROLLBACK */
enum roll_node_state state; /*!< node execution state */ enum roll_node_state state; /*!< node execution state */
bool partial;/*!< TRUE if we want a partial const trx_savept_t* savept; /*!< savepoint to which to
rollback */
trx_savept_t savept; /*!< savepoint to which to
roll back, in the case of a roll back, in the case of a
partial rollback */ partial rollback */
que_thr_t* undo_thr;/*!< undo query graph */ que_thr_t* undo_thr;/*!< undo query graph */

View File

@ -1958,10 +1958,24 @@ LinuxAIOHandler::collect()
will be done in the calling function. */ will be done in the calling function. */
m_array->acquire(); m_array->acquire();
slot->ret = events[i].res2; /* events[i].res2 should always be ZERO */
ut_ad(events[i].res2 == 0);
slot->io_already_done = true; slot->io_already_done = true;
slot->n_bytes = events[i].res;
/*Even though events[i].res is an unsigned number
in libaio, it is used to return a negative value
(negated errno value) to indicate error and a positive
value to indicate number of bytes read or written. */
if (events[i].res > slot->len) {
/* failure */
slot->n_bytes = 0;
slot->ret = events[i].res;
} else {
/* success */
slot->n_bytes = events[i].res;
slot->ret = 0;
}
m_array->release(); m_array->release();
} }

View File

@ -1230,7 +1230,5 @@ que_eval_sql(
mutex_exit(&dict_sys->mutex); mutex_exit(&dict_sys->mutex);
} }
ut_a(trx->error_state != 0);
DBUG_RETURN(trx->error_state); DBUG_RETURN(trx->error_state);
} }

View File

@ -445,11 +445,12 @@ row_log_online_op(
} }
log->tail.blocks++; log->tail.blocks++;
if (!os_file_write( if (os_file_write(
request, request,
"(modification log)", "(modification log)",
log->fd, log->fd,
buf, byte_offset, srv_sort_buf_size)) { buf, byte_offset, srv_sort_buf_size)
!= DB_SUCCESS) {
write_failed: write_failed:
/* We set the flag directly instead of invoking /* We set the flag directly instead of invoking
dict_set_corrupted_index_cache_only(index) here, dict_set_corrupted_index_cache_only(index) here,
@ -583,11 +584,12 @@ row_log_table_close_func(
} }
log->tail.blocks++; log->tail.blocks++;
if (!os_file_write( if (os_file_write(
request, request,
"(modification log)", "(modification log)",
log->fd, log->fd,
buf, byte_offset, srv_sort_buf_size)) { buf, byte_offset, srv_sort_buf_size)
!= DB_SUCCESS) {
write_failed: write_failed:
log->error = DB_ONLINE_LOG_TOO_BIG; log->error = DB_ONLINE_LOG_TOO_BIG;
} }
@ -2862,9 +2864,9 @@ all_done:
IORequest request(IORequest::READ); IORequest request(IORequest::READ);
byte* buf = index->online_log->head.block; byte* buf = index->online_log->head.block;
if (!os_file_read_no_error_handling( if (os_file_read_no_error_handling(
request, index->online_log->fd, request, index->online_log->fd,
buf, ofs, srv_sort_buf_size, 0)) { buf, ofs, srv_sort_buf_size, 0) != DB_SUCCESS) {
ib::error() ib::error()
<< "Unable to read temporary file" << "Unable to read temporary file"
" for table " << index->table->name; " for table " << index->table->name;
@ -3765,9 +3767,9 @@ all_done:
byte* buf = index->online_log->head.block; byte* buf = index->online_log->head.block;
if (!os_file_read_no_error_handling( if (os_file_read_no_error_handling(
request, index->online_log->fd, request, index->online_log->fd,
buf, ofs, srv_sort_buf_size, 0)) { buf, ofs, srv_sort_buf_size, 0) != DB_SUCCESS) {
ib::error() ib::error()
<< "Unable to read temporary file" << "Unable to read temporary file"
" for index " << index->name; " for index " << index->name;

View File

@ -1094,7 +1094,7 @@ row_merge_read(
DBUG_EXECUTE_IF("row_merge_read_failure", DBUG_RETURN(FALSE);); DBUG_EXECUTE_IF("row_merge_read_failure", DBUG_RETURN(FALSE););
IORequest request(IORequest::READ); IORequest request(IORequest::READ);
const bool success = os_file_read_no_error_handling( const bool success = DB_SUCCESS == os_file_read_no_error_handling(
request, fd, buf, ofs, srv_sort_buf_size, 0); request, fd, buf, ofs, srv_sort_buf_size, 0);
/* If encryption is enabled decrypt buffer */ /* If encryption is enabled decrypt buffer */
@ -1156,7 +1156,7 @@ row_merge_write(
} }
IORequest request(IORequest::WRITE); IORequest request(IORequest::WRITE);
const bool success = os_file_write( const bool success = DB_SUCCESS == os_file_write(
request, "(merge)", fd, out_buf, ofs, buf_len); request, "(merge)", fd, out_buf, ofs, buf_len);
#ifdef POSIX_FADV_DONTNEED #ifdef POSIX_FADV_DONTNEED

View File

@ -2179,6 +2179,16 @@ srv_master_do_active_tasks(void)
MONITOR_SRV_DICT_LRU_MICROSECOND, counter_time); MONITOR_SRV_DICT_LRU_MICROSECOND, counter_time);
} }
/* The periodic log_checkpoint() call here makes it harder to
reproduce bugs in crash recovery or mariabackup --prepare, or
in code that writes the redo log records. Omitting the call
here should not affect correctness, because log_free_check()
should still be invoking checkpoints when needed. In a
production server, those calls could cause "furious flushing"
and stall the server. Normally we want to perform checkpoints
early and often to avoid those situations. */
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", return;);
if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
return; return;
} }
@ -2258,6 +2268,16 @@ srv_master_do_idle_tasks(void)
MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_LOG_FLUSH_MICROSECOND, counter_time); MONITOR_SRV_LOG_FLUSH_MICROSECOND, counter_time);
/* The periodic log_checkpoint() call here makes it harder to
reproduce bugs in crash recovery or mariabackup --prepare, or
in code that writes the redo log records. Omitting the call
here should not affect correctness, because log_free_check()
should still be invoking checkpoints when needed. In a
production server, those calls could cause "furious flushing"
and stall the server. Normally we want to perform checkpoints
early and often to avoid those situations. */
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", return;);
if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
return; return;
} }

View File

@ -116,8 +116,7 @@ trx_rollback_to_savepoint_low(
roll_node = roll_node_create(heap); roll_node = roll_node_create(heap);
if (savept != NULL) { if (savept != NULL) {
roll_node->partial = TRUE; roll_node->savept = savept;
roll_node->savept = *savept;
check_trx_state(trx); check_trx_state(trx);
} else { } else {
assert_trx_nonlocking_or_in_list(trx); assert_trx_nonlocking_or_in_list(trx);
@ -1084,7 +1083,7 @@ que_thr_t*
trx_rollback_start( trx_rollback_start(
/*===============*/ /*===============*/
trx_t* trx, /*!< in: transaction */ trx_t* trx, /*!< in: transaction */
ib_id_t roll_limit) /*!< in: rollback to undo no (for undo_no_t roll_limit) /*!< in: rollback to undo no (for
partial undo), 0 if we are rolling back partial undo), 0 if we are rolling back
the entire transaction */ the entire transaction */
{ {
@ -1162,7 +1161,7 @@ trx_rollback_step(
ut_a(node->undo_thr == NULL); ut_a(node->undo_thr == NULL);
roll_limit = node->partial ? node->savept.least_undo_no : 0; roll_limit = node->savept ? node->savept->least_undo_no : 0;
trx_commit_or_rollback_prepare(trx); trx_commit_or_rollback_prepare(trx);

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2002, 2014, Oracle and/or its affiliates. /* Copyright (c) 2002, 2014, Oracle and/or its affiliates.
Copyright (c) 2008, 2017, MariaDB Copyright (c) 2008, 2019, MariaDB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -20368,6 +20368,65 @@ static void test_bulk_delete()
myquery(rc); myquery(rc);
} }
static void test_bulk_replace()
{
int rc;
MYSQL_STMT *stmt;
MYSQL_BIND bind[2];
MYSQL_ROW row;
int i,
id[]= {1, 2, 3, 4},
val[]= {1, 1, 1, 1},
count= sizeof(id)/sizeof(id[0]);
MYSQL_RES *result;
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key, active int)");
myquery(rc);
rc= mysql_query(mysql, "insert into t1 values (1, 0), (2, 0), (3, 0)");
myquery(rc);
verify_affected_rows(3);
stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, "replace into t1 (id, active) values (?, ?)", -1);
check_execute(stmt, rc);
memset(bind, 0, sizeof(bind));
bind[0].buffer_type = MYSQL_TYPE_LONG;
bind[0].buffer = (void *)id;
bind[0].buffer_length = 0;
bind[1].buffer_type = MYSQL_TYPE_LONG;
bind[1].buffer = (void *)val;
bind[1].buffer_length = 0;
mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
rc= mysql_stmt_bind_param(stmt, bind);
check_execute(stmt, rc);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "SELECT active FROM t1");
myquery(rc);
result= mysql_store_result(mysql);
mytest(result);
i= 0;
while ((row= mysql_fetch_row(result)))
{
i++;
DIE_IF(atoi(row[0]) != 1);
}
DIE_IF(i != 4);
mysql_free_result(result);
rc= mysql_query(mysql, "DROP TABLE t1");
myquery(rc);
}
#endif #endif
static void print_metadata(MYSQL_RES *rs_metadata, int num_fields) static void print_metadata(MYSQL_RES *rs_metadata, int num_fields)
@ -20995,6 +21054,7 @@ static struct my_tests_st my_tests[]= {
{ "test_proxy_header", test_proxy_header}, { "test_proxy_header", test_proxy_header},
{ "test_bulk_autoinc", test_bulk_autoinc}, { "test_bulk_autoinc", test_bulk_autoinc},
{ "test_bulk_delete", test_bulk_delete }, { "test_bulk_delete", test_bulk_delete },
{ "test_bulk_replace", test_bulk_replace },
#endif #endif
{ "test_explain_meta", test_explain_meta }, { "test_explain_meta", test_explain_meta },
{ 0, 0 } { 0, 0 }