diff -Narup ./006_mariadb-10.0.15-direct_update_rows/sql/ha_partition.cc ./007_mariadb-10.0.15-partition_fulltext/sql/ha_partition.cc
--- ./006_mariadb-10.0.15-direct_update_rows/sql/ha_partition.cc	2014-11-29 17:01:50.121564027 +0900
+++ ./007_mariadb-10.0.15-partition_fulltext/sql/ha_partition.cc	2014-11-29 17:02:14.985796196 +0900
@@ -73,7 +73,6 @@
                                        HA_REC_NOT_IN_SEQ | \
                                        HA_CAN_REPAIR)
 #define PARTITION_DISABLED_TABLE_FLAGS (HA_CAN_GEOMETRY | \
-                                        HA_CAN_FULLTEXT | \
                                         HA_DUPLICATE_POS | \
                                         HA_CAN_INSERT_DELAYED | \
                                         HA_READ_BEFORE_WRITE_REMOVAL)
@@ -246,6 +245,8 @@ ha_partition::ha_partition(handlerton *h
   :handler(hton, share)
 {
   DBUG_ENTER("ha_partition::ha_partition(table)");
+  ft_first = NULL;
+  ft_current = NULL;
   init_alloc_root(&m_mem_root, 512, 512, MYF(0));
   init_handler_variables();
   DBUG_VOID_RETURN;
@@ -268,6 +269,8 @@ ha_partition::ha_partition(handlerton *h
 {
   DBUG_ENTER("ha_partition::ha_partition(part_info)");
   DBUG_ASSERT(part_info);
+  ft_first = NULL;
+  ft_current = NULL;
   init_alloc_root(&m_mem_root, 512, 512, MYF(0));
   init_handler_variables();
   m_part_info= part_info;
@@ -5044,6 +5047,7 @@ int ha_partition::rnd_pos(uchar * buf, u
   file= m_file[part_id];
   DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
   m_last_part= part_id;
+  ft_current_part= part_id;
   DBUG_RETURN(file->ha_rnd_pos(buf, (pos + PARTITION_BYTES_IN_POS)));
 }
 
@@ -5826,6 +5830,208 @@ int ha_partition::read_range_next()
 }
 
 
+float partition_ft_find_relevance(FT_INFO *handler, uchar *record, uint length)
+{
+  st_partition_ft_info *info = (st_partition_ft_info *) handler;
+  return info->file->ft_find_relevance(handler, record, length);
+}
+
+
+float ha_partition::ft_find_relevance(
+  FT_INFO *handler, uchar *record, uint length)
+{
+  st_partition_ft_info *info = (st_partition_ft_info *) handler;
+  FT_INFO *m_handler= info->part_ft_info[ft_current_part];
+  DBUG_ENTER("ha_partition::ft_find_relevance");
+  if (
+    m_handler &&
+    m_handler->please &&
+    m_handler->please->find_relevance
+  ) {
+    DBUG_RETURN(m_handler->please->find_relevance(
+      m_handler, record, length));
+  }
+  DBUG_RETURN((float) -1.0);
+}
+
+
+float partition_ft_get_relevance(FT_INFO *handler)
+{
+  st_partition_ft_info *info = (st_partition_ft_info *) handler;
+  return info->file->ft_get_relevance(handler);
+}
+
+
+float ha_partition::ft_get_relevance(FT_INFO *handler)
+{
+  st_partition_ft_info *info = (st_partition_ft_info *) handler;
+  FT_INFO *m_handler= info->part_ft_info[ft_current_part];
+  DBUG_ENTER("ha_partition::ft_get_relevance");
+  if (
+    m_handler &&
+    m_handler->please &&
+    m_handler->please->get_relevance
+  ) {
+    DBUG_RETURN(m_handler->please->get_relevance(m_handler));
+  }
+  DBUG_RETURN((float) -1.0);
+}
+
+
+void partition_ft_close_search(FT_INFO *handler)
+{
+  st_partition_ft_info *info = (st_partition_ft_info *) handler;
+  info->file->ft_close_search(handler);
+}
+
+
+void ha_partition::ft_close_search(FT_INFO *handler)
+{
+  uint i;
+  st_partition_ft_info *info = (st_partition_ft_info *) handler;
+  DBUG_ENTER("ha_partition::ft_close_search");
+  for (i= 0; i < m_tot_parts; i++)
+  {
+    FT_INFO *m_handler= info->part_ft_info[i];
+    if (
+      m_handler &&
+      m_handler->please &&
+      m_handler->please->close_search
+    )
+      m_handler->please->close_search(m_handler);
+  }
+  DBUG_VOID_RETURN;
+}
+
+
+_ft_vft partition_ft_vft = {
+  NULL, // partition_ft_read_next
+  partition_ft_find_relevance,
+  partition_ft_close_search,
+  partition_ft_get_relevance,
+  NULL // partition_ft_reinit_search
+};
+
+
+int ha_partition::ft_init()
+{
+  int error= 0;
+  handler **file;
+  DBUG_ENTER("ha_partition::ft_init");
+  file= m_file;
+  do
+  {
+    if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
+      if ((error= (*file)->ft_init()))
+        DBUG_RETURN(error);
+  } while (*(++file));
+  m_ordered= FALSE;
+  end_range= 0;
+  m_index_scan_type= partition_ft_read;
+  ft_init_and_first= TRUE;
+  DBUG_RETURN(0);
+}
+
+
+void ha_partition::ft_end()
+{
+  handler **file;
+  DBUG_ENTER("ha_partition::ft_end");
+  file= m_file;
+  do
+  {
+    if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
+      (*file)->ft_end();
+  } while (*(++file));
+  ft_current = NULL;
+  DBUG_VOID_RETURN;
+}
+
+
+FT_INFO *ha_partition::ft_init_ext(
+  uint flags,
+  uint inx,
+  String *key
+) {
+  FT_INFO *ft_handler;
+  handler **file;
+  st_partition_ft_info *ft_target;
+  FT_INFO **tmp_ft_info;
+  DBUG_ENTER("ha_partition::ft_init_ext");
+  if (ft_current)
+  {
+    ft_target = ft_current->next;
+    if (!ft_target)
+    {
+      if (!(ft_target = (st_partition_ft_info *)
+        my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+          &ft_target, sizeof(st_partition_ft_info),
+          &tmp_ft_info, sizeof(FT_INFO *) * m_tot_parts,
+          NullS))
+      ) {
+        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
+        DBUG_RETURN(NULL);
+      }
+      ft_target->part_ft_info = tmp_ft_info;
+      ft_current->next = ft_target;
+    }
+  } else {
+    ft_target = ft_first;
+    if (!ft_target)
+    {
+      if (!(ft_target = (st_partition_ft_info *)
+        my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+          &ft_target, sizeof(st_partition_ft_info),
+          &tmp_ft_info, sizeof(FT_INFO *) * m_tot_parts,
+          NullS))
+      ) {
+        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
+        DBUG_RETURN(NULL);
+      }
+      ft_target->part_ft_info = tmp_ft_info;
+      ft_first = ft_target;
+    }
+  }
+  ft_current = ft_target;
+  file= m_file;
+  do
+  {
+    if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
+    {
+      if ((ft_handler= (*file)->ft_init_ext(flags, inx, key)))
+        (*file)->ft_handler= ft_handler;
+      else
+        (*file)->ft_handler= NULL;
+      ft_target->part_ft_info[file - m_file]= ft_handler;
+    }
+    else {
+      (*file)->ft_handler= NULL;
+      ft_target->part_ft_info[file - m_file]= NULL;
+    }
+  } while (*(++file));
+  ft_target->please= &partition_ft_vft;
+  ft_target->file= this;
+  DBUG_RETURN((FT_INFO*) ft_target);
+}
+
+
+int ha_partition::ft_read(
+  uchar *buf
+) {
+  DBUG_ENTER("ha_partition::ft_read");
+  if (ft_init_and_first)
+  {
+    ft_init_and_first= FALSE;
+    DBUG_RETURN(common_index_read(buf, FALSE));
+  }
+  if (!m_ordered_scan_ongoing)
+  {
+    DBUG_RETURN(handle_unordered_next(buf, FALSE));
+  }
+  DBUG_RETURN(handle_ordered_next(buf, FALSE));
+}
+
+
 /*
   Common routine to set up index scans
 
@@ -5857,7 +6063,12 @@ int ha_partition::partition_scan_set_up(
   DBUG_ENTER("ha_partition::partition_scan_set_up");
 
   if (idx_read_flag)
+  {
+    if (m_index_scan_type == partition_ft_read)
+      get_partition_set(table,buf,MAX_KEY,&m_start_key,&m_part_spec);
+    else
     get_partition_set(table,buf,active_index,&m_start_key,&m_part_spec);
+  }
   else
   {
     m_part_spec.start_part= 0;
@@ -5962,6 +6173,15 @@ int ha_partition::handle_unordered_next(
       DBUG_RETURN(0);
     }
   }
+  else if (m_index_scan_type == partition_ft_read)
+  {
+    if (!(error= file->ft_read(buf)))
+    {
+      ft_current_part= m_part_spec.start_part;
+      m_last_part= m_part_spec.start_part;
+      DBUG_RETURN(0);
+    }
+  }
   else if (is_next_same)
   {
     if (!(error= file->ha_index_next_same(buf, m_start_key.key,
@@ -6030,6 +6250,11 @@ int ha_partition::handle_unordered_scan_
       error= file->read_range_first(m_start_key.key? &m_start_key: NULL,
                                     end_range, eq_range, FALSE);
       break;
+    case partition_ft_read:
+      DBUG_PRINT("info", ("ft_read on partition %d", i));
+      error= file->ft_read(buf);
+      ft_current_part= i;
+      break;
     case partition_index_read:
       DBUG_PRINT("info", ("index_read on partition %d", i));
       error= file->ha_index_read_map(buf, m_start_key.key,
@@ -6176,6 +6401,11 @@ int ha_partition::handle_ordered_index_s
       reverse_order= FALSE;
       break;
     }
+    case partition_ft_read:
+      error= file->ft_read(rec_buf_ptr);
+      ft_current_part= i;
+      reverse_order= FALSE;
+      break;
     default:
       DBUG_ASSERT(FALSE);
       DBUG_RETURN(HA_ERR_END_OF_FILE);
@@ -6367,6 +6597,11 @@ int ha_partition::handle_ordered_next(uc
     error= file->read_range_next();
     memcpy(rec_buf, table->record[0], m_rec_length);
   }
+  else if (m_index_scan_type == partition_ft_read)
+  {
+    error= file->ft_read(rec_buf);
+    ft_current_part= part_id;
+  }
   else if (!is_next_same)
     error= file->ha_index_next(rec_buf);
   else
@@ -7312,6 +7547,7 @@ int ha_partition::reset(void)
       result= tmp;
   }
   bitmap_clear_all(&m_partitions_to_reset);
+  ft_current = NULL;
   DBUG_RETURN(result);
 }
 
diff -Narup ./006_mariadb-10.0.15-direct_update_rows/sql/ha_partition.h ./007_mariadb-10.0.15-partition_fulltext/sql/ha_partition.h
--- ./006_mariadb-10.0.15-direct_update_rows/sql/ha_partition.h	2014-11-29 17:01:50.121564027 +0900
+++ ./007_mariadb-10.0.15-partition_fulltext/sql/ha_partition.h	2014-11-29 17:02:14.988421063 +0900
@@ -33,6 +33,16 @@ enum partition_keywords
 #define PARTITION_BYTES_IN_POS 2
 
 
+class ha_partition;
+struct st_partition_ft_info
+{
+  struct _ft_vft *please;
+  st_partition_ft_info *next;
+  ha_partition *file;
+  FT_INFO **part_ft_info;
+};
+
+
 /** Struct used for partition_name_hash */
 typedef struct st_part_name_def
 {
@@ -132,7 +142,8 @@ private:
     partition_index_last= 3,
     partition_index_read_last= 4,
     partition_read_range = 5,
-    partition_no_index_scan= 6
+    partition_no_index_scan= 6,
+    partition_ft_read= 7
   };
   /* Data for the partition handler */
   int  m_mode;                          // Open mode
@@ -930,7 +941,7 @@ public:
     special file for handling names of partitions, engine types.
     HA_REC_NOT_IN_SEQ is always set for partition handler since we cannot
     guarantee that the records will be returned in sequence.
-    HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_DUPLICATE_POS,
+    HA_CAN_GEOMETRY, HA_DUPLICATE_POS,
     HA_CAN_INSERT_DELAYED, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is disabled
     until further investigated.
   */
@@ -1149,14 +1160,19 @@ public:
     -------------------------------------------------------------------------
     MODULE fulltext index
     -------------------------------------------------------------------------
-    Fulltext stuff not yet.
-    -------------------------------------------------------------------------
-    virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
-    virtual FT_INFO *ft_init_ext(uint flags,uint inx,const uchar *key,
-    uint keylen)
-    { return NULL; }
-    virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
   */
+  st_partition_ft_info *ft_first;
+  st_partition_ft_info *ft_current;
+  uint ft_current_part;
+  bool ft_init_and_first;
+  virtual float ft_find_relevance(
+    FT_INFO *handler, uchar *record, uint length);
+  virtual float ft_get_relevance(FT_INFO *handler);
+  void ft_close_search(FT_INFO *handler);
+  virtual int ft_init();
+  void ft_end();
+  virtual FT_INFO *ft_init_ext(uint flags,uint inx,String *key);
+  virtual int ft_read(uchar *buf);
 
   /*
      -------------------------------------------------------------------------
