mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
[2/2] MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
Several different test cases were failing under the same reason: the fields in a vcol expression were not marked during marking columns of a key contatining virtual column for read. Fix: make marking columns of a key for read a special case where register_field_in_read_map() is done instead of plain bitmap_set_bit(). Some test cases are only reproducible in 10.4+, but the fix is applicable to 10.2+
This commit is contained in:
@ -629,4 +629,34 @@ DROP TABLE t1;
|
||||
--let $datadir= `SELECT @@datadir`
|
||||
--remove_file $datadir/test/load.data
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
f ENUM('a','b','c'),
|
||||
v ENUM('a','b','c') AS (f),
|
||||
KEY(v,id)
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (f) VALUES ('a'),('b');
|
||||
INSERT IGNORE INTO t1 SELECT * FROM t1;
|
||||
|
||||
# Cleanup
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
f ENUM('a','b','c'),
|
||||
v ENUM('a','b','c') AS (f),
|
||||
KEY(v,id)
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (f) VALUES ('a'),('b');
|
||||
INSERT IGNORE INTO t1 SELECT * FROM t1;
|
||||
|
||||
# Cleanup
|
||||
DROP TABLE t1;
|
||||
|
||||
}
|
||||
|
@ -250,3 +250,20 @@ DELETE FROM v1 ORDER BY b LIMIT 2;
|
||||
# Cleanup
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (d INT, v TINYINT AS (d));
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 (d) VALUES ('2004'),('1985') ;
|
||||
DELETE FROM v1 ORDER BY v LIMIT 4;
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d));
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ;
|
||||
DELETE FROM v1 ORDER BY v LIMIT 4;
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP VIEW v1;
|
||||
|
||||
|
@ -764,6 +764,33 @@ SELECT pk, b FROM t1 INTO OUTFILE 'load.data';
|
||||
LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b);
|
||||
ERROR 22001: Data too long for column 'v' at row 1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
f ENUM('a','b','c'),
|
||||
v ENUM('a','b','c') AS (f),
|
||||
KEY(v,id)
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (f) VALUES ('a'),('b');
|
||||
INSERT IGNORE INTO t1 SELECT * FROM t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
|
||||
Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
f ENUM('a','b','c'),
|
||||
v ENUM('a','b','c') AS (f),
|
||||
KEY(v,id)
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (f) VALUES ('a'),('b');
|
||||
INSERT IGNORE INTO t1 SELECT * FROM t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
|
||||
Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
|
||||
DROP TABLE t1;
|
||||
DROP VIEW IF EXISTS v1,v2;
|
||||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
|
@ -686,6 +686,33 @@ SELECT pk, b FROM t1 INTO OUTFILE 'load.data';
|
||||
LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b);
|
||||
ERROR 22001: Data too long for column 'v' at row 1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
f ENUM('a','b','c'),
|
||||
v ENUM('a','b','c') AS (f),
|
||||
KEY(v,id)
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (f) VALUES ('a'),('b');
|
||||
INSERT IGNORE INTO t1 SELECT * FROM t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
|
||||
Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
f ENUM('a','b','c'),
|
||||
v ENUM('a','b','c') AS (f),
|
||||
KEY(v,id)
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (f) VALUES ('a'),('b');
|
||||
INSERT IGNORE INTO t1 SELECT * FROM t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
|
||||
Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
|
||||
DROP TABLE t1;
|
||||
DROP VIEW IF EXISTS v1,v2;
|
||||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
|
@ -291,6 +291,18 @@ INSERT INTO t1 (a) VALUES ('foo'),('bar');
|
||||
DELETE FROM v1 ORDER BY b LIMIT 2;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (d INT, v TINYINT AS (d));
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 (d) VALUES ('2004'),('1985') ;
|
||||
DELETE FROM v1 ORDER BY v LIMIT 4;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d));
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ;
|
||||
DELETE FROM v1 ORDER BY v LIMIT 4;
|
||||
DROP TABLE t1;
|
||||
DROP VIEW v1;
|
||||
DROP VIEW IF EXISTS v1,v2;
|
||||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
|
@ -291,6 +291,18 @@ INSERT INTO t1 (a) VALUES ('foo'),('bar');
|
||||
DELETE FROM v1 ORDER BY b LIMIT 2;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (d INT, v TINYINT AS (d));
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 (d) VALUES ('2004'),('1985') ;
|
||||
DELETE FROM v1 ORDER BY v LIMIT 4;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d));
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ;
|
||||
DELETE FROM v1 ORDER BY v LIMIT 4;
|
||||
DROP TABLE t1;
|
||||
DROP VIEW v1;
|
||||
DROP VIEW IF EXISTS v1,v2;
|
||||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
|
39
sql/table.cc
39
sql/table.cc
@ -6329,7 +6329,7 @@ void TABLE::prepare_for_position()
|
||||
if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
|
||||
s->primary_key < MAX_KEY)
|
||||
{
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
|
||||
mark_columns_used_by_index_for_read_no_reset(s->primary_key);
|
||||
/* signal change */
|
||||
file->column_bitmaps_signal();
|
||||
}
|
||||
@ -6385,23 +6385,36 @@ void TABLE::restore_column_maps_after_keyread(MY_BITMAP *backup)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
static void mark_index_columns(TABLE *table, uint index,
|
||||
MY_BITMAP *bitmap, bool read)
|
||||
{
|
||||
KEY_PART_INFO *key_part= table->key_info[index].key_part;
|
||||
uint key_parts= table->key_info[index].user_defined_key_parts;
|
||||
for (uint k= 0; k < key_parts; k++)
|
||||
if (read)
|
||||
key_part[k].field->register_field_in_read_map();
|
||||
else
|
||||
bitmap_set_bit(bitmap, key_part[k].fieldnr-1);
|
||||
if (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
|
||||
table->s->primary_key != MAX_KEY && table->s->primary_key != index)
|
||||
mark_index_columns(table, table->s->primary_key, bitmap, read);
|
||||
|
||||
}
|
||||
/*
|
||||
mark columns used by key, but don't reset other fields
|
||||
*/
|
||||
|
||||
void TABLE::mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *bitmap)
|
||||
inline void TABLE::mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *bitmap)
|
||||
{
|
||||
KEY_PART_INFO *key_part= key_info[index].key_part;
|
||||
KEY_PART_INFO *key_part_end= (key_part + key_info[index].user_defined_key_parts);
|
||||
for (;key_part != key_part_end; key_part++)
|
||||
bitmap_set_bit(bitmap, key_part->fieldnr-1);
|
||||
if (file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
|
||||
s->primary_key != MAX_KEY && s->primary_key != index)
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, bitmap);
|
||||
mark_index_columns(this, index, bitmap, false);
|
||||
}
|
||||
|
||||
|
||||
inline void TABLE::mark_columns_used_by_index_for_read_no_reset(uint index)
|
||||
{
|
||||
mark_index_columns(this, index, read_set, true);
|
||||
}
|
||||
|
||||
/*
|
||||
Mark auto-increment fields as used fields in both read and write maps
|
||||
|
||||
@ -6420,7 +6433,7 @@ void TABLE::mark_auto_increment_column()
|
||||
bitmap_set_bit(read_set, found_next_number_field->field_index);
|
||||
bitmap_set_bit(write_set, found_next_number_field->field_index);
|
||||
if (s->next_number_keypart)
|
||||
mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
|
||||
mark_columns_used_by_index_for_read_no_reset(s->next_number_index);
|
||||
file->column_bitmaps_signal();
|
||||
}
|
||||
|
||||
@ -6476,7 +6489,7 @@ void TABLE::mark_columns_needed_for_delete()
|
||||
file->use_hidden_primary_key();
|
||||
else
|
||||
{
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
|
||||
mark_columns_used_by_index_for_read_no_reset(s->primary_key);
|
||||
need_signal= true;
|
||||
}
|
||||
}
|
||||
@ -6566,7 +6579,7 @@ void TABLE::mark_columns_needed_for_update()
|
||||
file->use_hidden_primary_key();
|
||||
else
|
||||
{
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
|
||||
mark_columns_used_by_index_for_read_no_reset(s->primary_key);
|
||||
need_signal= true;
|
||||
}
|
||||
}
|
||||
@ -6729,7 +6742,7 @@ void TABLE::mark_columns_per_binlog_row_image()
|
||||
We don't need to mark the primary key in the rpl_write_set as the
|
||||
binary log will include all columns read anyway.
|
||||
*/
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
|
||||
mark_columns_used_by_index_for_read_no_reset(s->primary_key);
|
||||
/* Only write columns that have changed */
|
||||
rpl_write_set= write_set;
|
||||
break;
|
||||
|
@ -1423,6 +1423,7 @@ public:
|
||||
{ return prepare_for_keyread(index, &tmp_set); }
|
||||
void mark_columns_used_by_index(uint index, MY_BITMAP *map);
|
||||
void mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *map);
|
||||
void mark_columns_used_by_index_for_read_no_reset(uint index);
|
||||
void restore_column_maps_after_keyread(MY_BITMAP *backup);
|
||||
void mark_auto_increment_column(void);
|
||||
void mark_columns_needed_for_update(void);
|
||||
|
Reference in New Issue
Block a user