summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Mathew <jacob.mathew@mariadb.com>2017-06-16 14:25:10 -0700
committerJacob Mathew <jacob.mathew@mariadb.com>2017-06-16 14:25:10 -0700
commit7b51381a4fbc00d5503cbc268bb91f9cf11fdad7 (patch)
treeb8ef55d78a733b944301d49aa6229a69adbe7c28
parentba2336f6a31f0e5a040894934ad1c1aec52ae1e0 (diff)
downloadmariadb-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.cc16
-rw-r--r--sql/ha_partition.h3
-rw-r--r--sql/handler.cc70
-rw-r--r--sql/handler.h28
-rw-r--r--sql/opt_range.cc146
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)