mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-24583 SELECT aborts after failed REPLACE into table with vcol
table->move_fields wasn't undone in case of error. 1. move_fields is unconditionally undone even when error is occurred 2. cherry-pick an assertion in `ptr_in_record`, which is already in 10.5
This commit is contained in:
@ -669,3 +669,77 @@ PRIMARY KEY (number)
|
|||||||
REPLACE t2(number) VALUES('1');
|
REPLACE t2(number) VALUES('1');
|
||||||
REPLACE t2(number) VALUES('1');
|
REPLACE t2(number) VALUES('1');
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
# MDEV-24583 SELECT aborts after failed REPLACE into table with vcol
|
||||||
|
CREATE TABLE t1 (pk INT, a VARCHAR(3), v VARCHAR(3) AS (CONCAT('x-',a)),
|
||||||
|
PRIMARY KEY(pk)) ENGINE=MyISAM;
|
||||||
|
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 (pk, a) VALUES (1,'foo');
|
||||||
|
SET sql_mode=CONCAT(@@sql_mode,',STRICT_ALL_TABLES');
|
||||||
|
REPLACE INTO t1 (pk,a) VALUES (1,'qux');
|
||||||
|
SELECT * FROM v1;
|
||||||
|
pk a v
|
||||||
|
1 foo x-f
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
pk INT,
|
||||||
|
a VARCHAR(1),
|
||||||
|
v VARCHAR(1) AS (CONCAT('virt-',a)) VIRTUAL,
|
||||||
|
PRIMARY KEY (pk)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 (pk,a) VALUES
|
||||||
|
(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f');
|
||||||
|
REPLACE INTO t1 (pk) VALUES (1);
|
||||||
|
ERROR 22001: Data too long for column 'v' at row 1
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
pk a v
|
||||||
|
1 a v
|
||||||
|
2 b v
|
||||||
|
3 c v
|
||||||
|
4 d v
|
||||||
|
5 e v
|
||||||
|
6 f v
|
||||||
|
SET SQL_MODE=DEFAULT;
|
||||||
|
DROP TABLE t1;
|
||||||
|
# (duplicate) MDEV-24656
|
||||||
|
# [FATAL] InnoDB: Data field type 0, len 0, ASAN heap-buffer-overflow
|
||||||
|
# upon LOAD DATA with virtual columns
|
||||||
|
CREATE TABLE t1 (id INT PRIMARY KEY, a VARCHAR(2333),
|
||||||
|
va VARCHAR(171) AS (a)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 (id,a) VALUES (1,REPEAT('x',200));
|
||||||
|
SELECT id, va INTO OUTFILE 'load_t1' FROM t1;
|
||||||
|
LOAD DATA INFILE 'load_t1' REPLACE INTO TABLE t1 (id,va);
|
||||||
|
ERROR 22001: Data too long for column 'va' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id a va
|
||||||
|
1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
LOAD DATA INFILE 'load_t1' IGNORE INTO TABLE t1 (id,va);
|
||||||
|
Warnings:
|
||||||
|
Warning 1062 Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (id BIGINT PRIMARY KEY, a VARCHAR(2333),
|
||||||
|
va VARCHAR(171) AS (a)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 (id,a) VALUES (1,REPEAT('x',200));
|
||||||
|
SELECT id, va INTO OUTFILE 'load_t1' FROM t1;
|
||||||
|
LOAD DATA INFILE 'load_t1' REPLACE INTO TABLE t1 (id,va);
|
||||||
|
ERROR 22001: Data too long for column 'va' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id a va
|
||||||
|
1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
LOAD DATA INFILE 'load_t1' IGNORE INTO TABLE t1 (id,va);
|
||||||
|
Warnings:
|
||||||
|
Warning 1062 Duplicate entry '1' for key 'PRIMARY'
|
||||||
|
DROP TABLE t1;
|
||||||
|
# (duplicate) MDEV-24665
|
||||||
|
# ASAN errors, assertion failures, corrupt values after failed
|
||||||
|
# LOAD DATA into table with virtual/stored column
|
||||||
|
CREATE TABLE t1 (id INT PRIMARY KEY,
|
||||||
|
ts TIMESTAMP DEFAULT '1971-01-01 00:00:00',
|
||||||
|
c VARBINARY(8) DEFAULT '', vc VARCHAR(3) AS (c) STORED);
|
||||||
|
INSERT IGNORE INTO t1 (id,c) VALUES (1,'foobar');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'vc' at row 1
|
||||||
|
SELECT id, ts, vc INTO OUTFILE 'load_t1' FROM t1;
|
||||||
|
LOAD DATA INFILE 'load_t1' REPLACE INTO TABLE t1 (id, ts, vc);
|
||||||
|
INSERT IGNORE INTO t1 (id) VALUES (2);
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -634,3 +634,87 @@ REPLACE t2(number) VALUES('1');
|
|||||||
REPLACE t2(number) VALUES('1');
|
REPLACE t2(number) VALUES('1');
|
||||||
|
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
|
||||||
|
--echo # MDEV-24583 SELECT aborts after failed REPLACE into table with vcol
|
||||||
|
|
||||||
|
CREATE TABLE t1 (pk INT, a VARCHAR(3), v VARCHAR(3) AS (CONCAT('x-',a)),
|
||||||
|
PRIMARY KEY(pk)) ENGINE=MyISAM;
|
||||||
|
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 (pk, a) VALUES (1,'foo');
|
||||||
|
SET sql_mode=CONCAT(@@sql_mode,',STRICT_ALL_TABLES');
|
||||||
|
--error 0,ER_DATA_TOO_LONG
|
||||||
|
REPLACE INTO t1 (pk,a) VALUES (1,'qux');
|
||||||
|
SELECT * FROM v1;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
pk INT,
|
||||||
|
a VARCHAR(1),
|
||||||
|
v VARCHAR(1) AS (CONCAT('virt-',a)) VIRTUAL,
|
||||||
|
PRIMARY KEY (pk)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
INSERT INTO t1 (pk,a) VALUES
|
||||||
|
(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f');
|
||||||
|
|
||||||
|
--error ER_DATA_TOO_LONG
|
||||||
|
REPLACE INTO t1 (pk) VALUES (1);
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
|
||||||
|
SET SQL_MODE=DEFAULT;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo # (duplicate) MDEV-24656
|
||||||
|
--echo # [FATAL] InnoDB: Data field type 0, len 0, ASAN heap-buffer-overflow
|
||||||
|
--echo # upon LOAD DATA with virtual columns
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id INT PRIMARY KEY, a VARCHAR(2333),
|
||||||
|
va VARCHAR(171) AS (a)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 (id,a) VALUES (1,REPEAT('x',200));
|
||||||
|
SELECT id, va INTO OUTFILE 'load_t1' FROM t1;
|
||||||
|
--error ER_DATA_TOO_LONG
|
||||||
|
LOAD DATA INFILE 'load_t1' REPLACE INTO TABLE t1 (id,va);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
LOAD DATA INFILE 'load_t1' IGNORE INTO TABLE t1 (id,va);
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
--let $datadir= `select @@datadir`
|
||||||
|
--remove_file $datadir/test/load_t1
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id BIGINT PRIMARY KEY, a VARCHAR(2333),
|
||||||
|
va VARCHAR(171) AS (a)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 (id,a) VALUES (1,REPEAT('x',200));
|
||||||
|
SELECT id, va INTO OUTFILE 'load_t1' FROM t1;
|
||||||
|
--error ER_DATA_TOO_LONG
|
||||||
|
LOAD DATA INFILE 'load_t1' REPLACE INTO TABLE t1 (id,va);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
LOAD DATA INFILE 'load_t1' IGNORE INTO TABLE t1 (id,va);
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
DROP TABLE t1;
|
||||||
|
--let $datadir= `select @@datadir`
|
||||||
|
--remove_file $datadir/test/load_t1
|
||||||
|
|
||||||
|
|
||||||
|
--echo # (duplicate) MDEV-24665
|
||||||
|
--echo # ASAN errors, assertion failures, corrupt values after failed
|
||||||
|
--echo # LOAD DATA into table with virtual/stored column
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id INT PRIMARY KEY,
|
||||||
|
ts TIMESTAMP DEFAULT '1971-01-01 00:00:00',
|
||||||
|
c VARBINARY(8) DEFAULT '', vc VARCHAR(3) AS (c) STORED);
|
||||||
|
INSERT IGNORE INTO t1 (id,c) VALUES (1,'foobar');
|
||||||
|
SELECT id, ts, vc INTO OUTFILE 'load_t1' FROM t1;
|
||||||
|
--error 0,ER_DATA_TOO_LONG
|
||||||
|
LOAD DATA INFILE 'load_t1' REPLACE INTO TABLE t1 (id, ts, vc);
|
||||||
|
INSERT IGNORE INTO t1 (id) VALUES (2);
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
DROP TABLE t1;
|
||||||
|
--let $datadir= `select @@datadir`
|
||||||
|
--remove_file $datadir/test/load_t1
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,4 +67,17 @@ connection master;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
set @@binlog_row_image=default;
|
set @@binlog_row_image=default;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
SET SQL_MODE=default;
|
||||||
|
CREATE TABLE t1 (pk INT, a VARCHAR(3), b VARCHAR(1) AS (a) VIRTUAL, PRIMARY KEY (pk));
|
||||||
|
INSERT IGNORE INTO t1 (pk, a) VALUES (1,'foo'),(2,'bar');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 2
|
||||||
|
REPLACE INTO t1 (pk) VALUES (2);
|
||||||
|
ERROR 22001: Data too long for column 'b' at row 1
|
||||||
|
UPDATE IGNORE t1 SET a = NULL;
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 2
|
||||||
|
DROP TABLE t1;
|
||||||
include/rpl_end.inc
|
include/rpl_end.inc
|
||||||
|
@ -51,5 +51,19 @@ DROP VIEW v1;
|
|||||||
set @@binlog_row_image=default;
|
set @@binlog_row_image=default;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
SET SQL_MODE=default;
|
||||||
|
|
||||||
|
# MDEV-24782
|
||||||
|
# ASAN use-after-poison in Field::pack_int / THD::binlog_update_row
|
||||||
|
|
||||||
|
CREATE TABLE t1 (pk INT, a VARCHAR(3), b VARCHAR(1) AS (a) VIRTUAL, PRIMARY KEY (pk));
|
||||||
|
INSERT IGNORE INTO t1 (pk, a) VALUES (1,'foo'),(2,'bar');
|
||||||
|
--error ER_DATA_TOO_LONG
|
||||||
|
REPLACE INTO t1 (pk) VALUES (2);
|
||||||
|
UPDATE IGNORE t1 SET a = NULL;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--source include/rpl_end.inc
|
--source include/rpl_end.inc
|
||||||
|
@ -972,8 +972,9 @@ public:
|
|||||||
virtual void reset_fields() {}
|
virtual void reset_fields() {}
|
||||||
const uchar *ptr_in_record(const uchar *record) const
|
const uchar *ptr_in_record(const uchar *record) const
|
||||||
{
|
{
|
||||||
my_ptrdiff_t l_offset= (my_ptrdiff_t) (record - table->record[0]);
|
my_ptrdiff_t l_offset= (my_ptrdiff_t) (ptr - table->record[0]);
|
||||||
return ptr + l_offset;
|
DBUG_ASSERT(l_offset >= 0 && table->s->rec_buff_length - l_offset > 0);
|
||||||
|
return record + l_offset;
|
||||||
}
|
}
|
||||||
virtual int set_default();
|
virtual int set_default();
|
||||||
|
|
||||||
|
@ -1753,9 +1753,10 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
in handler methods for the just read row in record[1].
|
in handler methods for the just read row in record[1].
|
||||||
*/
|
*/
|
||||||
table->move_fields(table->field, table->record[1], table->record[0]);
|
table->move_fields(table->field, table->record[1], table->record[0]);
|
||||||
if (table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE))
|
int verr = table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE);
|
||||||
goto err;
|
|
||||||
table->move_fields(table->field, table->record[0], table->record[1]);
|
table->move_fields(table->field, table->record[0], table->record[1]);
|
||||||
|
if (verr)
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
if (info->handle_duplicates == DUP_UPDATE)
|
if (info->handle_duplicates == DUP_UPDATE)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user