diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-07-23 14:16:34 +0300 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2021-08-02 10:31:22 +0200 |
commit | b549af69137023ce0f93d312a10d61e467dca07f (patch) | |
tree | 2ecbb1e763f351306c69d29968c057997163c4b5 | |
parent | 8b6c8a6ce96c2c8ce6fde16049fcd60eb1547aed (diff) | |
download | mariadb-git-b549af69137023ce0f93d312a10d61e467dca07f.tar.gz |
MDEV-26220 Server crashes with indexed by prefix virtual columnmariadb-10.2.40
Server crashes in Field::register_field_in_read_map upon select from
partitioned table with indexed by prefix virtual column.
After several read-mark fixes a problem has surfaced:
Since KEY (c(10),a) uses only a prefix of c, a new field is created,
duplicated from table->field[3], with a new length. However,
vcol_inco->expr is not copied.
Therefore, (*key_info)->key_part[i].field->vcol_info->expr was left NULL
in ha_partition::index_init().
Solution: copy vcol_info from table field when it's set up.
-rw-r--r-- | mysql-test/suite/gcol/inc/gcol_partition.inc | 12 | ||||
-rw-r--r-- | mysql-test/suite/gcol/r/gcol_partition_innodb.result | 11 | ||||
-rw-r--r-- | mysql-test/suite/gcol/r/gcol_partition_myisam.result | 11 | ||||
-rw-r--r-- | sql/table.cc | 15 |
4 files changed, 49 insertions, 0 deletions
diff --git a/mysql-test/suite/gcol/inc/gcol_partition.inc b/mysql-test/suite/gcol/inc/gcol_partition.inc index 4e4af4f0023..50a743c0153 100644 --- a/mysql-test/suite/gcol/inc/gcol_partition.inc +++ b/mysql-test/suite/gcol/inc/gcol_partition.inc @@ -169,3 +169,15 @@ CREATE TABLE t1 ( INSERT INTO t1 () VALUES (),(); UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; DROP TABLE t1; + +--echo # +--echo # MDEV-26220 Server crashes with indexed by prefix virtual column +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), + KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; + +# Cleanup +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/gcol_partition_innodb.result b/mysql-test/suite/gcol/r/gcol_partition_innodb.result index d3f211c9b9a..e61c0a26417 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_partition_innodb.result @@ -104,6 +104,17 @@ INSERT INTO t1 () VALUES (),(); UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; DROP TABLE t1; # +# MDEV-26220 Server crashes with indexed by prefix virtual column +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), +KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; +a +11 +10 +DROP TABLE t1; +# # MDEV-16980 Wrongly set tablename len while opening the # table for purge thread # diff --git a/mysql-test/suite/gcol/r/gcol_partition_myisam.result b/mysql-test/suite/gcol/r/gcol_partition_myisam.result index 75e216f903b..e54b0ad83c6 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_partition_myisam.result @@ -101,6 +101,17 @@ KEY (b,d) INSERT INTO t1 () VALUES (),(); UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; DROP TABLE t1; +# +# MDEV-26220 Server crashes with indexed by prefix virtual column +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), +KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; +a +11 +10 +DROP TABLE t1; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/sql/table.cc b/sql/table.cc index b7cf1274400..281b8f82abc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3284,6 +3284,21 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, /* Update to use trigger fields */ switch_defaults_to_nullable_trigger_fields(outparam); + + for (uint k= 0; k < share->keys; k++) + { + KEY &key_info= outparam->key_info[k]; + uint parts = (share->use_ext_keys ? key_info.ext_key_parts : + key_info.user_defined_key_parts); + for (uint p= 0; p < parts; p++) + { + KEY_PART_INFO &kp= key_info.key_part[p]; + if (kp.field != outparam->field[kp.fieldnr - 1]) + { + kp.field->vcol_info = outparam->field[kp.fieldnr - 1]->vcol_info; + } + } + } } #ifdef WITH_PARTITION_STORAGE_ENGINE |