summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2021-07-23 14:16:34 +0300
committerOleksandr Byelkin <sanja@mariadb.com>2021-08-02 10:31:22 +0200
commitb549af69137023ce0f93d312a10d61e467dca07f (patch)
tree2ecbb1e763f351306c69d29968c057997163c4b5
parent8b6c8a6ce96c2c8ce6fde16049fcd60eb1547aed (diff)
downloadmariadb-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.inc12
-rw-r--r--mysql-test/suite/gcol/r/gcol_partition_innodb.result11
-rw-r--r--mysql-test/suite/gcol/r/gcol_partition_myisam.result11
-rw-r--r--sql/table.cc15
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