diff -Narup ./038_mariadb-10.0.15-partition_fulltext2/sql/ha_partition.cc ./039_mariadb-10.0.15-child_partition_pruning/sql/ha_partition.cc
--- ./038_mariadb-10.0.15-partition_fulltext2/sql/ha_partition.cc	2014-11-29 17:08:53.572795615 +0900
+++ ./039_mariadb-10.0.15-child_partition_pruning/sql/ha_partition.cc	2014-11-29 17:09:03.933590356 +0900
@@ -12077,6 +12077,22 @@ void ha_partition::clear_top_table_field
 #endif
 
 
+#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 -Narup ./038_mariadb-10.0.15-partition_fulltext2/sql/ha_partition.h ./039_mariadb-10.0.15-child_partition_pruning/sql/ha_partition.h
--- ./038_mariadb-10.0.15-partition_fulltext2/sql/ha_partition.h	2014-11-29 17:08:53.572795615 +0900
+++ ./039_mariadb-10.0.15-child_partition_pruning/sql/ha_partition.h	2014-11-29 17:09:03.934795234 +0900
@@ -1425,6 +1425,9 @@ public:
 #ifdef HANDLER_HAS_TOP_TABLE_FIELDS
     virtual void clear_top_table_fields();
 #endif
+#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 -Narup ./038_mariadb-10.0.15-partition_fulltext2/sql/handler.cc ./039_mariadb-10.0.15-child_partition_pruning/sql/handler.cc
--- ./038_mariadb-10.0.15-partition_fulltext2/sql/handler.cc	2014-11-29 17:07:12.241695603 +0900
+++ ./039_mariadb-10.0.15-child_partition_pruning/sql/handler.cc	2014-11-29 17:09:04.155796252 +0900
@@ -6231,6 +6231,36 @@ void handler::unlock_shared_ha_data()
     mysql_mutex_unlock(&table_share->LOCK_ha_data);
 }
 
+
+Field *handler::get_top_table_field(uint16 field_index)
+{
+  Field *field;
+  if (set_top_table_fields)
+  {
+    field = top_table->field[field_index];
+  } else {
+    field = table->field[field_index];
+  }
+  return field;
+}
+
+
+Field *handler::field_exchange(Field *field)
+{
+  if (set_top_table_fields)
+  {
+    if (field->table != top_table)
+      return NULL;
+    if (!(field = top_table_field[field->field_index]))
+      return NULL;
+  } else {
+    if (field->table != table)
+      return NULL;
+  }
+  return field;
+}
+
+
 /** @brief
   Dummy function which accept information about log files which is not need
   by handlers
diff -Narup ./038_mariadb-10.0.15-partition_fulltext2/sql/handler.h ./039_mariadb-10.0.15-child_partition_pruning/sql/handler.h
--- ./038_mariadb-10.0.15-partition_fulltext2/sql/handler.h	2014-11-29 17:08:53.576754903 +0900
+++ ./039_mariadb-10.0.15-child_partition_pruning/sql/handler.h	2014-11-29 17:09:05.973380133 +0900
@@ -44,6 +44,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 INFO_KIND_UPDATE_FIELDS 101
 #define INFO_KIND_UPDATE_VALUES 102
 #define INFO_KIND_FORCE_LIMIT_BEGIN 103
@@ -3553,6 +3554,10 @@ public:
      top_table_fields = 0;
    }
  }
+ 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 -Narup ./038_mariadb-10.0.15-partition_fulltext2/sql/opt_range.cc ./039_mariadb-10.0.15-child_partition_pruning/sql/opt_range.cc
--- ./038_mariadb-10.0.15-partition_fulltext2/sql/opt_range.cc	2014-11-29 17:07:29.316795424 +0900
+++ ./039_mariadb-10.0.15-child_partition_pruning/sql/opt_range.cc	2014-11-29 17:09:06.052654379 +0900
@@ -3998,17 +3998,32 @@ bool prune_partitions(THD *thd, TABLE *t
 {
   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;
   MEM_ROOT alloc;
   RANGE_OPT_PARAM  *range_par= &prune_param.range_param;
@@ -4024,7 +4039,8 @@ bool prune_partitions(THD *thd, TABLE *t
   {
     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, 
@@ -4052,19 +4068,27 @@ bool prune_partitions(THD *thd, TABLE *t
 
   tree= 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;
@@ -4081,6 +4105,8 @@ bool prune_partitions(THD *thd, TABLE *t
   }
   else
   {
+    DBUG_PRINT("info",("partition tree->merges.elements=%u",
+      tree->merges.elements));
     if (tree->merges.elements == 1)
     {
       /* 
@@ -4154,6 +4180,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);
 }
 
@@ -8154,10 +8182,14 @@ get_mm_parts(RANGE_OPT_PARAM *param, CON
   if (value &&
       value->used_tables() & ~(param->prev_tables | param->read_tables))
     DBUG_RETURN(0);
+  handler *file= key_part->field->table->file;
   for (; key_part != end ; key_part++)
   {
-    if (field->eq(key_part->field))
+    Field *key_field= file->get_top_table_field(key_part->field->field_index);
+
+    if (field->eq(key_field))
     {
+      DBUG_PRINT("info",("match field"));
       SEL_ARG *sel_arg=0;
       if (!tree && !(tree=new SEL_TREE()))
 	DBUG_RETURN(0);				// OOM
@@ -8215,6 +8247,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND
   param->thd->mem_root= param->old_root;
   if (!value)					// IS NULL or IS NOT NULL
   {
+    DBUG_PRINT("info",("!value"));
     if (field->table->maybe_null)		// Can't use a key on this
       goto end;
     if (!maybe_null)				// Not null field
@@ -8233,6 +8266,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND
     goto end;
   }
 
+  DBUG_PRINT("info",("value=%p", value));
   /*
     1. Usually we can't use an index if the column collation
        differ from the operation collation.
@@ -8511,6 +8545,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND
     }
   }
 
+  DBUG_PRINT("info",("type=%u", type));
   switch (type) {
   case Item_func::LT_FUNC:
     if (stored_field_cmp_to_item(param->thd, field, value) == 0)
@@ -8580,6 +8615,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND
 
 end:
   param->thd->mem_root= alloc;
+  DBUG_PRINT("info",("tree=%p", tree));
   DBUG_RETURN(tree);
 }
 
