diff options
author | Jacob Mathew <jacob.mathew@mariadb.com> | 2017-06-16 14:25:10 -0700 |
---|---|---|
committer | Jacob Mathew <jacob.mathew@mariadb.com> | 2017-06-16 14:25:10 -0700 |
commit | 7b51381a4fbc00d5503cbc268bb91f9cf11fdad7 (patch) | |
tree | b8ef55d78a733b944301d49aa6229a69adbe7c28 | |
parent | ba2336f6a31f0e5a040894934ad1c1aec52ae1e0 (diff) | |
download | mariadb-git-bb-10.2-spider-jacob.tar.gz |
Spider Patch Integrationbb-10.2-spider-jacob
Spiral patches 039 and 047.
Fixed bugs in patches 039 and 047, which resulted in a crash.
-rw-r--r-- | sql/ha_partition.cc | 16 | ||||
-rw-r--r-- | sql/ha_partition.h | 3 | ||||
-rw-r--r-- | sql/handler.cc | 70 | ||||
-rw-r--r-- | sql/handler.h | 28 | ||||
-rw-r--r-- | sql/opt_range.cc | 146 |
5 files changed, 196 insertions, 67 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index e1852d668dc..08ca749a4ae 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -12341,6 +12341,22 @@ void ha_partition::clear_top_table_fields() } +#ifdef HANDLER_HAS_PRUNE_PARTITIONS_FOR_CHILD +bool ha_partition::prune_partitions_for_child(THD *thd, Item *pprune_cond) +{ + bool res= TRUE; + handler **file; + DBUG_ENTER("ha_partition::prune_partitions_for_child"); + + for (file= m_file; *file; file++) + if (bitmap_is_set(&(m_part_info->read_partitions), (file - m_file))) + if (!(*file)->prune_partitions_for_child(thd, pprune_cond)) + res= FALSE; + DBUG_RETURN(res); +} +#endif + + #ifdef HA_CAN_BULK_ACCESS PARTITION_BULK_ACCESS_INFO *ha_partition::create_bulk_access_info() { diff --git a/sql/ha_partition.h b/sql/ha_partition.h index b846f253f86..58810f17a59 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1414,6 +1414,9 @@ public: Field **top_table_field, uint top_table_fields); virtual void clear_top_table_fields(); +#ifdef HANDLER_HAS_PRUNE_PARTITIONS_FOR_CHILD + virtual bool prune_partitions_for_child(THD *thd, Item *pprune_cond); +#endif private: int handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, uint flags); diff --git a/sql/handler.cc b/sql/handler.cc index 92dff7b99e8..1061041fabe 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6234,6 +6234,76 @@ void handler::unlock_shared_ha_data() mysql_mutex_unlock(&table_share->LOCK_ha_data); } + +int handler::set_top_table_and_fields(TABLE *top_table, + Field **top_table_field, + uint top_table_fields) +{ + DBUG_ENTER("handler::set_top_table_and_fields"); + DBUG_PRINT("info", ("set_top_table_fields=%s", + set_top_table_fields ? "TRUE" : "FALSE")); + if (!set_top_table_fields) + { + set_top_table_fields = TRUE; + this->top_table = top_table; + this->top_table_field = top_table_field; + this->top_table_fields = top_table_fields; + } + DBUG_RETURN(0); +} + + +void handler::clear_top_table_fields() +{ + DBUG_ENTER("handler::clear_top_table_fields"); + DBUG_PRINT("info", ("set_top_table_fields=%s", + set_top_table_fields ? "TRUE" : "FALSE")); + if (set_top_table_fields) + { + set_top_table_fields = FALSE; + top_table = NULL; + top_table_field = NULL; + top_table_fields = 0; + } + DBUG_VOID_RETURN; +} + + +Field *handler::get_top_table_field(uint16 field_index) +{ + DBUG_ENTER("handler::get_top_table_field"); + Field *field; + DBUG_PRINT("info", ("set_top_table_fields=%s", + set_top_table_fields ? "TRUE" : "FALSE")); + if (set_top_table_fields) + { + field = top_table->field[field_index]; + } else { + field = table->field[field_index]; + } + DBUG_RETURN(field); +} + + +Field *handler::field_exchange(Field *field) +{ + DBUG_ENTER("handler::field_exchange"); + DBUG_PRINT("info", ("set_top_table_fields=%s", + set_top_table_fields ? "TRUE" : "FALSE")); + if (set_top_table_fields) + { + if (field->table != top_table) + DBUG_RETURN(NULL); + if (!(field = top_table_field[field->field_index])) + DBUG_RETURN(NULL); + } else { + if (field->table != table) + DBUG_RETURN(NULL); + } + DBUG_RETURN(field); +} + + /** @brief Dummy function which accept information about log files which is not need by handlers diff --git a/sql/handler.h b/sql/handler.h index b7a4f170cfb..dcf39d813bc 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -47,6 +47,7 @@ #define HANDLER_HAS_NEED_INFO_FOR_AUTO_INC #define HANDLER_HAS_CAN_USE_FOR_AUTO_INC_INIT #define HANDLER_HAS_DIRECT_AGGREGATE +#define HANDLER_HAS_PRUNE_PARTITIONS_FOR_CHILD #define HANDLER_HAS_CHECK_AND_SET_BITMAP_FOR_UPDATE #define INFO_KIND_UPDATE_FIELDS 101 #define INFO_KIND_UPDATE_VALUES 102 @@ -3757,27 +3758,12 @@ public: */ virtual int set_top_table_and_fields(TABLE *top_table, Field **top_table_field, - uint top_table_fields) - { - if (!set_top_table_fields) - { - set_top_table_fields= TRUE; - this->top_table= top_table; - this->top_table_field= top_table_field; - this->top_table_fields= top_table_fields; - } - return 0; - } - virtual void clear_top_table_fields() - { - if (set_top_table_fields) - { - set_top_table_fields= FALSE; - top_table= NULL; - top_table_field= NULL; - top_table_fields= 0; - } - } + uint top_table_fields); + virtual void clear_top_table_fields(); + virtual Field *get_top_table_field(uint16 field_index); + virtual Field *field_exchange(Field *field); + virtual bool prune_partitions_for_child(THD *thd, Item *pprune_cond) + { return FALSE; } /** Push down an index condition to the handler. diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 5aa3c0be06d..8225bf6866c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3441,15 +3441,30 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) { bool retval= FALSE; partition_info *part_info = table->part_info; + TABLE *base_table= table; DBUG_ENTER("prune_partitions"); + DBUG_PRINT("info", ("partition table=%p", table)); + DBUG_PRINT("info", ("partition table->file=%p", table->file)); if (!part_info) - DBUG_RETURN(FALSE); /* not a partitioned table */ + { + /* not a partitioned table */ + retval= base_table->file->prune_partitions_for_child(thd, pprune_cond); + DBUG_RETURN(retval); + } if (!pprune_cond) { mark_all_partitions_as_used(part_info); - DBUG_RETURN(FALSE); + retval= base_table->file->prune_partitions_for_child(thd, pprune_cond); + DBUG_RETURN(retval); + } + + while (table->pos_in_table_list->parent_l) + { + table= table->pos_in_table_list->parent_l->table; + DBUG_PRINT("info", ("partition table=%p", table)); + DBUG_PRINT("info", ("partition table->file=%p", table->file)); } PART_PRUNE_PARAM prune_param; @@ -3467,7 +3482,8 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) { mark_all_partitions_as_used(part_info); free_root(&alloc,MYF(0)); // Return memory & allocator - DBUG_RETURN(FALSE); + retval= base_table->file->prune_partitions_for_child(thd, pprune_cond); + DBUG_RETURN(retval); } dbug_tmp_use_all_columns(table, old_sets, @@ -3497,19 +3513,27 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) tree= pprune_cond->get_mm_tree(range_par, &pprune_cond); if (!tree) + { + DBUG_PRINT("info", ("partition !tree")); goto all_used; + } if (tree->type == SEL_TREE::IMPOSSIBLE) { + DBUG_PRINT("info", ("partition tree->type == SEL_TREE::IMPOSSIBLE")); retval= TRUE; goto end; } if (tree->type != SEL_TREE::KEY && tree->type != SEL_TREE::KEY_SMALLER) + { + DBUG_PRINT("info", ("partition tree->type != SEL_TREE::KEY && tree->type != SEL_TREE::KEY_SMALLER")); goto all_used; + } if (tree->merges.is_empty()) { + DBUG_PRINT("info", ("partition tree->merges is empty")); /* Range analysis has produced a single list of intervals. */ prune_param.arg_stack_end= prune_param.arg_stack; prune_param.cur_part_fields= 0; @@ -3526,6 +3550,8 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) } else { + DBUG_PRINT("info", ("partition tree->merges.elements=%u", + tree->merges.elements)); if (tree->merges.elements == 1) { /* @@ -3599,6 +3625,8 @@ end: table->all_partitions_pruned_away= true; retval= TRUE; } + if (!retval) + retval= base_table->file->prune_partitions_for_child(thd, pprune_cond); DBUG_RETURN(retval); } @@ -4297,6 +4325,7 @@ static bool fields_ok_for_partition_index(Field **pfield) static bool create_partition_index_description(PART_PRUNE_PARAM *ppar) { + DBUG_ENTER("create_partition_index_description"); RANGE_OPT_PARAM *range_par= &(ppar->range_param); partition_info *part_info= ppar->part_info; uint used_part_fields, used_subpart_fields; @@ -4339,14 +4368,14 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar) total_parts)) || !(ppar->is_subpart_keypart= (my_bool*)alloc_root(alloc, sizeof(my_bool)* total_parts))) - return TRUE; + DBUG_RETURN(TRUE); if (ppar->subpart_fields) { my_bitmap_map *buf; uint32 bufsize= bitmap_buffer_size(ppar->part_info->num_subparts); if (!(buf= (my_bitmap_map*) alloc_root(alloc, bufsize))) - return TRUE; + DBUG_RETURN(TRUE); my_bitmap_init(&ppar->subparts_bitmap, buf, ppar->part_info->num_subparts, FALSE); } @@ -4367,6 +4396,8 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar) key_part->length, key_part->store_length)); key_part->field= (*field); + DBUG_PRINT("info", ("key_part->field->field_name=%s", + key_part->field->field_name)); key_part->image_type = Field::itRAW; /* We set keypart flag to 0 here as the only HA_PART_KEY_SEG is checked @@ -4395,12 +4426,12 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar) if (!(range_par->min_key= (uchar*)alloc_root(alloc,total_key_len)) || !(range_par->max_key= (uchar*)alloc_root(alloc,total_key_len))) { - return true; + DBUG_RETURN(TRUE); } DBUG_EXECUTE("info", print_partitioning_index(range_par->key_parts, range_par->key_parts_end);); - return FALSE; + DBUG_RETURN(FALSE); } @@ -7605,47 +7636,68 @@ Item_bool_func::get_mm_parts(RANGE_OPT_PARAM *param, Field *field, (value_used_tables= value->used_tables()) & ~(param->prev_tables | param->read_tables)) DBUG_RETURN(0); - for (; key_part != end ; key_part++) - { - if (field->eq(key_part->field)) - { - SEL_ARG *sel_arg=0; - if (!tree && !(tree=new (param->thd->mem_root) SEL_TREE(param->mem_root, - param->keys))) - DBUG_RETURN(0); // OOM - if (!value || !(value_used_tables & ~param->read_tables)) - { - /* - We need to restore the runtime mem_root of the thread in this - function because it evaluates the value of its argument, while - the argument can be any, e.g. a subselect. The subselect - items, in turn, assume that all the memory allocated during - the evaluation has the same life span as the item itself. - TODO: opt_range.cc should not reset thd->mem_root at all. - */ - MEM_ROOT *tmp_root= param->mem_root; - param->thd->mem_root= param->old_root; - sel_arg= get_mm_leaf(param, key_part->field, key_part, type, value); - param->thd->mem_root= tmp_root; - - if (!sel_arg) - continue; - if (sel_arg->type == SEL_ARG::IMPOSSIBLE) - { - tree->type=SEL_TREE::IMPOSSIBLE; - DBUG_RETURN(tree); - } - } - else + handler *file= param->table->file; + DBUG_PRINT("info", ("param->table->s->db=%s", + param->table->s->db.str)); + DBUG_PRINT("info", ("param->table->s->table_name=%s", + param->table->s->table_name.str)); + DBUG_PRINT("info", ("field->field_name=%s", field->field_name)); + Field *child_field = file->field_exchange(field); + if (child_field) + { + DBUG_PRINT("info", ("child_field->field_name=%s", child_field->field_name)); + for (; key_part != end; key_part++) + { + DBUG_PRINT("info", ("key_part->field->field_name=%s", + key_part->field->field_name)); + DBUG_PRINT("info", ("key_part->field->field_index=%u", + key_part->field->field_index)); +/* + Field *key_field= file->get_top_table_field(key_part->field->field_index); + DBUG_PRINT("info",("key_field->field_name=%s", key_field->field_name)); + if (field->eq(key_field)) +*/ + if (child_field->eq(key_part->field)) { - // This key may be used later - if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY))) - DBUG_RETURN(0); // OOM + DBUG_PRINT("info", ("match field")); + SEL_ARG *sel_arg=0; + if (!tree && !(tree=new (param->thd->mem_root) SEL_TREE(param->mem_root, + param->keys))) + DBUG_RETURN(0); // OOM + if (!value || !(value_used_tables & ~param->read_tables)) + { + /* + We need to restore the runtime mem_root of the thread in this + function because it evaluates the value of its argument, while + the argument can be any, e.g. a subselect. The subselect + items, in turn, assume that all the memory allocated during + the evaluation has the same life span as the item itself. + TODO: opt_range.cc should not reset thd->mem_root at all. + */ + MEM_ROOT *tmp_root= param->mem_root; + param->thd->mem_root= param->old_root; + sel_arg= get_mm_leaf(param, key_part->field, key_part, type, value); + param->thd->mem_root= tmp_root; + + if (!sel_arg) + continue; + if (sel_arg->type == SEL_ARG::IMPOSSIBLE) + { + tree->type=SEL_TREE::IMPOSSIBLE; + DBUG_RETURN(tree); + } + } + else + { + // This key may be used later + if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY))) + DBUG_RETURN(0); // OOM + } + sel_arg->part=(uchar)key_part->part; + sel_arg->max_part_no= sel_arg->part+1; + tree->keys[key_part->key]=sel_add(tree->keys[key_part->key], sel_arg); + tree->keys_map.set_bit(key_part->key); } - sel_arg->part=(uchar) key_part->part; - sel_arg->max_part_no= sel_arg->part+1; - tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg); - tree->keys_map.set_bit(key_part->key); } } @@ -7716,6 +7768,7 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param, if (field->cmp_type() != STRING_RESULT) DBUG_RETURN(0); + DBUG_PRINT("info", ("value=%p", value)); /* TODO: Check if this was a function. This should have be optimized away @@ -7944,6 +7997,7 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param, } } + DBUG_PRINT("info", ("type=%u", type)); switch (type) { case LT_FUNC: if (stored_field_cmp_to_item(param->thd, field, value) == 0) |