diff options
author | Monty <monty@mariadb.org> | 2017-12-12 15:04:29 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2017-12-12 15:10:53 +0200 |
commit | d4a4185451061d84ed6d3ead9ce77faac04c7151 (patch) | |
tree | 45ca10cc2f74efbb3d2b03db9d542ea98d949c6f | |
parent | 0edd395e8d791a3d78a1e882dc598843e521403e (diff) | |
download | mariadb-git-d4a4185451061d84ed6d3ead9ce77faac04c7151.tar.gz |
MDEV Assertion `partition_id == m_extra_cache_part_id' failed in ha_partition::late_extra_no_cache
The problem was that multi_range_read_info_const() called
multi_range_key_create_key() which changed m_part_spec.start_part,
while there was an activ table scan ongoing.
Fixed by copying and restoring m_part_spec around
multi_range_key_create_calls()
-rw-r--r-- | mysql-test/suite/parts/r/cache.result | 15 | ||||
-rw-r--r-- | mysql-test/suite/parts/t/cache.test | 22 | ||||
-rw-r--r-- | sql/ha_partition.cc | 11 |
3 files changed, 47 insertions, 1 deletions
diff --git a/mysql-test/suite/parts/r/cache.result b/mysql-test/suite/parts/r/cache.result new file mode 100644 index 00000000000..fb40526f379 --- /dev/null +++ b/mysql-test/suite/parts/r/cache.result @@ -0,0 +1,15 @@ +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, f4 INT, KEY (f4), +KEY (f1,f4,f3,f2) +) PARTITION BY RANGE(f1) ( PARTITION p VALUES LESS THAN MAXVALUE ); +INSERT IGNORE INTO t1 VALUES +(140,0,0,7),(143,92,NULL,0),(0,0,NULL,154),(NULL,255,117,197),(0,0,NULL,0),(60,0,0,1); +CREATE TABLE t2 (f INT); +INSERT INTO t2 VALUES (NULL),(35),(NULL),(2); +SELECT * FROM t1, t2 WHERE f4 >= f; +f1 f2 f3 f4 f +0 0 NULL 154 2 +0 0 NULL 154 35 +140 0 0 7 2 +NULL 255 117 197 2 +NULL 255 117 197 35 +DROP TABLE t1, t2; diff --git a/mysql-test/suite/parts/t/cache.test b/mysql-test/suite/parts/t/cache.test new file mode 100644 index 00000000000..fcf2ba5d6b6 --- /dev/null +++ b/mysql-test/suite/parts/t/cache.test @@ -0,0 +1,22 @@ +# +# Test cases related to row cache +# + +# The server must support partitioning. +--source include/have_partition.inc + +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, f4 INT, KEY (f4), + KEY (f1,f4,f3,f2) +) PARTITION BY RANGE(f1) ( PARTITION p VALUES LESS THAN MAXVALUE ); + +INSERT IGNORE INTO t1 VALUES +(140,0,0,7),(143,92,NULL,0),(0,0,NULL,154),(NULL,255,117,197),(0,0,NULL,0),(60,0,0,1); + +CREATE TABLE t2 (f INT); +INSERT INTO t2 VALUES (NULL),(35),(NULL),(2); + +--sorted_result +SELECT * FROM t1, t2 WHERE f4 >= f; + +# Cleanup +DROP TABLE t1, t2; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 2c0d313fd2b..e2d6bb1bdfe 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5070,6 +5070,7 @@ int ha_partition::rnd_next(uchar *buf) } end: + DBUG_PRINT("exit", ("reset start_part")); m_part_spec.start_part= NO_CURRENT_PART_ID; end_dont_reset_start_part: DBUG_RETURN(result); @@ -6223,10 +6224,13 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, ha_rows rows= 0; uint ret_mrr_mode= 0; range_seq_t seq_it; + part_id_range save_part_spec; DBUG_ENTER("ha_partition::multi_range_read_info_const"); DBUG_PRINT("enter", ("partition this: %p", this)); m_mrr_new_full_buffer_size= 0; + save_part_spec= m_part_spec; + seq_it= seq->init(seq_init_param, n_ranges, *mrr_mode); if ((error= multi_range_key_create_key(seq, seq_it))) { @@ -6240,6 +6244,7 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, (probably running out of memory) and we need to fallback to normal reads */ + m_part_spec= save_part_spec; DBUG_RETURN(HA_POS_ERROR); } m_part_seq_if.get_key_info= @@ -6269,7 +6274,10 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, &m_mrr_buffer_size[i], &tmp_mrr_mode, cost); if (tmp_rows == HA_POS_ERROR) + { + m_part_spec= save_part_spec; DBUG_RETURN(HA_POS_ERROR); + } rows+= tmp_rows; ret_mrr_mode|= tmp_mrr_mode; m_mrr_new_full_buffer_size+= m_mrr_buffer_size[i]; @@ -6278,6 +6286,7 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, *mrr_mode= ret_mrr_mode; calc_cost: + m_part_spec= save_part_spec; cost->reset(); cost->avg_io_cost= 1; if ((*mrr_mode & HA_MRR_INDEX_ONLY) && rows > 2) @@ -8660,8 +8669,8 @@ int ha_partition::extra(enum ha_extra_function operation) { if (!m_myisam) DBUG_RETURN(loop_extra(operation)); - break; } + break; /* Category 3), used by MyISAM handlers */ case HA_EXTRA_PREPARE_FOR_UPDATE: |