diff -Narup ./002_mariadb-10.0.15-spider/sql/ha_partition.cc ./003_mariadb-10.0.15-vp/sql/ha_partition.cc
--- ./002_mariadb-10.0.15-spider/sql/ha_partition.cc	2014-11-29 17:01:07.231796206 +0900
+++ ./003_mariadb-10.0.15-vp/sql/ha_partition.cc	2014-11-29 17:01:25.372795661 +0900
@@ -7117,6 +7117,7 @@ void ha_partition::get_dynamic_partition
 
 int ha_partition::extra(enum ha_extra_function operation)
 {
+  ulonglong additional_table_flags;
   DBUG_ENTER("ha_partition:extra");
   DBUG_PRINT("info", ("operation: %d", (int) operation));
 
@@ -7239,13 +7240,30 @@ int ha_partition::extra(enum ha_extra_fu
   }
     /* Category 9) Operations only used by MERGE */
   case HA_EXTRA_ADD_CHILDREN_LIST:
+    DBUG_RETURN(loop_extra(operation));
   case HA_EXTRA_ATTACH_CHILDREN:
+    int result;
+    handler **file;
+    if ((result = loop_extra(operation)))
+      DBUG_RETURN(result);
+    m_num_locks = 0;
+    additional_table_flags =
+      (HA_CAN_BG_SEARCH | HA_CAN_BG_INSERT | HA_CAN_BG_UPDATE);
+    file = m_file;
+    do
+    {
+      m_num_locks += (*file)->lock_count();
+      additional_table_flags &= ~((ulonglong) ((*file)->ha_table_flags() ^
+        (HA_CAN_BG_SEARCH | HA_CAN_BG_INSERT | HA_CAN_BG_UPDATE)));
+    } while (*(++file));
+    cached_table_flags |= additional_table_flags;
+    break;
   case HA_EXTRA_IS_ATTACHED_CHILDREN:
+    DBUG_RETURN(loop_extra(operation));
   case HA_EXTRA_DETACH_CHILDREN:
-  {
-    /* Special actions for MERGE tables. Ignore. */
-    break;
-  }
+    cached_table_flags &= ~((ulonglong)
+      (HA_CAN_BG_SEARCH | HA_CAN_BG_INSERT | HA_CAN_BG_UPDATE));
+    DBUG_RETURN(loop_extra(operation));
   /*
     http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html
     says we no longer support logging to partitioned tables, so we fail
@@ -9123,6 +9141,19 @@ const COND *ha_partition::cond_push(cons
   handler **file= m_file;
   COND *res_cond = NULL;
   DBUG_ENTER("ha_partition::cond_push");
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  if (set_top_table_fields)
+  {
+    do
+    {
+      if ((*file)->set_top_table_and_fields(top_table,
+                                        top_table_field,
+                                        top_table_fields))
+        DBUG_RETURN(cond);
+    } while (*(++file));
+    file= m_file;
+  }
+#endif
 
   do
   {
@@ -9151,6 +9182,20 @@ void ha_partition::cond_pop()
 }
 
 
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+void ha_partition::clear_top_table_fields()
+{
+  handler **file;
+  if (set_top_table_fields)
+  {
+    set_top_table_fields = FALSE;
+    for (file= m_file; *file; file++)
+      (*file)->clear_top_table_fields();
+  }
+}
+#endif
+
+
 struct st_mysql_storage_engine partition_storage_engine=
 { MYSQL_HANDLERTON_INTERFACE_VERSION };
 
diff -Narup ./002_mariadb-10.0.15-spider/sql/ha_partition.h ./003_mariadb-10.0.15-vp/sql/ha_partition.h
--- ./002_mariadb-10.0.15-spider/sql/ha_partition.h	2014-11-29 17:01:07.232796383 +0900
+++ ./003_mariadb-10.0.15-vp/sql/ha_partition.h	2014-11-29 17:01:25.373795437 +0900
@@ -28,6 +28,8 @@ enum partition_keywords
 };
 
 
+#define PARTITION_HAS_EXTRA_ATTACH_CHILDREN
+#define PARTITION_HAS_GET_CHILD_HANDLERS
 #define PARTITION_BYTES_IN_POS 2
 
 
@@ -284,6 +286,10 @@ private:
   MY_BITMAP m_key_not_found_partitions;
   bool m_key_not_found;
 public:
+  handler **get_child_handlers()
+  {
+    return m_file;
+  }
   Partition_share *get_part_share() { return part_share; }
   handler *clone(const char *name, MEM_ROOT *mem_root);
   virtual void set_part_info(partition_info *part_info)
@@ -1219,6 +1225,9 @@ public:
   */
     virtual const COND *cond_push(const COND *cond);
     virtual void cond_pop();
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+    virtual void clear_top_table_fields();
+#endif
 
     private:
     int handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, uint flags);
diff -Narup ./002_mariadb-10.0.15-spider/sql/handler.h ./003_mariadb-10.0.15-vp/sql/handler.h
--- ./002_mariadb-10.0.15-spider/sql/handler.h	2014-11-22 06:02:55.000000000 +0900
+++ ./003_mariadb-10.0.15-vp/sql/handler.h	2014-11-29 17:01:25.378795153 +0900
@@ -39,6 +39,8 @@
 #include <keycache.h>
 #include <mysql/psi/mysql_table.h>
 
+#define HANDLER_HAS_TOP_TABLE_FIELDS
+
 #if MAX_KEY > 128
 #error MAX_KEY is too large.  Values up to 128 are supported.
 #endif
@@ -263,6 +265,11 @@ enum enum_alter_inplace_result {
  */
 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
 
+#define HA_CAN_BG_SEARCH       (1LL << 45)
+#define HA_CAN_BG_INSERT       (1LL << 46)
+#define HA_CAN_BG_UPDATE       (1LL << 47)
+#define HA_CAN_MULTISTEP_MERGE (1LL << 48)
+
 /* bits in index_flags(index_number) for what you can do with index */
 #define HA_READ_NEXT            1       /* TODO really use this flag */
 #define HA_READ_PREV            2       /* supports ::index_prev */
@@ -1372,6 +1379,7 @@ static inline sys_var *find_hton_sysvar(
 #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
 #define HTON_SUPPORT_LOG_TABLES      (1 << 7) //Engine supports log tables
 #define HTON_NO_PARTITION            (1 << 8) //Not partition of these tables
+#define HTON_CAN_MULTISTEP_MERGE     (1 << 9) //You can merge mearged tables
 
 /*
   This flag should be set when deciding that the engine does not allow
@@ -2529,6 +2537,11 @@ public:
   virtual void unbind_psi();
   virtual void rebind_psi();
 
+  bool set_top_table_fields;
+  struct TABLE *top_table;
+  Field **top_table_field;
+  uint top_table_fields;
+
 private:
   /**
     The lock type set by when calling::ha_external_lock(). This is 
@@ -2556,7 +2569,9 @@ public:
     pushed_idx_cond(NULL),
     pushed_idx_cond_keyno(MAX_KEY),
     auto_inc_intervals_count(0),
-    m_psi(NULL), m_lock_type(F_UNLCK), ha_share(NULL)
+    m_psi(NULL), set_top_table_fields(FALSE), top_table(0),
+    top_table_field(0), top_table_fields(0),
+    m_lock_type(F_UNLCK), ha_share(NULL)
   {
     DBUG_PRINT("info",
                ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
@@ -3369,6 +3384,29 @@ public:
    Pops the top if condition stack, if stack is not empty.
  */
  virtual void cond_pop() { return; };
+ 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;
+   }
+ }
 
  /**
    Push down an index condition to the handler.
diff -Narup ./002_mariadb-10.0.15-spider/sql/sql_base.cc ./003_mariadb-10.0.15-vp/sql/sql_base.cc
--- ./002_mariadb-10.0.15-spider/sql/sql_base.cc	2014-11-22 06:02:53.000000000 +0900
+++ ./003_mariadb-10.0.15-vp/sql/sql_base.cc	2014-11-29 17:01:25.382795910 +0900
@@ -1434,14 +1434,34 @@ unique_table(THD *thd, TABLE_LIST *table
              bool check_alias)
 {
   TABLE_LIST *dup;
-  if (table->table && table->table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
-  {
-    TABLE_LIST *child;
+  if (table->table &&
+    (
+      table->table->file->ht->db_type == DB_TYPE_MRG_MYISAM ||
+      (table->table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
+    )
+  ) {
+    TABLE_LIST *child, *tmp_parent;
     dup= NULL;
     /* Check duplicates of all merge children. */
-    for (child= table->next_global; child && child->parent_l == table;
+    for (child= table->next_global; child;
          child= child->next_global)
     {
+      if (
+        child->table &&
+        (
+          child->table->file->ht->db_type == DB_TYPE_MRG_MYISAM ||
+          (child->table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
+        )
+      )
+        continue;
+      tmp_parent = child;
+      while ((tmp_parent = tmp_parent->parent_l))
+      {
+        if (tmp_parent == table)
+          break;
+      }
+      if (!tmp_parent)
+        break;
       if ((dup= find_dup_table(thd, child, child->next_global, check_alias)))
         break;
     }
@@ -4593,8 +4613,12 @@ restart:
     TABLE *tbl= tables->table;
 
     /* Schema tables may not have a TABLE object here. */
-    if (tbl && tbl->file->ht->db_type == DB_TYPE_MRG_MYISAM)
-    {
+    if (tbl &&
+      (
+        tbl->file->ht->db_type == DB_TYPE_MRG_MYISAM ||
+        (tbl->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
+      )
+    ) {
       /* MERGE tables need to access parent and child TABLE_LISTs. */
       DBUG_ASSERT(tbl->pos_in_table_list == tables);
       if (tbl->file->extra(HA_EXTRA_ATTACH_CHILDREN))
@@ -5037,8 +5061,10 @@ TABLE *open_ltable(THD *thd, TABLE_LIST 
     */
     DBUG_ASSERT(table_list->table);
     table= table_list->table;
-    if (table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
-    {
+    if (
+      table->file->ht->db_type == DB_TYPE_MRG_MYISAM ||
+      (table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
+    ) {
       /* A MERGE table must not come here. */
       /* purecov: begin tested */
       my_error(ER_WRONG_OBJECT, MYF(0), table->s->db.str,
