diff -Nurd mysql-4.1.22.senna/include/my_pthread.h mysql-4.1.22.senna.2ind/include/my_pthread.h
--- mysql-4.1.22.senna/include/my_pthread.h	2006-11-03 11:15:38.000000000 +0900
+++ mysql-4.1.22.senna.2ind/include/my_pthread.h	2007-03-24 12:54:40.852997000 +0900
@@ -665,6 +665,9 @@
   gptr dbug;
   char name[THREAD_NAME_SIZE+1];
 #endif
+#ifdef ENABLE_SENNA
+  int sen_flags;
+#endif /* ENABLE_SENNA */
 };
 
 extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
diff -Nurd mysql-4.1.22.senna/libmysqld/filesort.cc mysql-4.1.22.senna.2ind/libmysqld/filesort.cc
--- mysql-4.1.22.senna/libmysqld/filesort.cc	2006-11-03 11:15:57.000000000 +0900
+++ mysql-4.1.22.senna.2ind/libmysqld/filesort.cc	2007-03-24 12:54:40.864306000 +0900
@@ -1145,6 +1145,9 @@
       }
       if (sortorder->field->maybe_null())
 	length++;				// Place for NULL marker
+#ifdef ENABLE_SENNA
+      my_thread_var->sen_flags |= 2;
+#endif /* ENABLE_SENNA */
     }
     else
     {
diff -Nurd mysql-4.1.22.senna/libmysqld/item_cmpfunc.cc mysql-4.1.22.senna.2ind/libmysqld/item_cmpfunc.cc
--- mysql-4.1.22.senna/libmysqld/item_cmpfunc.cc	2006-11-03 11:16:54.000000000 +0900
+++ mysql-4.1.22.senna.2ind/libmysqld/item_cmpfunc.cc	2007-03-24 12:54:40.873841000 +0900
@@ -2246,6 +2246,22 @@
   }
 }
 
+#ifdef ENABLE_SENNA
+bool 
+Item_cond::needs_record()
+{
+  List_iterator_fast<Item> li(list);
+  Item *item;
+  while ((item=li++))
+  {
+    if (item->needs_record())
+    {
+      return true;
+    }
+  }
+  return false;
+}
+#endif /* ENABLE_SENNA */
 
 /*
   Evalution of AND(expr, expr, expr ...)
diff -Nurd mysql-4.1.22.senna/libmysqld/item_func.cc mysql-4.1.22.senna.2ind/libmysqld/item_func.cc
--- mysql-4.1.22.senna/libmysqld/item_func.cc	2006-11-03 11:17:25.000000000 +0900
+++ mysql-4.1.22.senna.2ind/libmysqld/item_func.cc	2007-03-24 12:54:40.884259000 +0900
@@ -3151,7 +3151,11 @@
   for (keynr=0 ; keynr < table->keys ; keynr++)
   {
     if ((table->key_info[keynr].flags & HA_FULLTEXT) &&
-        (table->keys_in_use_for_query.is_set(keynr)))
+        ((table->keys_in_use_for_query.is_set(keynr))
+#ifdef ENABLE_SENNA
+	 || my_thread_var->sen_flags
+#endif /* ENABLE_SENNA */
+	 ))
     {
       ft_to_key[fts]=keynr;
       ft_cnt[fts]=0;
diff -Nurd mysql-4.1.22.senna/libmysqld/item_sum.cc mysql-4.1.22.senna.2ind/libmysqld/item_sum.cc
--- mysql-4.1.22.senna/libmysqld/item_sum.cc	2006-11-03 11:17:16.000000000 +0900
+++ mysql-4.1.22.senna.2ind/libmysqld/item_sum.cc	2007-03-24 12:54:40.896138000 +0900
@@ -1200,6 +1200,9 @@
     return 1;
 
   /* Create a table with an unique key over all parameters */
+#ifdef ENABLE_SENNA
+  my_thread_var->sen_flags |= 16;
+#endif /* ENABLE_SENNA */
   for (uint i=0; i < arg_count ; i++)
   {
     Item *item=args[i];
diff -Nurd mysql-4.1.22.senna/libmysqld/records.cc mysql-4.1.22.senna.2ind/libmysqld/records.cc
--- mysql-4.1.22.senna/libmysqld/records.cc	2006-11-03 11:16:13.000000000 +0900
+++ mysql-4.1.22.senna.2ind/libmysqld/records.cc	2007-03-24 12:54:40.899149000 +0900
@@ -159,6 +159,9 @@
                     table->sort.found_records*info->ref_length;
     info->read_record= (table->sort.addon_field ?
                         rr_unpack_from_buffer : rr_from_pointers);
+#ifdef ENABLE_SENNA
+    my_thread_var->sen_flags |= 4;
+#endif /* ENABLE_SENNA */
   }
   else
   {
@@ -315,6 +318,9 @@
   {
     if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
       return -1;					/* End of file */
+#ifdef ENABLE_SENNA
+    if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) { return 0; }
+#endif /* ENABLE_SENNA */
     if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos)))
       break;
     /* The following is extremely unlikely to happen */
@@ -368,6 +374,9 @@
     cache_pos= info->cache_pos;
     info->cache_pos+= info->ref_length;
 
+#ifdef ENABLE_SENNA
+    if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) { return 0; }
+#endif /* ENABLE_SENNA */
     if (!(tmp=info->file->rnd_pos(info->record,cache_pos)))
       break;
 
diff -Nurd mysql-4.1.22.senna/libmysqld/sql_select.cc mysql-4.1.22.senna.2ind/libmysqld/sql_select.cc
--- mysql-4.1.22.senna/libmysqld/sql_select.cc	2006-11-03 11:15:07.000000000 +0900
+++ mysql-4.1.22.senna.2ind/libmysqld/sql_select.cc	2007-03-24 12:54:40.952945000 +0900
@@ -1125,6 +1125,10 @@
   int      tmp_error;
   DBUG_ENTER("JOIN::exec");
   
+#ifdef ENABLE_SENNA
+  my_thread_var->sen_flags |= 32;
+#endif /* ENABLE_SENNA */
+
   error= 0;
   if (procedure)
   {
@@ -1589,6 +1593,9 @@
   }
   curr_join->having= curr_join->tmp_having;
   thd->proc_info="Sending data";
+#ifdef ENABLE_SENNA
+  my_thread_var->sen_flags &= ~32;
+#endif /* ENABLE_SENNA */
   error= thd->net.report_error ? -1 :
     do_select(curr_join, curr_fields_list, NULL, procedure);
   thd->limit_found_rows= curr_join->send_records;
@@ -1698,7 +1705,10 @@
       goto err;
     }
   }
-
+#ifdef ENABLE_SENNA
+  my_thread_var->sen_flags = select_lex->ftfunc_list->elements ? 1 : 0;
+  if (join->select_distinct) { my_thread_var->sen_flags |= 16; }
+#endif /* ENABLE_SENNA */
   if ((err= join->optimize()))
   {
     goto err;					// 1
@@ -2673,7 +2683,11 @@
   for ( ; field != end ; field++)
     add_key_part(keyuse,field);
 
-  if (select_lex->ftfunc_list->elements)
+  if (select_lex->ftfunc_list->elements
+#ifdef ENABLE_SENNA
+      && !join_tab->table->force_index
+#endif /* ENABLE_SENNA */
+      )
   {
     add_ft_keys(keyuse,join_tab,cond,normal_tables);
   }
@@ -3993,6 +4007,9 @@
       table->status=STATUS_NO_RECORD;
       tab->read_first_record= join_ft_read_first;
       tab->read_record.read_record= join_ft_read_next;
+#ifdef ENABLE_SENNA
+      my_thread_var->sen_flags |= 4;
+#endif /* ENABLE_SENNA */
       break;
     case JT_ALL:
       /*
@@ -6177,10 +6194,27 @@
   return sub_select(join,join_tab,end_of_records); /* Use ordinary select */
 }
 
+#ifdef ENABLE_SENNA
+static void
+decide_read_or_skip(JOIN *join,JOIN_TAB *join_tab,bool needs_record)
+{
+  if (needs_record || (my_thread_var->sen_flags & 48) ||
+      (join_tab->next_select != end_send_group &&
+       !join->unit->offset_limit_cnt && 
+       join->send_records < join->unit->select_limit_cnt)) {
+    my_thread_var->sen_flags |= 8;
+  } else {
+    my_thread_var->sen_flags &= ~8;
+  }
+}
+#endif /* ENABLE_SENNA */
 
 static int
 sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
 {
+#ifdef ENABLE_SENNA
+  if (join_tab->next_select == end_update) { my_thread_var->sen_flags &= ~4; }
+#endif /* ENABLE_SENNA */
 
   join_tab->table->null_row=0;
   if (end_of_records)
@@ -6191,7 +6225,11 @@
   bool found=0;
   COND *on_expr=join_tab->on_expr, *select_cond=join_tab->select_cond;
   my_bool *report_error= &(join->thd->net.report_error);
-
+#ifdef ENABLE_SENNA
+  bool needs_record = select_cond ? select_cond->needs_record() : false;
+ 
+  decide_read_or_skip(join, join_tab, needs_record);
+#endif /* ENABLE_SENNA */
   if (!(error=(*join_tab->read_first_record)(join_tab)))
   {
     bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize;
@@ -6238,6 +6276,9 @@
           */
 	  info->file->unlock_row();
         }
+#ifdef ENABLE_SENNA
+	decide_read_or_skip(join, join_tab, needs_record);
+#endif /* ENABLE_SENNA */
       }
     } while (!(error=info->read_record(info)) && !(*report_error));
   }
@@ -6658,7 +6699,14 @@
   tab->read_record.record=table->record[0];
   if (!table->file->inited)
     table->file->ha_index_init(tab->index);
-  if ((error=tab->table->file->index_first(tab->table->record[0])))
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & 1) { my_thread_var->sen_flags |= 4; }
+  if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) {
+    error=tab->table->file->index_first(NULL);
+  } else
+#endif /* ENABLE_SENNA */
+    error=tab->table->file->index_first(tab->table->record[0]);
+  if (error)
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
       report_error(table, error);
@@ -6672,7 +6720,13 @@
 join_read_next(READ_RECORD *info)
 {
   int error;
-  if ((error=info->file->index_next(info->record)))
+#ifdef ENABLE_SENNA
+  if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) {
+    error=info->file->index_next(NULL);
+  } else
+#endif /* ENABLE_SENNA */
+    error=info->file->index_next(info->record);
+  if (error)
     return report_error(info->table, error);
   return 0;
 }
@@ -6697,7 +6751,14 @@
   tab->read_record.record=table->record[0];
   if (!table->file->inited)
     table->file->ha_index_init(tab->index);
-  if ((error= tab->table->file->index_last(tab->table->record[0])))
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & 1) { my_thread_var->sen_flags |= 4; }
+  if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) {
+    error=tab->table->file->index_last(NULL);
+  } else
+#endif /* ENABLE_SENNA */
+    error=tab->table->file->index_last(tab->table->record[0]);
+  if (error)
     return report_error(table, error);
   return 0;
 }
@@ -6707,7 +6768,13 @@
 join_read_prev(READ_RECORD *info)
 {
   int error;
-  if ((error= info->file->index_prev(info->record)))
+#ifdef ENABLE_SENNA
+  if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) {
+    error=info->file->index_prev(NULL);
+  } else
+#endif /* ENABLE_SENNA */
+    error=info->file->index_prev(info->record);
+  if (error)
     return report_error(info->table, error);
   return 0;
 }
@@ -6721,6 +6788,9 @@
 
   if (!table->file->inited)
     table->file->ha_index_init(tab->ref.key);
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & 1) { my_thread_var->sen_flags |= 4; }
+#endif /* ENABLE_SENNA */
 #if NOT_USED_YET
   if (cp_buffer_from_ref(tab->join->thd, &tab->ref)) // as ft-key doesn't use store_key's
     return -1;                             // see also FT_SELECT::init()
@@ -7924,6 +7994,11 @@
   table=  tab->table;
   select= tab->select;
 
+#ifdef ENABLE_SENNA
+  if (tab->select_cond && tab->select_cond->needs_record()) {
+    my_thread_var->sen_flags |= 8;
+  }
+#endif /* ENABLE_SENNA */
   if (test_if_skip_sort_order(tab,order,select_limit,0))
     DBUG_RETURN(0);
   if (!(sortorder=make_unireg_sortorder(order,&length)))
diff -Nurd mysql-4.1.22.senna/myisam/ft_boolean_search.c mysql-4.1.22.senna.2ind/myisam/ft_boolean_search.c
--- mysql-4.1.22.senna/myisam/ft_boolean_search.c	2007-03-24 12:53:40.474268000 +0900
+++ mysql-4.1.22.senna.2ind/myisam/ft_boolean_search.c	2007-03-24 12:54:40.971887000 +0900
@@ -576,6 +576,7 @@
     while (ftb->sir && sen_records_next(ftb->sir, &pos, sizeof(my_off_t), NULL)) {
       info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
       info->lastpos=pos;
+      if (!(my_thread_var->sen_flags & (8|2))) { return 0; }
       if (!(*info->read_record)(info,info->lastpos,record)) {
         info->update|= HA_STATE_AKTIV;          /* Record is read */
         return 0;
diff -Nurd mysql-4.1.22.senna/myisam/ft_nlq_search.c mysql-4.1.22.senna.2ind/myisam/ft_nlq_search.c
--- mysql-4.1.22.senna/myisam/ft_nlq_search.c	2007-03-24 12:53:40.480132000 +0900
+++ mysql-4.1.22.senna.2ind/myisam/ft_nlq_search.c	2007-03-24 12:54:40.973008000 +0900
@@ -325,6 +325,7 @@
     while (sen_records_next(handler->sir, &pos, sizeof(my_off_t), NULL))
     {
       info->lastpos=pos;
+      if (!(my_thread_var->sen_flags & (8|2))) { return 0; }
       if (!(*info->read_record)(info,info->lastpos,record))
       {
 	info->update|= HA_STATE_AKTIV;		/* Record is read */
diff -Nurd mysql-4.1.22.senna/sql/filesort.cc mysql-4.1.22.senna.2ind/sql/filesort.cc
--- mysql-4.1.22.senna/sql/filesort.cc	2006-11-03 11:15:57.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/filesort.cc	2007-03-24 12:54:40.987426000 +0900
@@ -1145,6 +1145,9 @@
       }
       if (sortorder->field->maybe_null())
 	length++;				// Place for NULL marker
+#ifdef ENABLE_SENNA
+      my_thread_var->sen_flags |= 2;
+#endif /* ENABLE_SENNA */
     }
     else
     {
diff -Nurd mysql-4.1.22.senna/sql/item.h mysql-4.1.22.senna.2ind/sql/item.h
--- mysql-4.1.22.senna/sql/item.h	2006-11-03 11:17:10.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/item.h	2007-03-24 13:00:01.553776000 +0900
@@ -275,7 +275,9 @@
     Any new item which can be NULL must implement this call.
   */
   virtual bool is_null() { return 0; }
-
+#ifdef ENABLE_SENNA
+  virtual bool needs_record() { return true; }
+#endif /* ENABLE_SENNA */
   /*
     Inform the item that there will be no distinction between its result
     being FALSE or NULL.
diff -Nurd mysql-4.1.22.senna/sql/item.h.rej mysql-4.1.22.senna.2ind/sql/item.h.rej
--- mysql-4.1.22.senna/sql/item.h.rej	1970-01-01 09:00:00.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/item.h.rej	2007-03-24 12:54:40.993545000 +0900
@@ -0,0 +1,18 @@
+***************
+*** 275,280 ****
+      Any new item which can be NULL must implement this call.
+    */
+    virtual bool is_null() { return 0; }
+    /*
+      it is "top level" item of WHERE clause and we do not need correct NULL
+      handling
+--- 275,283 ----
+      Any new item which can be NULL must implement this call.
+    */
+    virtual bool is_null() { return 0; }
++ #ifdef ENABLE_SENNA
++   virtual bool needs_record() { return true; }
++ #endif /* ENABLE_SENNA */
+    /*
+      it is "top level" item of WHERE clause and we do not need correct NULL
+      handling
diff -Nurd mysql-4.1.22.senna/sql/item_cmpfunc.cc mysql-4.1.22.senna.2ind/sql/item_cmpfunc.cc
--- mysql-4.1.22.senna/sql/item_cmpfunc.cc	2006-11-03 11:16:54.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/item_cmpfunc.cc	2007-03-24 12:54:41.008369000 +0900
@@ -2246,6 +2246,22 @@
   }
 }
 
+#ifdef ENABLE_SENNA
+bool 
+Item_cond::needs_record()
+{
+  List_iterator_fast<Item> li(list);
+  Item *item;
+  while ((item=li++))
+  {
+    if (item->needs_record())
+    {
+      return true;
+    }
+  }
+  return false;
+}
+#endif /* ENABLE_SENNA */
 
 /*
   Evalution of AND(expr, expr, expr ...)
diff -Nurd mysql-4.1.22.senna/sql/item_cmpfunc.h mysql-4.1.22.senna.2ind/sql/item_cmpfunc.h
--- mysql-4.1.22.senna/sql/item_cmpfunc.h	2006-11-03 11:17:24.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/item_cmpfunc.h	2007-03-24 12:54:41.010375000 +0900
@@ -992,6 +992,9 @@
   bool add(Item *item) { return list.push_back(item); }
   bool fix_fields(THD *, struct st_table_list *, Item **ref);
 
+#ifdef ENABLE_SENNA
+  bool needs_record();
+#endif /* ENABLE_SENNA */
   enum Type type() const { return COND_ITEM; }
   List<Item>* argument_list() { return &list; }
   table_map used_tables() const;
diff -Nurd mysql-4.1.22.senna/sql/item_func.cc mysql-4.1.22.senna.2ind/sql/item_func.cc
--- mysql-4.1.22.senna/sql/item_func.cc	2006-11-03 11:17:25.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/item_func.cc	2007-03-24 12:54:41.022113000 +0900
@@ -3151,7 +3151,11 @@
   for (keynr=0 ; keynr < table->keys ; keynr++)
   {
     if ((table->key_info[keynr].flags & HA_FULLTEXT) &&
-        (table->keys_in_use_for_query.is_set(keynr)))
+        ((table->keys_in_use_for_query.is_set(keynr))
+#ifdef ENABLE_SENNA
+	 || my_thread_var->sen_flags
+#endif /* ENABLE_SENNA */
+	 ))
     {
       ft_to_key[fts]=keynr;
       ft_cnt[fts]=0;
diff -Nurd mysql-4.1.22.senna/sql/item_func.h mysql-4.1.22.senna.2ind/sql/item_func.h
--- mysql-4.1.22.senna/sql/item_func.h	2006-11-03 11:16:02.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/item_func.h	2007-03-24 12:54:41.024250000 +0900
@@ -1074,6 +1074,9 @@
   table_map not_null_tables() const { return 0; }
   bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
   bool eq(const Item *, bool binary_cmp) const;
+#ifdef ENABLE_SENNA
+  bool needs_record() { return false; }
+#endif /* ENABLE_SENNA */
   /* The following should be safe, even if we compare doubles */
   longlong val_int() { DBUG_ASSERT(fixed == 1); return val()!=0.0; }
   double val();
diff -Nurd mysql-4.1.22.senna/sql/item_sum.cc mysql-4.1.22.senna.2ind/sql/item_sum.cc
--- mysql-4.1.22.senna/sql/item_sum.cc	2006-11-03 11:17:16.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/item_sum.cc	2007-03-24 12:54:41.029200000 +0900
@@ -1200,6 +1200,9 @@
     return 1;
 
   /* Create a table with an unique key over all parameters */
+#ifdef ENABLE_SENNA
+  my_thread_var->sen_flags |= 16;
+#endif /* ENABLE_SENNA */
   for (uint i=0; i < arg_count ; i++)
   {
     Item *item=args[i];
diff -Nurd mysql-4.1.22.senna/sql/records.cc mysql-4.1.22.senna.2ind/sql/records.cc
--- mysql-4.1.22.senna/sql/records.cc	2006-11-03 11:16:13.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/records.cc	2007-03-24 12:54:41.032103000 +0900
@@ -159,6 +159,9 @@
                     table->sort.found_records*info->ref_length;
     info->read_record= (table->sort.addon_field ?
                         rr_unpack_from_buffer : rr_from_pointers);
+#ifdef ENABLE_SENNA
+    my_thread_var->sen_flags |= 4;
+#endif /* ENABLE_SENNA */
   }
   else
   {
@@ -315,6 +318,9 @@
   {
     if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
       return -1;					/* End of file */
+#ifdef ENABLE_SENNA
+    if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) { return 0; }
+#endif /* ENABLE_SENNA */
     if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos)))
       break;
     /* The following is extremely unlikely to happen */
@@ -368,6 +374,9 @@
     cache_pos= info->cache_pos;
     info->cache_pos+= info->ref_length;
 
+#ifdef ENABLE_SENNA
+    if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) { return 0; }
+#endif /* ENABLE_SENNA */
     if (!(tmp=info->file->rnd_pos(info->record,cache_pos)))
       break;
 
diff -Nurd mysql-4.1.22.senna/sql/sql_select.cc mysql-4.1.22.senna.2ind/sql/sql_select.cc
--- mysql-4.1.22.senna/sql/sql_select.cc	2006-11-03 11:15:07.000000000 +0900
+++ mysql-4.1.22.senna.2ind/sql/sql_select.cc	2007-03-24 12:54:41.089840000 +0900
@@ -1125,6 +1125,10 @@
   int      tmp_error;
   DBUG_ENTER("JOIN::exec");
   
+#ifdef ENABLE_SENNA
+  my_thread_var->sen_flags |= 32;
+#endif /* ENABLE_SENNA */
+
   error= 0;
   if (procedure)
   {
@@ -1589,6 +1593,9 @@
   }
   curr_join->having= curr_join->tmp_having;
   thd->proc_info="Sending data";
+#ifdef ENABLE_SENNA
+  my_thread_var->sen_flags &= ~32;
+#endif /* ENABLE_SENNA */
   error= thd->net.report_error ? -1 :
     do_select(curr_join, curr_fields_list, NULL, procedure);
   thd->limit_found_rows= curr_join->send_records;
@@ -1698,7 +1705,10 @@
       goto err;
     }
   }
-
+#ifdef ENABLE_SENNA
+  my_thread_var->sen_flags = select_lex->ftfunc_list->elements ? 1 : 0;
+  if (join->select_distinct) { my_thread_var->sen_flags |= 16; }
+#endif /* ENABLE_SENNA */
   if ((err= join->optimize()))
   {
     goto err;					// 1
@@ -2673,7 +2683,11 @@
   for ( ; field != end ; field++)
     add_key_part(keyuse,field);
 
-  if (select_lex->ftfunc_list->elements)
+  if (select_lex->ftfunc_list->elements
+#ifdef ENABLE_SENNA
+      && !join_tab->table->force_index
+#endif /* ENABLE_SENNA */
+      )
   {
     add_ft_keys(keyuse,join_tab,cond,normal_tables);
   }
@@ -3993,6 +4007,9 @@
       table->status=STATUS_NO_RECORD;
       tab->read_first_record= join_ft_read_first;
       tab->read_record.read_record= join_ft_read_next;
+#ifdef ENABLE_SENNA
+      my_thread_var->sen_flags |= 4;
+#endif /* ENABLE_SENNA */
       break;
     case JT_ALL:
       /*
@@ -6177,10 +6194,27 @@
   return sub_select(join,join_tab,end_of_records); /* Use ordinary select */
 }
 
+#ifdef ENABLE_SENNA
+static void
+decide_read_or_skip(JOIN *join,JOIN_TAB *join_tab,bool needs_record)
+{
+  if (needs_record || (my_thread_var->sen_flags & 48) ||
+      (join_tab->next_select != end_send_group &&
+       !join->unit->offset_limit_cnt && 
+       join->send_records < join->unit->select_limit_cnt)) {
+    my_thread_var->sen_flags |= 8;
+  } else {
+    my_thread_var->sen_flags &= ~8;
+  }
+}
+#endif /* ENABLE_SENNA */
 
 static int
 sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
 {
+#ifdef ENABLE_SENNA
+  if (join_tab->next_select == end_update) { my_thread_var->sen_flags &= ~4; }
+#endif /* ENABLE_SENNA */
 
   join_tab->table->null_row=0;
   if (end_of_records)
@@ -6191,7 +6225,11 @@
   bool found=0;
   COND *on_expr=join_tab->on_expr, *select_cond=join_tab->select_cond;
   my_bool *report_error= &(join->thd->net.report_error);
-
+#ifdef ENABLE_SENNA
+  bool needs_record = select_cond ? select_cond->needs_record() : false;
+ 
+  decide_read_or_skip(join, join_tab, needs_record);
+#endif /* ENABLE_SENNA */
   if (!(error=(*join_tab->read_first_record)(join_tab)))
   {
     bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize;
@@ -6238,6 +6276,9 @@
           */
 	  info->file->unlock_row();
         }
+#ifdef ENABLE_SENNA
+	decide_read_or_skip(join, join_tab, needs_record);
+#endif /* ENABLE_SENNA */
       }
     } while (!(error=info->read_record(info)) && !(*report_error));
   }
@@ -6658,7 +6699,14 @@
   tab->read_record.record=table->record[0];
   if (!table->file->inited)
     table->file->ha_index_init(tab->index);
-  if ((error=tab->table->file->index_first(tab->table->record[0])))
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & 1) { my_thread_var->sen_flags |= 4; }
+  if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) {
+    error=tab->table->file->index_first(NULL);
+  } else
+#endif /* ENABLE_SENNA */
+    error=tab->table->file->index_first(tab->table->record[0]);
+  if (error)
   {
     if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
       report_error(table, error);
@@ -6672,7 +6720,13 @@
 join_read_next(READ_RECORD *info)
 {
   int error;
-  if ((error=info->file->index_next(info->record)))
+#ifdef ENABLE_SENNA
+  if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) {
+    error=info->file->index_next(NULL);
+  } else
+#endif /* ENABLE_SENNA */
+    error=info->file->index_next(info->record);
+  if (error)
     return report_error(info->table, error);
   return 0;
 }
@@ -6697,7 +6751,14 @@
   tab->read_record.record=table->record[0];
   if (!table->file->inited)
     table->file->ha_index_init(tab->index);
-  if ((error= tab->table->file->index_last(tab->table->record[0])))
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & 1) { my_thread_var->sen_flags |= 4; }
+  if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) {
+    error=tab->table->file->index_last(NULL);
+  } else
+#endif /* ENABLE_SENNA */
+    error=tab->table->file->index_last(tab->table->record[0]);
+  if (error)
     return report_error(table, error);
   return 0;
 }
@@ -6707,7 +6768,13 @@
 join_read_prev(READ_RECORD *info)
 {
   int error;
-  if ((error= info->file->index_prev(info->record)))
+#ifdef ENABLE_SENNA
+  if ((my_thread_var->sen_flags & (1|4|8)) == (1|4)) {
+    error=info->file->index_prev(NULL);
+  } else
+#endif /* ENABLE_SENNA */
+    error=info->file->index_prev(info->record);
+  if (error)
     return report_error(info->table, error);
   return 0;
 }
@@ -6721,6 +6788,9 @@
 
   if (!table->file->inited)
     table->file->ha_index_init(tab->ref.key);
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & 1) { my_thread_var->sen_flags |= 4; }
+#endif /* ENABLE_SENNA */
 #if NOT_USED_YET
   if (cp_buffer_from_ref(tab->join->thd, &tab->ref)) // as ft-key doesn't use store_key's
     return -1;                             // see also FT_SELECT::init()
@@ -7924,6 +7994,11 @@
   table=  tab->table;
   select= tab->select;
 
+#ifdef ENABLE_SENNA
+  if (tab->select_cond && tab->select_cond->needs_record()) {
+    my_thread_var->sen_flags |= 8;
+  }
+#endif /* ENABLE_SENNA */
   if (test_if_skip_sort_order(tab,order,select_limit,0))
     DBUG_RETURN(0);
   if (!(sortorder=make_unireg_sortorder(order,&length)))
