diff -Narup ./032_mariadb-10.0.15-scale_registering_xid/sql/ha_partition.cc ./033_mariadb-10.0.15-partition_mrr2/sql/ha_partition.cc
--- ./032_mariadb-10.0.15-scale_registering_xid/sql/ha_partition.cc	2014-11-29 17:06:49.192408630 +0900
+++ ./033_mariadb-10.0.15-partition_mrr2/sql/ha_partition.cc	2014-11-29 17:07:29.307797068 +0900
@@ -420,10 +420,10 @@ void ha_partition::init_handler_variable
   m_new_partitions_share_refs.empty();
   m_part_ids_sorted_by_num_of_records= NULL;
 
-  m_range_info_list_len= 0;
-  m_range_info_list= NULL;
+  m_range_info= NULL;
   m_mrr_full_buffer_size= 0;
   m_mrr_full_buffer= NULL;
+  m_mrr_range_first= NULL;
 
 #ifdef DONT_HAVE_TO_BE_INITALIZED
   m_start_key.flag= 0;
@@ -3506,7 +3506,6 @@ int ha_partition::open(const char *name,
   ref_length= 0;
   m_ref_buf = NULL;
   m_ref_buf_length = 0;
-  m_seq_params = NULL;
   m_mode= mode;
   m_open_test_lock= test_if_locked;
   m_part_field_array= m_part_info->full_part_field_array;
@@ -3541,19 +3540,26 @@ int ha_partition::open(const char *name,
     bitmap_free(&(m_part_info->read_partitions));
     DBUG_RETURN(error);
   }
-  if (!(m_seq_params = (void **)
+  if (!(m_range_info = (void **)
     my_multi_malloc(MYF(MY_WME),
-      &m_seq_params, sizeof(void *) * m_tot_parts,
       &m_range_info, sizeof(range_id_t) * m_tot_parts,
       &m_stock_range_seq, sizeof(uint) * m_tot_parts,
       &m_mrr_buffer, sizeof(HANDLER_BUFFER) * m_tot_parts,
       &m_mrr_buffer_size, sizeof(uint) * m_tot_parts,
+      &m_part_mrr_range_length, sizeof(uint) * m_tot_parts,
+      &m_part_mrr_range_first,
+        sizeof(PARTITION_PART_KEY_MULTI_RANGE *) * m_tot_parts,
+      &m_part_mrr_range_current,
+        sizeof(PARTITION_PART_KEY_MULTI_RANGE *) * m_tot_parts,
+      &m_partition_part_key_multi_range_hld,
+        sizeof(PARTITION_PART_KEY_MULTI_RANGE_HLD) * m_tot_parts,
       NullS))
   ) {
     goto err_alloc;
   }
-  bzero(m_seq_params, m_tot_parts * sizeof(void *));
   bzero(m_mrr_buffer, m_tot_parts * sizeof(HANDLER_BUFFER));
+  bzero(m_part_mrr_range_first,
+    m_tot_parts * sizeof(PARTITION_PART_KEY_MULTI_RANGE *));
 
   if (m_is_clone_of)
   {
@@ -3669,10 +3675,10 @@ err_handler:
 err_alloc:
   free_partition_bitmaps();
   bitmap_free(&m_mrr_used_partitions);
-  if (m_seq_params)
+  if (m_range_info)
   {
-    my_free(m_seq_params);
-    m_seq_params = NULL;
+    my_free(m_range_info);
+    m_range_info = NULL;
   }
 
   DBUG_RETURN(error);
@@ -3793,6 +3799,7 @@ int ha_partition::close(void)
 {
   bool first= TRUE;
   handler **file;
+  uint i;
   DBUG_ENTER("ha_partition::close");
 
   DBUG_ASSERT(table->s == table_share);
@@ -3819,16 +3826,36 @@ int ha_partition::close(void)
   free_partition_bitmaps();
   DBUG_ASSERT(m_part_info);
   bitmap_free(&m_mrr_used_partitions);
-  if (m_seq_params)
+  for (i= 0; i < m_tot_parts; i++)
+  {
+    if (m_part_mrr_range_first[i])
+    {
+      PARTITION_PART_KEY_MULTI_RANGE *tmp_mrr_range_first=
+        m_part_mrr_range_first[i];
+      PARTITION_PART_KEY_MULTI_RANGE *tmp_mrr_range_current;
+      do {
+        tmp_mrr_range_current= tmp_mrr_range_first;
+        tmp_mrr_range_first= tmp_mrr_range_first->next;
+        my_free(tmp_mrr_range_current);
+      } while (tmp_mrr_range_first);
+    }
+  }
+  if (m_mrr_range_first)
   {
-    my_free(m_seq_params);
-    m_seq_params = NULL;
+    do {
+      m_mrr_range_current= m_mrr_range_first;
+      m_mrr_range_first= m_mrr_range_first->next;
+      if (m_mrr_range_current->key[0])
+        my_free(m_mrr_range_current->key[0]);
+      if (m_mrr_range_current->key[1])
+        my_free(m_mrr_range_current->key[1]);
+      my_free(m_mrr_range_current);
+    } while (m_mrr_range_first);
   }
-  if (m_range_info_list)
+  if (m_range_info)
   {
-    my_free(m_range_info_list);
-    m_range_info_list= NULL;
-    m_range_info_list_len= 0;
+    my_free(m_range_info);
+    m_range_info = NULL;
   }
   if (m_mrr_full_buffer)
   {
@@ -5878,11 +5905,6 @@ int ha_partition::index_end()
        i < m_tot_parts;
        i= bitmap_get_next_set(&m_part_info->read_partitions, i))
   {
-    if (m_seq_params[i])
-    {
-      m_seq->clone_end(m_seq_params[i]);
-      m_seq_params[i]= NULL;
-    }
     int tmp;
     if ((tmp= m_file[i]->ha_index_end()))
       error= tmp;
@@ -6520,6 +6542,267 @@ int ha_partition::read_range_next()
 }
 
 
+int ha_partition::multi_range_key_create_key(
+  RANGE_SEQ_IF *seq,
+  range_seq_t seq_it
+) {
+  uint i, length;
+  key_range *start_key, *end_key;
+  KEY_MULTI_RANGE *range;
+  DBUG_ENTER("ha_partition::multi_range_key_create_key");
+  bitmap_clear_all(&m_mrr_used_partitions);
+  m_mrr_range_length= 0;
+  bzero(m_part_mrr_range_length, sizeof(uint) * m_tot_parts);
+  if (!m_mrr_range_first)
+  {
+    if (!(m_mrr_range_first= (PARTITION_KEY_MULTI_RANGE *)
+      my_multi_malloc(MYF(MY_WME),
+        &m_mrr_range_current, sizeof(PARTITION_KEY_MULTI_RANGE),
+        NullS))
+    ) {
+      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+    }
+    m_mrr_range_first->id= 1;
+    m_mrr_range_first->key[0]= NULL;
+    m_mrr_range_first->key[1]= NULL;
+    m_mrr_range_first->next= NULL;
+  } else {
+    m_mrr_range_current= m_mrr_range_first;
+  }
+  for (i = 0; i < m_tot_parts; i++)
+  {
+    if (!m_part_mrr_range_first[i])
+    {
+      if (!(m_part_mrr_range_first[i]= (PARTITION_PART_KEY_MULTI_RANGE *)
+        my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+          &m_part_mrr_range_current[i], sizeof(PARTITION_PART_KEY_MULTI_RANGE),
+          NullS))
+      ) {
+        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+      }
+    } else {
+      m_part_mrr_range_current[i]= m_part_mrr_range_first[i];
+      m_part_mrr_range_current[i]->partition_key_multi_range= NULL;
+    }
+  }
+  while (!seq->next(seq_it, &m_mrr_range_current->key_multi_range))
+  {
+    m_mrr_range_length++;
+    range= &m_mrr_range_current->key_multi_range;
+    start_key= &range->start_key;
+    length= start_key->length;
+    if (
+      start_key->key &&
+      (
+        !m_mrr_range_current->key[0] ||
+        m_mrr_range_current->length[0] < length
+      )
+    ) {
+      if (m_mrr_range_current->key[0])
+      {
+        my_free(m_mrr_range_current->key[0]);
+      }
+      if (!(m_mrr_range_current->key[0]= (uchar *)
+        my_multi_malloc(MYF(MY_WME),
+          &m_mrr_range_current->key[0], length,
+          NullS))
+      ) {
+        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+      }
+      m_mrr_range_current->length[0]= length;
+    }
+    memcpy(m_mrr_range_current->key[0], start_key->key, length);
+    start_key->key= m_mrr_range_current->key[0];
+
+    end_key= &range->end_key;
+    length= end_key->length;
+    if (
+      end_key->key &&
+      (
+        !m_mrr_range_current->key[1] ||
+        m_mrr_range_current->length[1] < length
+      )
+    ) {
+      if (m_mrr_range_current->key[1])
+      {
+        my_free(m_mrr_range_current->key[1]);
+      }
+      if (!(m_mrr_range_current->key[1]= (uchar *)
+        my_multi_malloc(MYF(MY_WME),
+          &m_mrr_range_current->key[1], length,
+          NullS))
+      ) {
+        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+      }
+      m_mrr_range_current->length[1]= length;
+    }
+    memcpy(m_mrr_range_current->key[1], end_key->key, length);
+    end_key->key= m_mrr_range_current->key[1];
+    m_mrr_range_current->ptr= m_mrr_range_current->key_multi_range.ptr;
+    m_mrr_range_current->key_multi_range.ptr= m_mrr_range_current;
+
+    if (start_key->key)
+      get_partition_set(table, table->record[0], active_index,
+        start_key, &m_part_spec);
+    else {
+      m_part_spec.start_part = 0;
+      m_part_spec.end_part = m_tot_parts - 1;
+    }
+    for (i = m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+    {
+      if (bitmap_is_set(&(m_part_info->read_partitions), i))
+      {
+        bitmap_set_bit(&m_mrr_used_partitions, i);
+        m_part_mrr_range_length[i]++;
+        m_part_mrr_range_current[i]->partition_key_multi_range=
+          m_mrr_range_current;
+
+        if (!m_part_mrr_range_current[i]->next)
+        {
+          PARTITION_PART_KEY_MULTI_RANGE *tmp_part_mrr_range;
+          if (!(tmp_part_mrr_range= (PARTITION_PART_KEY_MULTI_RANGE *)
+            my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+              &tmp_part_mrr_range, sizeof(PARTITION_PART_KEY_MULTI_RANGE),
+              NullS))
+          ) {
+            DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+          }
+          m_part_mrr_range_current[i]->next= tmp_part_mrr_range;
+          m_part_mrr_range_current[i]= tmp_part_mrr_range;
+        } else {
+          m_part_mrr_range_current[i]= m_part_mrr_range_current[i]->next;
+          m_part_mrr_range_current[i]->partition_key_multi_range= NULL;
+        }
+      }
+    }
+
+    if (!m_mrr_range_current->next)
+    {
+      PARTITION_KEY_MULTI_RANGE *tmp_mrr_range;
+      if (!(tmp_mrr_range= (PARTITION_KEY_MULTI_RANGE *)
+        my_multi_malloc(MYF(MY_WME),
+          &tmp_mrr_range, sizeof(PARTITION_KEY_MULTI_RANGE),
+          NullS))
+      ) {
+        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+      }
+      tmp_mrr_range->id= m_mrr_range_current->id + 1;
+      tmp_mrr_range->key[0]= NULL;
+      tmp_mrr_range->key[1]= NULL;
+      tmp_mrr_range->next= NULL;
+      m_mrr_range_current->next= tmp_mrr_range;
+      m_mrr_range_current= tmp_mrr_range;
+    } else {
+      m_mrr_range_current= m_mrr_range_current->next;
+    }
+  }
+
+  /* set start and end part */
+  for (i= 0; i < m_tot_parts; i++)
+  {
+    if (bitmap_is_set(&m_mrr_used_partitions, i))
+    {
+      m_part_spec.start_part= i;
+      break;
+    }
+  }
+  for (i= m_tot_parts; i > 0; i--)
+  {
+    uint j= i - 1;
+    if (bitmap_is_set(&m_mrr_used_partitions, j))
+    {
+      m_part_spec.end_part= j;
+      break;
+    }
+  }
+  for (i= 0; i < m_tot_parts; i++)
+  {
+    m_partition_part_key_multi_range_hld[i].partition= this;
+    m_partition_part_key_multi_range_hld[i].part_id= i;
+    m_partition_part_key_multi_range_hld[i].partition_part_key_multi_range=
+      m_part_mrr_range_first[i];
+  }
+  DBUG_PRINT("info",("partition OK"));
+  DBUG_RETURN(0);
+}
+
+
+static void partition_multi_range_key_get_key_info(
+  void *init_params,
+  uint *length,
+  key_part_map *map
+) {
+  DBUG_ENTER("partition_multi_range_key_get_key_info");
+  PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+    (PARTITION_PART_KEY_MULTI_RANGE_HLD *)init_params;
+  ha_partition *partition= hld->partition;
+  key_range *start_key=
+    &partition->m_mrr_range_first->key_multi_range.start_key;
+  *length= start_key->length;
+  *map= start_key->keypart_map;
+  DBUG_VOID_RETURN;
+}
+
+
+static range_seq_t partition_multi_range_key_init(
+  void *init_params,
+  uint n_ranges,
+  uint flags
+) {
+  DBUG_ENTER("partition_multi_range_key_init");
+  PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+    (PARTITION_PART_KEY_MULTI_RANGE_HLD *)init_params;
+  ha_partition *partition= hld->partition;
+  uint i= hld->part_id;
+  partition->m_mrr_range_init_flags= flags;
+  hld->partition_part_key_multi_range= partition->m_part_mrr_range_first[i];
+  DBUG_RETURN(init_params);
+}
+
+
+static bool partition_multi_range_key_next(
+  range_seq_t seq,
+  KEY_MULTI_RANGE *range
+) {
+  DBUG_ENTER("partition_multi_range_key_next");
+  PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+    (PARTITION_PART_KEY_MULTI_RANGE_HLD *)seq;
+  PARTITION_KEY_MULTI_RANGE *partition_key_multi_range=
+    hld->partition_part_key_multi_range->partition_key_multi_range;
+  if (!partition_key_multi_range)
+    DBUG_RETURN(TRUE);
+  *range= partition_key_multi_range->key_multi_range;
+  hld->partition_part_key_multi_range=
+    hld->partition_part_key_multi_range->next;
+  DBUG_RETURN(FALSE);
+}
+
+
+static bool partition_multi_range_key_skip_record(
+  range_seq_t seq,
+  range_id_t range_info,
+  uchar *rowid
+) {
+  DBUG_ENTER("partition_multi_range_key_skip_record");
+  PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+    (PARTITION_PART_KEY_MULTI_RANGE_HLD *)seq;
+  DBUG_RETURN(hld->partition->m_seq_if->skip_record(
+    hld->partition->m_seq, range_info, rowid));
+}
+
+
+static bool partition_multi_range_key_skip_index_tuple(
+  range_seq_t seq,
+  range_id_t range_info
+) {
+  DBUG_ENTER("partition_multi_range_key_skip_index_tuple");
+  PARTITION_PART_KEY_MULTI_RANGE_HLD *hld=
+    (PARTITION_PART_KEY_MULTI_RANGE_HLD *)seq;
+  DBUG_RETURN(hld->partition->m_seq_if->skip_index_tuple(
+    hld->partition->m_seq, range_info));
+}
+
+
 ha_rows ha_partition::multi_range_read_info_const(uint keyno,
                                                   RANGE_SEQ_IF *seq,
                                                   void *seq_init_param, 
@@ -6531,29 +6814,47 @@ ha_rows ha_partition::multi_range_read_i
   uint i;
   handler **file;
   ha_rows rows= 0, tmp_rows;
+  range_seq_t seq_it;
+  uint tmp_mrr_mode, ret_mrr_mode= 0;
   DBUG_ENTER("ha_partition::multi_range_read_info_const");
   m_mrr_new_full_buffer_size= 0;
+  seq_it= seq->init(seq_init_param, n_ranges, *mrr_mode);
+  if ((error= multi_range_key_create_key(seq, seq_it)))
+  {
+    DBUG_RETURN(HA_POS_ERROR);
+  }
+  m_part_seq_if.get_key_info=
+    seq->get_key_info ? partition_multi_range_key_get_key_info : NULL;
+  m_part_seq_if.init=
+    partition_multi_range_key_init;
+  m_part_seq_if.next=
+    partition_multi_range_key_next;
+  m_part_seq_if.skip_record=
+    seq->skip_record ? partition_multi_range_key_skip_record : NULL;
+  m_part_seq_if.skip_index_tuple=
+    seq->skip_index_tuple ? partition_multi_range_key_skip_index_tuple : NULL;
+
   file= m_file;
   do
   {
     i= file - m_file;
-    if (bitmap_is_set(&(m_part_info->read_partitions), (i)))
+    if (bitmap_is_set(&m_mrr_used_partitions, i))
     {
-      void *seq_param= seq->clone_start(seq_init_param, &error);
-      if (!seq_param)
-        DBUG_RETURN(HA_POS_ERROR);
       m_mrr_buffer_size[i]= 0;
-      tmp_rows= (*file)->multi_range_read_info_const(keyno, seq, seq_param,
-                                                     n_ranges,
-                                                     &m_mrr_buffer_size[i],
-                                                     mrr_mode, cost);
-      seq->clone_end(seq_param);
+      tmp_mrr_mode= *mrr_mode;
+      tmp_rows= (*file)->multi_range_read_info_const(keyno, &m_part_seq_if,
+        &m_partition_part_key_multi_range_hld[i],
+        m_part_mrr_range_length[i],
+        &m_mrr_buffer_size[i],
+        &tmp_mrr_mode, cost);
       if (tmp_rows == HA_POS_ERROR)
         DBUG_RETURN(HA_POS_ERROR);
       rows+= tmp_rows;
+      ret_mrr_mode|= tmp_mrr_mode;
       m_mrr_new_full_buffer_size+= m_mrr_buffer_size[i];
     }
   } while (*(++file));
+  *mrr_mode= ret_mrr_mode;
   DBUG_RETURN(rows);
 }
 
@@ -6597,8 +6898,22 @@ int ha_partition::multi_range_read_init(
   handler **file;
   uchar *tmp_buffer;
   DBUG_ENTER("ha_partition::multi_range_read_init");
-  m_seq= seq;
-  bitmap_clear_all(&m_mrr_used_partitions);
+  m_seq_if= seq;
+  m_seq= seq->init(seq_init_param, n_ranges, mrr_mode);
+  if ((error= multi_range_key_create_key(seq, m_seq)))
+  {
+    DBUG_RETURN(error);
+  }
+  m_part_seq_if.get_key_info=
+    seq->get_key_info ? partition_multi_range_key_get_key_info : NULL;
+  m_part_seq_if.init=
+    partition_multi_range_key_init;
+  m_part_seq_if.next=
+    partition_multi_range_key_next;
+  m_part_seq_if.skip_record=
+    seq->skip_record ? partition_multi_range_key_skip_record : NULL;
+  m_part_seq_if.skip_index_tuple=
+    seq->skip_index_tuple ? partition_multi_range_key_skip_index_tuple : NULL;
   if (m_mrr_full_buffer_size < m_mrr_new_full_buffer_size)
   {
     if (m_mrr_full_buffer)
@@ -6619,11 +6934,8 @@ int ha_partition::multi_range_read_init(
   do
   {
     i= file - m_file;
-    if (bitmap_is_set(&(m_part_info->read_partitions), i))
+    if (bitmap_is_set(&m_mrr_used_partitions, i))
     {
-      m_seq_params[i]= seq->clone_start(seq_init_param, &error);
-      if (!m_seq_params[i])
-        goto error;
       if (m_mrr_new_full_buffer_size && m_mrr_buffer_size[i])
       {
         m_mrr_buffer[i].buffer= tmp_buffer;
@@ -6631,25 +6943,20 @@ int ha_partition::multi_range_read_init(
         tmp_buffer+= m_mrr_buffer_size[i];
         m_mrr_buffer[i].buffer_end= tmp_buffer;
       }
-      if ((error= (*file)->multi_range_read_init(seq, m_seq_params[i],
-                                                 n_ranges, mrr_mode,
-                                                 &m_mrr_buffer[i])))
+      if ((error= (*file)->multi_range_read_init(&m_part_seq_if,
+        &m_partition_part_key_multi_range_hld[i],
+        m_part_mrr_range_length[i],
+        mrr_mode,
+        &m_mrr_buffer[i])))
         goto error;
-      bitmap_set_bit(&m_mrr_used_partitions, i);
       m_stock_range_seq[i]= 0;
     }
   } while (*(++file));
   m_multi_range_read_first = TRUE;
-  m_current_range_seq = 0;
+  m_mrr_range_current= m_mrr_range_first;
   m_index_scan_type = partition_read_multi_range;
   m_mrr_mode= mrr_mode;
   m_mrr_n_ranges= n_ranges;
-  if ((error = handler::multi_range_read_init(seq,
-                                              seq_init_param,
-                                              n_ranges,
-                                              mrr_mode,
-                                              buf)))
-    goto error;
   DBUG_RETURN(0);
 
 error:
@@ -6664,29 +6971,6 @@ int ha_partition::multi_range_read_next(
   if (!(m_mrr_mode & HA_MRR_NO_ASSOCIATION))
   {
     if (m_multi_range_read_first) {
-      if (m_mrr_n_ranges > m_range_info_list_len)
-      {
-        if (m_range_info_list)
-        {
-          my_free(m_range_info_list);
-          m_range_info_list_len= 0;
-        }
-        if (!(m_range_info_list = (void **)
-          my_multi_malloc(MYF(MY_WME),
-            &m_range_info_list, sizeof(range_id_t) * m_mrr_n_ranges,
-            NullS))
-        ) {
-          DBUG_RETURN(HA_ERR_OUT_OF_MEM);
-        }
-        m_range_info_list_len= m_mrr_n_ranges;
-      }
-      uint i= 0;
-      while (!mrr_funcs.next(mrr_iter, &mrr_cur_range))
-      {
-        DBUG_ASSERT(i < m_mrr_n_ranges);
-        m_range_info_list[i]= (char *) mrr_cur_range.ptr;
-        ++i;
-      }
       if ((error = handle_ordered_index_scan(table->record[0], FALSE)))
         DBUG_RETURN(error);
       m_multi_range_read_first = FALSE;
@@ -6694,7 +6978,7 @@ int ha_partition::multi_range_read_next(
       if ((error = handle_ordered_next(table->record[0], eq_range)))
         DBUG_RETURN(error);
     }
-    *range_info= m_range_info_list[m_current_range_seq];
+    *range_info= m_mrr_range_current->ptr;
   } else {
     if (m_multi_range_read_first) {
       if ((error = handle_unordered_scan_next_partition(table->record[0])))
@@ -6704,7 +6988,8 @@ int ha_partition::multi_range_read_next(
       if ((error = handle_unordered_next(table->record[0], FALSE)))
         DBUG_RETURN(error);
     }
-    *range_info= m_range_info[m_last_part];
+    *range_info=
+      ((PARTITION_KEY_MULTI_RANGE *) m_range_info[m_last_part])->ptr;
   }
   DBUG_RETURN(0);
 }
@@ -7432,7 +7717,7 @@ int ha_partition::handle_ordered_index_s
   int error;
   uint i;
   uint j= queue_first_element(&m_queue);
-  uint smallest_range_seq = 0, range_seq;
+  uint smallest_range_seq = 0;
   bool found= FALSE;
   uchar *part_rec_buf_ptr= m_ordered_rec_buffer;
   int saved_error= HA_ERR_END_OF_FILE;
@@ -7529,20 +7814,17 @@ int ha_partition::handle_ordered_index_s
       {
         memcpy(rec_buf_ptr, table->record[0], m_rec_length);
         reverse_order = FALSE;
-        if (m_range_info[i] != m_range_info_list[m_current_range_seq])
+        if (((PARTITION_KEY_MULTI_RANGE *) m_range_info[i])->id !=
+          m_mrr_range_current->id)
         {
-          range_seq= m_current_range_seq + 1;
-          while (m_range_info[i] != m_range_info_list[range_seq])
-          {
-            ++range_seq;
-          }
-          m_stock_range_seq[i]= range_seq;
-          if (!smallest_range_seq || smallest_range_seq > range_seq)
-            smallest_range_seq= range_seq;
+          m_stock_range_seq[i]=
+            ((PARTITION_KEY_MULTI_RANGE *) m_range_info[i])->id;
+          if (!smallest_range_seq || smallest_range_seq > m_stock_range_seq[i])
+            smallest_range_seq= m_stock_range_seq[i];
           part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
           continue;
         }
-        m_stock_range_seq[i]= m_current_range_seq;
+        m_stock_range_seq[i]= m_mrr_range_current->id;
       }
       break;
     }
@@ -7598,7 +7880,10 @@ int ha_partition::handle_ordered_index_s
       }
       part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
     }
-    m_current_range_seq = smallest_range_seq;
+    while (m_mrr_range_current->id < smallest_range_seq)
+    {
+      m_mrr_range_current= m_mrr_range_current->next;
+    }
   }
   if (found)
   {
@@ -7792,14 +8077,11 @@ int ha_partition::handle_ordered_next(uc
     } else if (!error)
     {
       memcpy(rec_buf, table->record[0], m_rec_length);
-      if (m_range_info[part_id] != m_range_info_list[m_current_range_seq])
+      if (((PARTITION_KEY_MULTI_RANGE *) m_range_info[part_id])->id !=
+        m_mrr_range_current->id)
       {
-        uint range_seq= m_current_range_seq + 1;
-        while (m_range_info[part_id] != m_range_info_list[range_seq])
-        {
-          ++range_seq;
-        }
-        m_stock_range_seq[part_id]= range_seq;
+        m_stock_range_seq[part_id]=
+          ((PARTITION_KEY_MULTI_RANGE *) m_range_info[part_id])->id;
         queue_remove(&m_queue, (uint) 0);
         if (!m_queue.elements)
           get_next = TRUE;
@@ -7839,7 +8121,10 @@ int ha_partition::handle_ordered_next(uc
           }
           part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
         }
-        m_current_range_seq = smallest_range_seq;
+        while (m_mrr_range_current->id < smallest_range_seq)
+        {
+          m_mrr_range_current= m_mrr_range_current->next;
+        }
         queue_set_max_at_top(&m_queue, FALSE);
         queue_set_cmp_arg(&m_queue, (void *) m_curr_key_info);
         m_queue.elements = j;
diff -Narup ./032_mariadb-10.0.15-scale_registering_xid/sql/ha_partition.h ./033_mariadb-10.0.15-partition_mrr2/sql/ha_partition.h
--- ./032_mariadb-10.0.15-scale_registering_xid/sql/ha_partition.h	2014-11-29 17:06:49.194398596 +0900
+++ ./033_mariadb-10.0.15-partition_mrr2/sql/ha_partition.h	2014-11-29 17:07:29.309796916 +0900
@@ -64,6 +64,33 @@ typedef struct st_part_name_def
   my_bool is_subpart;
 } PART_NAME_DEF;
 
+
+typedef struct st_partition_key_multi_range
+{
+  uint id;
+  uchar *key[2];
+  uint length[2];
+  KEY_MULTI_RANGE key_multi_range;
+  range_id_t ptr;
+  st_partition_key_multi_range *next;
+} PARTITION_KEY_MULTI_RANGE;
+
+
+typedef struct st_partition_part_key_multi_range
+{
+  PARTITION_KEY_MULTI_RANGE *partition_key_multi_range;
+  st_partition_part_key_multi_range *next;
+} PARTITION_PART_KEY_MULTI_RANGE;
+
+
+typedef struct st_partition_part_key_multi_range_hld
+{
+  ha_partition *partition;
+  uint32 part_id;
+  PARTITION_PART_KEY_MULTI_RANGE *partition_part_key_multi_range;
+} PARTITION_PART_KEY_MULTI_RANGE_HLD;
+
+
 /** class where to save partitions Handler_share's */
 class Parts_share_refs
 {
@@ -748,15 +775,26 @@ public:
   MY_BITMAP m_mrr_used_partitions;
   uint *m_stock_range_seq;
   uint m_current_range_seq;
-  void **m_seq_params;
   uint m_mrr_mode;
   uint m_mrr_n_ranges;
   range_id_t *m_range_info;
-  uint m_range_info_list_len;
-  range_id_t *m_range_info_list;
   bool m_multi_range_read_first;
-  RANGE_SEQ_IF *m_seq;
-
+  uint m_mrr_range_init_flags;
+  uint m_mrr_range_length;
+  PARTITION_KEY_MULTI_RANGE *m_mrr_range_first;
+  PARTITION_KEY_MULTI_RANGE *m_mrr_range_current;
+  uint *m_part_mrr_range_length;
+  PARTITION_PART_KEY_MULTI_RANGE **m_part_mrr_range_first;
+  PARTITION_PART_KEY_MULTI_RANGE **m_part_mrr_range_current;
+  PARTITION_PART_KEY_MULTI_RANGE_HLD *m_partition_part_key_multi_range_hld;
+  range_seq_t m_seq;
+  RANGE_SEQ_IF *m_seq_if;
+  RANGE_SEQ_IF m_part_seq_if;
+
+  virtual int multi_range_key_create_key(
+    RANGE_SEQ_IF *seq,
+    range_seq_t seq_it
+  );
   virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
                                               void *seq_init_param, 
                                               uint n_ranges, uint *bufsz,
diff -Narup ./032_mariadb-10.0.15-scale_registering_xid/sql/handler.h ./033_mariadb-10.0.15-partition_mrr2/sql/handler.h
--- ./032_mariadb-10.0.15-scale_registering_xid/sql/handler.h	2014-11-29 17:06:49.198396131 +0900
+++ ./033_mariadb-10.0.15-partition_mrr2/sql/handler.h	2014-11-29 17:07:29.311797660 +0900
@@ -2139,9 +2139,6 @@ typedef struct st_range_seq_if
       1 - Otherwise
   */ 
   bool (*skip_index_tuple) (range_seq_t seq, range_id_t range_info);
-
-  void *(*clone_start)(void *init_params, int *error);
-  void (*clone_end)(void *init_params);
 } RANGE_SEQ_IF;
 
 typedef bool (*SKIP_INDEX_TUPLE_FUNC) (range_seq_t seq, range_id_t range_info);
diff -Narup ./032_mariadb-10.0.15-scale_registering_xid/sql/opt_range.cc ./033_mariadb-10.0.15-partition_mrr2/sql/opt_range.cc
--- ./032_mariadb-10.0.15-scale_registering_xid/sql/opt_range.cc	2014-11-29 17:03:56.243796073 +0900
+++ ./033_mariadb-10.0.15-partition_mrr2/sql/opt_range.cc	2014-11-29 17:07:29.316795424 +0900
@@ -3396,8 +3396,7 @@ double records_in_column_ranges(PARAM *p
   uint flags= 0;
   double total_rows= 0;
   RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init, 
-                         sel_arg_range_seq_next, 0, 0,
-                         sel_arg_range_clone_start, sel_arg_range_clone_end};
+                         sel_arg_range_seq_next, 0, 0};
   
   /* Handle cases when we don't have a valid non-empty list of range */
   if (!tree)
@@ -10635,7 +10634,7 @@ ha_rows check_quick_select(PARAM *param,
                            uint *mrr_flags, uint *bufsize, Cost_estimate *cost)
 {
   SEL_ARG_RANGE_SEQ seq;
-  RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0, sel_arg_range_clone_start, sel_arg_range_clone_end};
+  RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0};
   handler *file= param->table->file;
   ha_rows rows= HA_POS_ERROR;
   uint keynr= param->real_keynr[idx];
@@ -11676,7 +11675,7 @@ int QUICK_RANGE_SELECT::reset()
   DBUG_ENTER("QUICK_RANGE_SELECT::reset");
   last_range= NULL;
   cur_range= (QUICK_RANGE**) ranges.buffer;
-  RANGE_SEQ_IF seq_funcs= {NULL, quick_range_seq_init, quick_range_seq_next, 0, 0, quick_range_clone_start, quick_range_clone_end};
+  RANGE_SEQ_IF seq_funcs= {NULL, quick_range_seq_init, quick_range_seq_next, 0, 0};
   
   if (file->inited == handler::RND)
   {
diff -Narup ./032_mariadb-10.0.15-scale_registering_xid/sql/opt_range_mrr.cc ./033_mariadb-10.0.15-partition_mrr2/sql/opt_range_mrr.cc
--- ./032_mariadb-10.0.15-scale_registering_xid/sql/opt_range_mrr.cc	2014-11-29 17:03:56.249798613 +0900
+++ ./033_mariadb-10.0.15-partition_mrr2/sql/opt_range_mrr.cc	2014-11-29 17:07:29.321831143 +0900
@@ -86,30 +86,6 @@ range_seq_t sel_arg_range_seq_init(void 
 }
 
 
-void *sel_arg_range_clone_start(void *init_param, int *error)
-{
-  DBUG_ENTER("sel_arg_range_clone_start");
-  SEL_ARG_RANGE_SEQ *seq, *seq_base= (SEL_ARG_RANGE_SEQ*)init_param;
-  seq= (SEL_ARG_RANGE_SEQ *)my_multi_malloc(MYF(MY_WME),
-                                            &seq, sizeof(SEL_ARG_RANGE_SEQ),
-                                            NULL);
-  if (seq)
-    memcpy(seq, seq_base, sizeof(SEL_ARG_RANGE_SEQ));
-  else
-    *error= HA_ERR_OUT_OF_MEM;
-  DBUG_RETURN(seq);
-}
-
-
-void sel_arg_range_clone_end(void *init_param)
-{
-  DBUG_ENTER("sel_arg_range_clone_end");
-  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ *) init_param;
-  my_free(seq);
-  DBUG_VOID_RETURN;
-}
-
-
 static void step_down_to(SEL_ARG_RANGE_SEQ *arg, SEL_ARG *key_tree)
 {
   RANGE_SEQ_ENTRY *cur= &arg->stack[arg->i+1];
@@ -357,31 +333,6 @@ range_seq_t quick_range_seq_init(void *i
 }
 
 
-void *quick_range_clone_start(void *init_param, int *error)
-{
-  bool create_error= FALSE;
-  DBUG_ENTER("quick_range_clone_start");
-  QUICK_RANGE_SELECT *quick_base= (QUICK_RANGE_SELECT *) init_param;
-  QUICK_RANGE_SELECT *quick= quick_base->clone(&create_error);
-  if (create_error && quick) {
-    delete quick;
-    quick= NULL;
-  }
-  if (!quick)
-    *error= HA_ERR_OUT_OF_MEM;
-  DBUG_RETURN(quick);
-}
-
-
-void quick_range_clone_end(void *init_param)
-{
-  DBUG_ENTER("quick_range_clone_end");
-  QUICK_RANGE_SELECT *quick= (QUICK_RANGE_SELECT*)init_param;
-  delete quick;
-  DBUG_VOID_RETURN;
-}
-
-
 /*
   Range sequence interface implementation for array<QUICK_RANGE>: get next
   
diff -Narup ./032_mariadb-10.0.15-scale_registering_xid/sql/sql_join_cache.cc ./033_mariadb-10.0.15-partition_mrr2/sql/sql_join_cache.cc
--- ./032_mariadb-10.0.15-scale_registering_xid/sql/sql_join_cache.cc	2014-11-29 17:03:56.252796092 +0900
+++ ./033_mariadb-10.0.15-partition_mrr2/sql/sql_join_cache.cc	2014-11-29 17:07:29.323795540 +0900
@@ -3951,27 +3951,6 @@ DBUG_RETURN((range_seq_t) init_param);
 }
 
 
-static 
-void *bka_range_clone_start(void *init_param, int *error)
-{
-  DBUG_ENTER("bka_range_clone_start");
-  JOIN_CACHE_BKA *cache= new JOIN_CACHE_BKA((JOIN_CACHE_BKA *) init_param);
-  if (!cache)
-    *error= HA_ERR_OUT_OF_MEM;
-  DBUG_RETURN(cache);
-}
-
-
-static 
-void bka_range_clone_end(void *init_param)
-{
-  DBUG_ENTER("bka_range_clone_end");
-  JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) init_param;
-  delete cache;
-  DBUG_VOID_RETURN;
-}
-
-
 /*
 Get the next range/key over records from the join buffer used by a BKA cache
   
@@ -4232,9 +4211,7 @@ RANGE_SEQ_IF rs_funcs= { bka_range_seq_k
                          bka_range_seq_next,
                          check_only_first_match ?
                            bka_range_seq_skip_record : 0,
-                         bka_skip_index_tuple,
-                         bka_range_clone_start,
-                         bka_range_clone_end };
+                         bka_skip_index_tuple };
 
 DBUG_ENTER("JOIN_CACHE_BKA::init");
 
@@ -4456,27 +4433,6 @@ DBUG_RETURN((range_seq_t) init_param);
 }
 
 
-static 
-void *bkah_range_clone_start(void *init_param, int *error)
-{
-  DBUG_ENTER("bkah_range_clone_start");
-  JOIN_CACHE_BKAH *cache= new JOIN_CACHE_BKAH((JOIN_CACHE_BKAH *) init_param);
-  if (!cache)
-    *error= HA_ERR_OUT_OF_MEM;
-  DBUG_RETURN(cache);
-}
-
-
-static 
-void bkah_range_clone_end(void *init_param)
-{
-  DBUG_ENTER("bkah_range_clone_end");
-  JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) init_param;
-  delete cache;
-  DBUG_VOID_RETURN;
-}
-
-
 /*
 Get the next range/key over records from the join buffer of a BKAH cache  
   
@@ -4651,9 +4607,7 @@ int JOIN_CACHE_BKAH::init(bool for_expla
                            bkah_range_seq_next,
                            check_only_first_match && !no_association ?
                              bkah_range_seq_skip_record : 0,
-                           bkah_skip_index_tuple,
-                           bkah_range_clone_start,
-                           bkah_range_clone_end };
+                           bkah_skip_index_tuple };
 
   DBUG_ENTER("JOIN_CACHE_BKAH::init");
 
