From 6a490ca0fbcf0ceeaeee55bd6c98eb1ea8bcb8c5 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 28 Aug 2019 19:51:23 +0300 Subject: MDEV-18501 Partition pruning doesn't work for historical queries (fix) Pruning fix for SYSTEM_TIME INTERVAL partitioning. Allocating one more element in range_int_array for CURRENT partition is required for RANGE pruning to work correctly (get_partition_id_range_for_endpoint()). --- mysql-test/suite/versioning/r/partition_rotation.result | 2 +- sql/sql_lex.cc | 4 ---- sql/sql_partition.cc | 13 +++++++++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/versioning/r/partition_rotation.result b/mysql-test/suite/versioning/r/partition_rotation.result index 7e25f122238..82558085c02 100644 --- a/mysql-test/suite/versioning/r/partition_rotation.result +++ b/mysql-test/suite/versioning/r/partition_rotation.result @@ -47,7 +47,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 for system_time as of '2001-02-04 10:20:30'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1_p1sp0,p1_p1sp1,p0_p0sp0,p0_p0sp1,p2_p2sp0,p2_p2sp1,pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # Using where +1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p2_p2sp0,p2_p2sp1,pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # Using where set @ts=(select row_end from t1 for system_time all where i=1); select * from t1 for system_time all where row_end = @ts; i diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 1825ce7c1ce..d3c98115659 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -8171,8 +8171,6 @@ bool LEX::part_values_current(THD *thd) elem->type= partition_element::CURRENT; DBUG_ASSERT(part_info->vers_info); part_info->vers_info->now_part= elem; - if (unlikely(part_info->init_column_part(thd))) - return true; return false; } @@ -8203,8 +8201,6 @@ bool LEX::part_values_history(THD *thd) return true; } elem->type= partition_element::HISTORY; - if (unlikely(part_info->init_column_part(thd))) - return true; return false; } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index ba6d0f14aeb..f6afb7955b5 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1563,7 +1563,7 @@ static bool check_vers_constants(THD *thd, partition_info *part_info) return 0; part_info->range_int_array= - (longlong*) thd->alloc(hist_parts * sizeof(longlong)); + (longlong*) thd->alloc(part_info->num_parts * sizeof(longlong)); MYSQL_TIME ltime; List_iterator it(part_info->partitions); @@ -1582,6 +1582,9 @@ static bool check_vers_constants(THD *thd, partition_info *part_info) if (vers_info->hist_part->range_value <= thd->query_start()) vers_info->hist_part= el; } + DBUG_ASSERT(el == vers_info->now_part); + el->max_value= true; + part_info->range_int_array[el->id]= el->range_value= LONGLONG_MAX; return 0; err: my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "TIMESTAMP", "INTERVAL"); @@ -7671,6 +7674,11 @@ static void set_up_range_analysis_info(partition_info *part_info) partitioning */ switch (part_info->part_type) { + case VERSIONING_PARTITION: + if (!part_info->vers_info->interval.is_set()) + { + break; + } case RANGE_PARTITION: case LIST_PARTITION: if (!part_info->column_list) @@ -8107,7 +8115,8 @@ static int get_part_iter_for_interval_via_mapping(partition_info *part_info, part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE; part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE; - if (part_info->part_type == RANGE_PARTITION) + if (part_info->part_type == RANGE_PARTITION || + part_info->part_type == VERSIONING_PARTITION) { if (part_info->part_charset_field_array) get_endpoint= get_partition_id_range_for_endpoint_charset; -- cgit v1.2.1