From 0a286927d937852958cf74e188895d57894200ff Mon Sep 17 00:00:00 2001
From: Kentoku SHIBA <kentokushiba@gmail.com>
Date: Sat, 24 Aug 2013 14:23:11 +0900
Subject: [PATCH] Fulltext search optimization. Discard match fields.

---
 storage/spider/ha_spider.cc            | 125 ++++++++++++++++++++-----
 storage/spider/ha_spider.h             |   2 +
 storage/spider/spd_db_conn.cc          |  17 ++--
 storage/spider/spd_db_handlersocket.cc |  51 ++++++++--
 storage/spider/spd_db_handlersocket.h  |   6 ++
 storage/spider/spd_db_include.h        |  12 ++-
 storage/spider/spd_db_mysql.cc         |  81 +++++++++++++---
 storage/spider/spd_db_mysql.h          |   6 ++
 storage/spider/spd_db_oracle.cc        |  59 +++++++++---
 storage/spider/spd_db_oracle.h         |   6 ++
 storage/spider/spd_include.h           |   1 +
 storage/spider/spd_table.cc            |  47 +++++++---
 storage/spider/spd_table.h             |   8 ++
 13 files changed, 342 insertions(+), 79 deletions(-)

diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index 6c12fa4493a..ae95e56002d 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -342,6 +342,7 @@ int ha_spider::open(
     if (!(searched_bitmap = (uchar *)
       spider_bulk_malloc(spider_current_trx, 15, MYF(MY_WME),
         &searched_bitmap, sizeof(uchar) * no_bytes_in_map(table->read_set),
+        &ft_discard_bitmap, sizeof(uchar) * no_bytes_in_map(table->read_set),
         &position_bitmap, sizeof(uchar) * no_bytes_in_map(table->read_set),
         &partition_handler_share, sizeof(SPIDER_PARTITION_HANDLER_SHARE),
         &idx_read_bitmap, sizeof(uchar) * no_bytes_in_map(table->read_set),
@@ -363,6 +364,7 @@ int ha_spider::open(
     DBUG_PRINT("info",("spider table=%p", table));
     partition_handler_share->table = table;
     partition_handler_share->searched_bitmap = NULL;
+    partition_handler_share->ft_discard_bitmap = NULL;
     partition_handler_share->idx_read_bitmap = idx_read_bitmap;
     partition_handler_share->idx_write_bitmap = idx_write_bitmap;
     partition_handler_share->rnd_read_bitmap = rnd_read_bitmap;
@@ -405,6 +407,7 @@ int ha_spider::open(
     if (!(searched_bitmap = (uchar *)
       spider_bulk_malloc(spider_current_trx, 16, MYF(MY_WME),
         &searched_bitmap, sizeof(uchar) * no_bytes_in_map(table->read_set),
+        &ft_discard_bitmap, sizeof(uchar) * no_bytes_in_map(table->read_set),
         &position_bitmap, sizeof(uchar) * no_bytes_in_map(table->read_set),
         NullS))
     ) {
@@ -1532,12 +1535,16 @@ int ha_spider::reset()
     partition_handler_share->searched_bitmap
   ) {
     if (!is_clone)
+    {
       partition_handler_share->searched_bitmap = NULL;
+      partition_handler_share->ft_discard_bitmap = NULL;
+    }
     partition_handler_share->between_flg = FALSE;
     partition_handler_share->idx_bitmap_is_set = FALSE;
     partition_handler_share->rnd_bitmap_is_set = FALSE;
   }
 #endif
+  memset(ft_discard_bitmap, 0xFF, no_bytes_in_map(table->read_set));
   if (!(tmp_trx = spider_get_trx(thd, TRUE, &error_num2)))
   {
     DBUG_PRINT("info",("spider get trx error"));
@@ -7130,25 +7137,9 @@ void ha_spider::position(
     {
       if (select_column_mode)
       {
-        int roop_count;
-        for (roop_count = 0;
-          roop_count < (int) ((table_share->fields + 7) / 8);
-          roop_count++)
-        {
-          position_bitmap[roop_count] =
-            searched_bitmap[roop_count] |
-            ((uchar *) table->read_set->bitmap)[roop_count] |
-            ((uchar *) table->write_set->bitmap)[roop_count];
-          DBUG_PRINT("info",("spider roop_count=%d", roop_count));
-          DBUG_PRINT("info",("spider position_bitmap=%d",
-            position_bitmap[roop_count]));
-          DBUG_PRINT("info",("spider searched_bitmap=%d",
-            searched_bitmap[roop_count]));
-          DBUG_PRINT("info",("spider read_set=%d",
-            ((uchar *) table->read_set->bitmap)[roop_count]));
-          DBUG_PRINT("info",("spider write_set=%d",
-            ((uchar *) table->write_set->bitmap)[roop_count]));
-        }
+        spider_db_handler *dbton_hdl =
+          dbton_handler[result_list.current->result->dbton_id];
+        dbton_hdl->copy_minimum_select_bitmap(position_bitmap);
       }
       position_bitmap_init = TRUE;
     }
@@ -7333,8 +7324,10 @@ FT_INFO *ha_spider::ft_init_ext(
   tmp_ft_info = ft_current;
   if (ft_current)
     ft_current = ft_current->next;
-  else
+  else {
     ft_current = ft_first;
+    set_ft_discard_bitmap();
+  }
 
   if (!ft_current)
   {
@@ -10508,6 +10501,87 @@ TABLE *ha_spider::get_table()
   DBUG_RETURN(table);
 }
 
+void ha_spider::set_ft_discard_bitmap()
+{
+  DBUG_ENTER("ha_spider::set_ft_discard_bitmap");
+  TABLE_LIST *table_list = spider_get_parent_table_list(this);
+  if (table_list)
+  {
+    st_select_lex *select_lex = table_list->select_lex;
+    if (select_lex && select_lex->ftfunc_list)
+    {
+      uint roop_count;
+      Field *field;
+      Item *item, *item_next;
+      Item_func_match *item_func_match;
+      Item_field *item_field;
+      {
+        List_iterator_fast<Item_func_match> fmi(*select_lex->ftfunc_list);
+        while ((item_func_match = fmi++))
+        {
+          DBUG_PRINT("info",("spider item_func_match=%p", item_func_match));
+          uint item_count = item_func_match->argument_count();
+          Item **item_list = item_func_match->arguments();
+          for (roop_count = 1; roop_count < item_count; roop_count++)
+          {
+            item_field = (Item_field *) item_list[roop_count];
+            DBUG_PRINT("info",("spider item_field=%p", item_field));
+            field = item_field->field;
+            DBUG_PRINT("info",("spider field=%p", field));
+            if (!field || !(field = field_exchange(field)))
+              continue;
+            DBUG_PRINT("info",("spider clear_bit=%u", field->field_index));
+            spider_clear_bit(ft_discard_bitmap, field->field_index);
+          }
+        }
+      }
+      item_next = ha_thd()->free_list;
+      while ((item = item_next))
+      {
+        DBUG_PRINT("info",("spider item=%p", item));
+        item_next = item->next;
+        if (item->type() != Item::FIELD_ITEM)
+          continue;
+        field = ((Item_field *) item)->field;
+        DBUG_PRINT("info",("spider field=%p", field));
+        if (!field || !(field = field_exchange(field)))
+          continue;
+        DBUG_PRINT("info",("spider field_index=%u", field->field_index));
+        if (!spider_bit_is_set(ft_discard_bitmap, field->field_index))
+        {
+          bool match_flag = FALSE;
+          List_iterator_fast<Item_func_match> fmi(*select_lex->ftfunc_list);
+          while ((item_func_match = fmi++))
+          {
+            DBUG_PRINT("info",("spider item_func_match=%p", item_func_match));
+            uint item_count = item_func_match->argument_count();
+            Item **item_list = item_func_match->arguments();
+            for (roop_count = 1; roop_count < item_count; roop_count++)
+            {
+              DBUG_PRINT("info",("spider item_list[%u]=%p", roop_count,
+                item_list[roop_count]));
+              if (item == item_list[roop_count])
+              {
+                DBUG_PRINT("info",("spider matched"));
+                match_flag = TRUE;
+                break;
+              }
+            }
+            if (match_flag)
+              break;
+          }
+          if (!match_flag)
+          {
+            DBUG_PRINT("info",("spider set_bit=%u", field->field_index));
+            spider_set_bit(ft_discard_bitmap, field->field_index);
+          }
+        }
+      }
+    }
+  }
+  DBUG_VOID_RETURN;
+}
+
 void ha_spider::set_searched_bitmap()
 {
   int roop_count;
@@ -10530,8 +10604,8 @@ void ha_spider::set_searched_bitmap()
   {
     DBUG_PRINT("info",("spider update option start"));
     Item *item;
-    List_iterator_fast<Item> fi(table->pos_in_table_list->select_lex->
-      item_list);
+    st_select_lex *select_lex = spider_get_select_lex(this);
+    List_iterator_fast<Item> fi(select_lex->item_list);
     while ((item = fi++))
     {
       if (item->type() == Item::FIELD_ITEM)
@@ -10558,6 +10632,8 @@ void ha_spider::set_clone_searched_bitmap()
   DBUG_ENTER("ha_spider::set_clone_searched_bitmap");
   memcpy(searched_bitmap, pt_clone_source_handler->searched_bitmap,
     (table_share->fields + 7) / 8);
+  memcpy(ft_discard_bitmap, pt_clone_source_handler->ft_discard_bitmap,
+    (table_share->fields + 7) / 8);
   DBUG_VOID_RETURN;
 }
 
@@ -10586,8 +10662,12 @@ void ha_spider::set_select_column_mode()
       partition_handler_share->searched_bitmap
     ) {
       if (partition_handler_share->searched_bitmap != searched_bitmap)
+      {
         memcpy(searched_bitmap, partition_handler_share->searched_bitmap,
           (table_share->fields + 7) / 8);
+        memcpy(ft_discard_bitmap, partition_handler_share->ft_discard_bitmap,
+          (table_share->fields + 7) / 8);
+      }
       partition_handler_share->between_flg = FALSE;
       DBUG_PRINT("info",("spider copy searched_bitmap"));
     } else {
@@ -10633,6 +10713,7 @@ void ha_spider::set_select_column_mode()
       if (partition_handler_share)
       {
         partition_handler_share->searched_bitmap = searched_bitmap;
+        partition_handler_share->ft_discard_bitmap = ft_discard_bitmap;
         partition_handler_share->between_flg = TRUE;
         DBUG_PRINT("info",("spider set searched_bitmap"));
       }
diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h
index d2f479f8d90..a94515278ef 100644
--- a/storage/spider/ha_spider.h
+++ b/storage/spider/ha_spider.h
@@ -92,6 +92,7 @@ public:
   SPIDER_CONDITION   *condition;
   spider_string      *blob_buff;
   uchar              *searched_bitmap;
+  uchar              *ft_discard_bitmap;
   bool               position_bitmap_init;
   uchar              *position_bitmap;
   SPIDER_POSITION    *pushed_pos;
@@ -685,6 +686,7 @@ public:
     void *info
   );
   TABLE *get_table();
+  void set_ft_discard_bitmap();
   void set_searched_bitmap();
   void set_clone_searched_bitmap();
   void set_select_column_mode();
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index adf40c3ff94..fe6fe844ce5 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -2581,16 +2581,14 @@ int spider_db_fetch_table(
     if (spider->hs_pushed_ret_fields_num == MAX_FIELDS)
     {
 #endif
+      spider_db_handler *dbton_hdl = spider->dbton_handler[row->dbton_id];
       for (
         field = table->field;
         *field;
         field++
       ) {
-        if (
-          spider_bit_is_set(spider->searched_bitmap, (*field)->field_index) |
-          bitmap_is_set(table->read_set, (*field)->field_index) |
-          bitmap_is_set(table->write_set, (*field)->field_index)
-        ) {
+        if (dbton_hdl->minimum_select_bit_is_set((*field)->field_index))
+        {
 #ifndef DBUG_OFF
           my_bitmap_map *tmp_map =
             dbug_tmp_use_all_columns(table, table->write_set);
@@ -2738,6 +2736,7 @@ int spider_db_fetch_minimum_columns(
   SPIDER_RESULT *current = (SPIDER_RESULT*) result_list->current;
   SPIDER_DB_ROW *row;
   Field **field;
+  spider_db_handler *dbton_hdl;
   DBUG_ENTER("spider_db_fetch_minimum_columns");
   if (result_list->quick_mode == 0)
   {
@@ -2776,6 +2775,7 @@ int spider_db_fetch_minimum_columns(
     spider->ft_first, spider->ft_current, row)))
     DBUG_RETURN(error_num);
 
+  dbton_hdl = spider->dbton_handler[row->dbton_id];
   for (
     field = table->field;
     *field;
@@ -2788,11 +2788,8 @@ int spider_db_fetch_minimum_columns(
       bitmap_is_set(table->read_set, (*field)->field_index)));
     DBUG_PRINT("info", ("spider write_set %u",
       bitmap_is_set(table->write_set, (*field)->field_index)));
-    if (
-      spider_bit_is_set(spider->searched_bitmap, (*field)->field_index) |
-      bitmap_is_set(table->read_set, (*field)->field_index) |
-      bitmap_is_set(table->write_set, (*field)->field_index)
-    ) {
+    if (dbton_hdl->minimum_select_bit_is_set((*field)->field_index))
+    {
       if ((
         bitmap_is_set(table->read_set, (*field)->field_index) |
         bitmap_is_set(table->write_set, (*field)->field_index)
diff --git a/storage/spider/spd_db_handlersocket.cc b/storage/spider/spd_db_handlersocket.cc
index 0c1dce876dc..1dd6eb655bd 100644
--- a/storage/spider/spd_db_handlersocket.cc
+++ b/storage/spider/spd_db_handlersocket.cc
@@ -347,7 +347,8 @@ spider_string *spider_db_hs_str_buffer::add(
   DBUG_RETURN(element);
 }
 
-spider_db_handlersocket_row::spider_db_handlersocket_row() : spider_db_row(),
+spider_db_handlersocket_row::spider_db_handlersocket_row() :
+  spider_db_row(spider_dbton_handlersocket.dbton_id),
   hs_row(NULL), field_count(0), cloned(FALSE)
 {
   DBUG_ENTER("spider_db_handlersocket_row::spider_db_handlersocket_row");
@@ -568,7 +569,7 @@ bool spider_db_handlersocket_result_buffer::check_size(
 }
 
 spider_db_handlersocket_result::spider_db_handlersocket_result(
-) : spider_db_result()
+) : spider_db_result(spider_dbton_handlersocket.dbton_id)
 {
   DBUG_ENTER("spider_db_handlersocket_result::spider_db_handlersocket_result");
   DBUG_PRINT("info",("spider this=%p", this));
@@ -3943,11 +3944,8 @@ int spider_handlersocket_handler::append_minimum_select_without_quote(
   DBUG_ENTER("spider_handlersocket_handler::append_minimum_select_without_quote");
   for (field = table->field; *field; field++)
   {
-    if (
-      spider_bit_is_set(spider->searched_bitmap, (*field)->field_index) |
-      bitmap_is_set(table->read_set, (*field)->field_index) |
-      bitmap_is_set(table->write_set, (*field)->field_index)
-    ) {
+    if (minimum_select_bit_is_set((*field)->field_index))
+    {
       field_length =
         handlersocket_share->column_name_str[(*field)->field_index].length();
       if (str->reserve(field_length + SPIDER_SQL_COMMA_LEN))
@@ -5305,4 +5303,43 @@ bool spider_handlersocket_handler::support_use_handler(
   DBUG_PRINT("info",("spider this=%p", this));
   DBUG_RETURN(TRUE);
 }
+
+bool spider_handlersocket_handler::minimum_select_bit_is_set(
+  uint field_index
+) {
+  TABLE *table = spider->get_table();
+  DBUG_ENTER("spider_handlersocket_handler::minimum_select_bit_is_set");
+  DBUG_RETURN(
+    spider_bit_is_set(spider->searched_bitmap, field_index) |
+    bitmap_is_set(table->read_set, field_index) |
+    bitmap_is_set(table->write_set, field_index)
+  );
+}
+
+void spider_handlersocket_handler::copy_minimum_select_bitmap(
+  uchar *bitmap
+) {
+  int roop_count;
+  TABLE *table = spider->get_table();
+  DBUG_ENTER("spider_handlersocket_handler::copy_minimum_select_bitmap");
+  for (roop_count = 0;
+    roop_count < (int) ((table->s->fields + 7) / 8);
+    roop_count++)
+  {
+    bitmap[roop_count] =
+      spider->searched_bitmap[roop_count] |
+      ((uchar *) table->read_set->bitmap)[roop_count] |
+      ((uchar *) table->write_set->bitmap)[roop_count];
+    DBUG_PRINT("info",("spider roop_count=%d", roop_count));
+    DBUG_PRINT("info",("spider bitmap=%d",
+      bitmap[roop_count]));
+    DBUG_PRINT("info",("spider searched_bitmap=%d",
+      spider->searched_bitmap[roop_count]));
+    DBUG_PRINT("info",("spider read_set=%d",
+      ((uchar *) table->read_set->bitmap)[roop_count]));
+    DBUG_PRINT("info",("spider write_set=%d",
+      ((uchar *) table->write_set->bitmap)[roop_count]));
+  }
+  DBUG_VOID_RETURN;
+}
 #endif
diff --git a/storage/spider/spd_db_handlersocket.h b/storage/spider/spd_db_handlersocket.h
index f516e1ef101..147d45e93e6 100644
--- a/storage/spider/spd_db_handlersocket.h
+++ b/storage/spider/spd_db_handlersocket.h
@@ -890,4 +890,10 @@ public:
   bool support_use_handler(
     int use_handler
   );
+  bool minimum_select_bit_is_set(
+    uint field_index
+  );
+  void copy_minimum_select_bitmap(
+    uchar *bitmap
+  );
 };
diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h
index e2b3a2c95fe..cbe55f0608b 100644
--- a/storage/spider/spd_db_include.h
+++ b/storage/spider/spd_db_include.h
@@ -653,8 +653,9 @@ public:
 class spider_db_row
 {
 public:
+  uint dbton_id;
   SPIDER_DB_ROW *next_pos;
-  spider_db_row() : next_pos(NULL) {}
+  spider_db_row(uint in_dbton_id) : dbton_id(in_dbton_id), next_pos(NULL) {}
   virtual ~spider_db_row() {}
   virtual int store_to_field(
     Field *field,
@@ -693,7 +694,8 @@ public:
 class spider_db_result
 {
 public:
-  spider_db_result() {}
+  uint dbton_id;
+  spider_db_result(uint in_dbton_id) : dbton_id(in_dbton_id) {}
   virtual ~spider_db_result() {}
   virtual bool has_result() = 0;
   virtual void free_result() = 0;
@@ -1344,6 +1346,12 @@ public:
   virtual bool support_use_handler(
     int use_handler
   ) = 0;
+  virtual bool minimum_select_bit_is_set(
+    uint field_index
+  ) = 0;
+  virtual void copy_minimum_select_bitmap(
+    uchar *bitmap
+  ) = 0;
 };
 
 class spider_db_copy_table
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index d17de6cd32e..fd61b9f966d 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -210,7 +210,8 @@ SPIDER_DBTON spider_dbton_mysql = {
   &spider_db_mysql_utility
 };
 
-spider_db_mysql_row::spider_db_mysql_row() : spider_db_row(),
+spider_db_mysql_row::spider_db_mysql_row() :
+  spider_db_row(spider_dbton_mysql.dbton_id),
   row(NULL), lengths(NULL), cloned(FALSE)
 {
   DBUG_ENTER("spider_db_mysql_row::spider_db_mysql_row");
@@ -426,7 +427,8 @@ int spider_db_mysql_row::store_to_tmp_table(
   DBUG_RETURN(tmp_table->file->ha_write_row(tmp_table->record[0]));
 }
 
-spider_db_mysql_result::spider_db_mysql_result() : spider_db_result(),
+spider_db_mysql_result::spider_db_mysql_result() :
+  spider_db_result(spider_dbton_mysql.dbton_id),
   db_result(NULL)
 {
   DBUG_ENTER("spider_db_mysql_result::spider_db_mysql_result");
@@ -5701,11 +5703,8 @@ int spider_mysql_handler::append_minimum_select(
   DBUG_ENTER("spider_mysql_handler::append_minimum_select");
   for (field = table->field; *field; field++)
   {
-    if (
-      spider_bit_is_set(spider->searched_bitmap, (*field)->field_index) |
-      bitmap_is_set(table->read_set, (*field)->field_index) |
-      bitmap_is_set(table->write_set, (*field)->field_index)
-    ) {
+    if (minimum_select_bit_is_set((*field)->field_index))
+    {
       field_length =
         mysql_share->column_name_str[(*field)->field_index].length();
       if (str->reserve(field_length +
@@ -5789,11 +5788,8 @@ int spider_mysql_handler::append_minimum_select_with_alias(
   DBUG_ENTER("spider_mysql_handler::append_minimum_select_with_alias");
   for (field = table->field; *field; field++)
   {
-    if (
-      spider_bit_is_set(spider->searched_bitmap, (*field)->field_index) |
-      bitmap_is_set(table->read_set, (*field)->field_index) |
-      bitmap_is_set(table->write_set, (*field)->field_index)
-    ) {
+    if (minimum_select_bit_is_set((*field)->field_index))
+    {
       field_length =
         mysql_share->column_name_str[(*field)->field_index].length();
       if (str->reserve(alias_length + field_length +
@@ -10309,6 +10305,67 @@ bool spider_mysql_handler::support_use_handler(
   DBUG_RETURN(TRUE);
 }
 
+bool spider_mysql_handler::minimum_select_bit_is_set(
+  uint field_index
+) {
+  TABLE *table = spider->get_table();
+  DBUG_ENTER("spider_mysql_handler::minimum_select_bit_is_set");
+  DBUG_PRINT("info",("spider this=%p", this));
+  DBUG_PRINT("info",("spider field_index=%u", field_index));
+  DBUG_PRINT("info",("spider ft_discard_bitmap=%s",
+    spider_bit_is_set(spider->ft_discard_bitmap, field_index) ?
+      "TRUE" : "FALSE"));
+  DBUG_PRINT("info",("spider searched_bitmap=%s",
+    spider_bit_is_set(spider->searched_bitmap, field_index) ?
+      "TRUE" : "FALSE"));
+  DBUG_PRINT("info",("spider read_set=%s",
+    bitmap_is_set(table->read_set, field_index) ?
+      "TRUE" : "FALSE"));
+  DBUG_PRINT("info",("spider write_set=%s",
+    bitmap_is_set(table->write_set, field_index) ?
+      "TRUE" : "FALSE"));
+  DBUG_RETURN(
+    spider_bit_is_set(spider->ft_discard_bitmap, field_index) &
+    (
+      spider_bit_is_set(spider->searched_bitmap, field_index) |
+      bitmap_is_set(table->read_set, field_index) |
+      bitmap_is_set(table->write_set, field_index)
+    )
+  );
+}
+
+void spider_mysql_handler::copy_minimum_select_bitmap(
+  uchar *bitmap
+) {
+  int roop_count;
+  TABLE *table = spider->get_table();
+  DBUG_ENTER("spider_mysql_handler::copy_minimum_select_bitmap");
+  for (roop_count = 0;
+    roop_count < (int) ((table->s->fields + 7) / 8);
+    roop_count++)
+  {
+    bitmap[roop_count] =
+      spider->ft_discard_bitmap[roop_count] &
+      (
+        spider->searched_bitmap[roop_count] |
+        ((uchar *) table->read_set->bitmap)[roop_count] |
+        ((uchar *) table->write_set->bitmap)[roop_count]
+      );
+    DBUG_PRINT("info",("spider roop_count=%d", roop_count));
+    DBUG_PRINT("info",("spider bitmap=%d",
+      bitmap[roop_count]));
+    DBUG_PRINT("info",("spider ft_discard_bitmap=%d",
+      spider->ft_discard_bitmap[roop_count]));
+    DBUG_PRINT("info",("spider searched_bitmap=%d",
+      spider->searched_bitmap[roop_count]));
+    DBUG_PRINT("info",("spider read_set=%d",
+      ((uchar *) table->read_set->bitmap)[roop_count]));
+    DBUG_PRINT("info",("spider write_set=%d",
+      ((uchar *) table->write_set->bitmap)[roop_count]));
+  }
+  DBUG_VOID_RETURN;
+}
+
 spider_mysql_copy_table::spider_mysql_copy_table(
   spider_mysql_share *db_share
 ) : spider_db_copy_table(
diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h
index 761537ba0a0..b24313b8d10 100644
--- a/storage/spider/spd_db_mysql.h
+++ b/storage/spider/spd_db_mysql.h
@@ -1211,6 +1211,12 @@ public:
   bool support_use_handler(
     int use_handler
   );
+  bool minimum_select_bit_is_set(
+    uint field_index
+  );
+  void copy_minimum_select_bitmap(
+    uchar *bitmap
+  );
 };
 
 class spider_mysql_copy_table: public spider_db_copy_table
diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc
index 7c40b3a4477..6c12ec49b6a 100644
--- a/storage/spider/spd_db_oracle.cc
+++ b/storage/spider/spd_db_oracle.cc
@@ -318,7 +318,8 @@ SPIDER_DBTON spider_dbton_oracle = {
   &spider_db_oracle_utility
 };
 
-spider_db_oracle_row::spider_db_oracle_row() : spider_db_row(),
+spider_db_oracle_row::spider_db_oracle_row() :
+  spider_db_row(spider_dbton_oracle.dbton_id),
   db_conn(NULL), result(NULL),
   ind(NULL), val(NULL), rlen(NULL), ind_first(NULL), val_first(NULL),
   rlen_first(NULL), val_str(NULL), val_str_first(NULL), defnp(NULL),
@@ -720,7 +721,8 @@ int spider_db_oracle_row::fetch()
   DBUG_RETURN(0);
 }
 
-spider_db_oracle_result::spider_db_oracle_result() : spider_db_result(),
+spider_db_oracle_result::spider_db_oracle_result() :
+  spider_db_result(spider_dbton_oracle.dbton_id),
   db_conn(NULL), stmtp(NULL), field_count(0), access_charset(NULL),
   fetched(FALSE)
 {
@@ -5770,11 +5772,8 @@ int spider_oracle_handler::append_minimum_select(
   DBUG_ENTER("spider_oracle_handler::append_minimum_select");
   for (field = table->field; *field; field++)
   {
-    if (
-      spider_bit_is_set(spider->searched_bitmap, (*field)->field_index) |
-      bitmap_is_set(table->read_set, (*field)->field_index) |
-      bitmap_is_set(table->write_set, (*field)->field_index)
-    ) {
+    if (minimum_select_bit_is_set((*field)->field_index))
+    {
       field_length =
         oracle_share->column_name_str[(*field)->field_index].length();
       if (str->reserve(field_length +
@@ -5858,11 +5857,8 @@ int spider_oracle_handler::append_minimum_select_with_alias(
   DBUG_ENTER("spider_oracle_handler::append_minimum_select_with_alias");
   for (field = table->field; *field; field++)
   {
-    if (
-      spider_bit_is_set(spider->searched_bitmap, (*field)->field_index) |
-      bitmap_is_set(table->read_set, (*field)->field_index) |
-      bitmap_is_set(table->write_set, (*field)->field_index)
-    ) {
+    if (minimum_select_bit_is_set((*field)->field_index))
+    {
       field_length =
         oracle_share->column_name_str[(*field)->field_index].length();
       if (str->reserve(alias_length + field_length +
@@ -10992,6 +10988,45 @@ bool spider_oracle_handler::support_use_handler(
   DBUG_RETURN(FALSE);
 }
 
+bool spider_oracle_handler::minimum_select_bit_is_set(
+  uint field_index
+) {
+  TABLE *table = spider->get_table();
+  DBUG_ENTER("spider_oracle_handler::minimum_select_bit_is_set");
+  DBUG_RETURN(
+    spider_bit_is_set(spider->searched_bitmap, field_index) |
+    bitmap_is_set(table->read_set, field_index) |
+    bitmap_is_set(table->write_set, field_index)
+  );
+}
+
+void spider_oracle_handler::copy_minimum_select_bitmap(
+  uchar *bitmap
+) {
+  int roop_count;
+  TABLE *table = spider->get_table();
+  DBUG_ENTER("spider_oracle_handler::copy_minimum_select_bitmap");
+  for (roop_count = 0;
+    roop_count < (int) ((table->s->fields + 7) / 8);
+    roop_count++)
+  {
+    bitmap[roop_count] =
+      spider->searched_bitmap[roop_count] |
+      ((uchar *) table->read_set->bitmap)[roop_count] |
+      ((uchar *) table->write_set->bitmap)[roop_count];
+    DBUG_PRINT("info",("spider roop_count=%d", roop_count));
+    DBUG_PRINT("info",("spider bitmap=%d",
+      bitmap[roop_count]));
+    DBUG_PRINT("info",("spider searched_bitmap=%d",
+      spider->searched_bitmap[roop_count]));
+    DBUG_PRINT("info",("spider read_set=%d",
+      ((uchar *) table->read_set->bitmap)[roop_count]));
+    DBUG_PRINT("info",("spider write_set=%d",
+      ((uchar *) table->write_set->bitmap)[roop_count]));
+  }
+  DBUG_VOID_RETURN;
+}
+
 spider_oracle_copy_table::spider_oracle_copy_table(
   spider_oracle_share *db_share
 ) : spider_db_copy_table(
diff --git a/storage/spider/spd_db_oracle.h b/storage/spider/spd_db_oracle.h
index e6ebb90f601..3b9335dff46 100644
--- a/storage/spider/spd_db_oracle.h
+++ b/storage/spider/spd_db_oracle.h
@@ -1297,6 +1297,12 @@ public:
   bool support_use_handler(
     int use_handler
   );
+  bool minimum_select_bit_is_set(
+    uint field_index
+  );
+  void copy_minimum_select_bitmap(
+    uchar *bitmap
+  );
 };
 
 class spider_oracle_copy_table: public spider_db_copy_table
diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h
index 4340339ac57..88f8aa1726f 100644
--- a/storage/spider/spd_include.h
+++ b/storage/spider/spd_include.h
@@ -388,6 +388,7 @@ typedef struct st_spider_patition_handler_share
   void               *creator;
   void               **handlers;
   uchar              *searched_bitmap;
+  uchar              *ft_discard_bitmap;
   uchar              *idx_read_bitmap;
   uchar              *idx_write_bitmap;
   uchar              *rnd_read_bitmap;
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index 40704f74437..c984af58f12 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -7309,30 +7309,49 @@ void spider_free_tmp_dbton_handler(
   DBUG_VOID_RETURN;
 }
 
+TABLE_LIST *spider_get_parent_table_list(
+  ha_spider *spider
+) {
+  TABLE *table = spider->get_table();
+  TABLE_LIST *table_list = table->pos_in_table_list;
+  DBUG_ENTER("spider_get_parent_table_list");
+  if (table_list)
+  {
+    while (table_list->parent_l)
+      table_list = table_list->parent_l;
+    DBUG_RETURN(table_list);
+  }
+  DBUG_RETURN(NULL);
+}
+
+st_select_lex *spider_get_select_lex(
+  ha_spider *spider
+) {
+  TABLE_LIST *table_list = spider_get_parent_table_list(spider);
+  DBUG_ENTER("spider_get_select_lex");
+  if (table_list)
+  {
+    DBUG_RETURN(table_list->select_lex);
+  }
+  DBUG_RETURN(NULL);
+}
+
 void spider_get_select_limit(
   ha_spider *spider,
   st_select_lex **select_lex,
   longlong *select_limit,
   longlong *offset_limit
 ) {
-  TABLE *table = spider->get_table();
-  TABLE_LIST *table_list = table->pos_in_table_list;
   DBUG_ENTER("spider_get_select_limit");
-  *select_lex = NULL;
+  *select_lex = spider_get_select_lex(spider);
   *select_limit = 9223372036854775807LL;
   *offset_limit = 0;
-  if (table_list)
+  if (*select_lex && (*select_lex)->explicit_limit)
   {
-    while (table_list->parent_l)
-      table_list = table_list->parent_l;
-    *select_lex = table_list->select_lex;
-    if (*select_lex && (*select_lex)->explicit_limit)
-    {
-      *select_limit = (*select_lex)->select_limit ?
-        (*select_lex)->select_limit->val_int() : 0;
-      *offset_limit = (*select_lex)->offset_limit ?
-        (*select_lex)->offset_limit->val_int() : 0;
-    }
+    *select_limit = (*select_lex)->select_limit ?
+      (*select_lex)->select_limit->val_int() : 0;
+    *offset_limit = (*select_lex)->offset_limit ?
+      (*select_lex)->offset_limit->val_int() : 0;
   }
   DBUG_VOID_RETURN;
 }
diff --git a/storage/spider/spd_table.h b/storage/spider/spd_table.h
index 7a0732276dc..ea5f50bd98a 100644
--- a/storage/spider/spd_table.h
+++ b/storage/spider/spd_table.h
@@ -355,6 +355,14 @@ void spider_free_tmp_dbton_handler(
   ha_spider *tmp_spider
 );
 
+TABLE_LIST *spider_get_parent_table_list(
+  ha_spider *spider
+);
+
+st_select_lex *spider_get_select_lex(
+  ha_spider *spider
+);
+
 void spider_get_select_limit(
   ha_spider *spider,
   st_select_lex **select_lex,