[Commits] 7b51381a4fb: Spider Patch Integration

jacob.mathew at mariadb.com jacob.mathew at mariadb.com
Sat Jun 17 02:02:13 EEST 2017


revision-id: 7b51381a4fbc00d5503cbc268bb91f9cf11fdad7 (mariadb-10.2.3-107-g7b51381a4fb)
parent(s): ba2336f6a31f0e5a040894934ad1c1aec52ae1e0
author: Jacob Mathew
committer: Jacob Mathew
timestamp: 2017-06-16 14:25:10 -0700
message:

Spider Patch Integration

Spiral patches 039 and 047.
Fixed bugs in patches 039 and 047, which resulted in a crash.

---
 sql/ha_partition.cc |  16 ++++++
 sql/ha_partition.h  |   3 ++
 sql/handler.cc      |  70 +++++++++++++++++++++++++
 sql/handler.h       |  28 +++-------
 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 @@ class ha_partition :public handler
                                          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 @@ class handler :public Sql_alloc
  */
  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 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
     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)


More information about the commits mailing list