--- orig/configure.in	2009-10-16 06:18:59.000000000 +0900
+++ new/configure.in	2009-11-16 17:45:02.000000000 +0900
@@ -856,6 +856,137 @@ MYSQL_SYS_LARGEFILE
 # Types that must be checked AFTER large file support is checked
 AC_TYPE_SIZE_T
 
+# For senna
+get_version_id()
+{
+  _VERSION="$1"
+  _NO_DASH_VERSION=`echo $_VERSION | sed -e "s|-.*$||"`
+  _NUMERIC_VERSION=`echo $_NO_DASH_VERSION | sed -e "s|[[a-z]][[a-z0-9]]*$||"`
+  _BASE_VERSION=`echo $_NUMERIC_VERSION | sed -e "s|\.[[^.]]*$||"`
+  _VERSION_ID=`echo $_NUMERIC_VERSION | \
+      awk -F. '{printf "%d%0.2d%0.2d", $1, $2, $3}'`
+  echo $_VERSION_ID
+}
+
+MECAB_INCLUDES=
+MECAB_LIBS=
+
+AC_ARG_WITH(mecab,
+[  --with-mecab[=DIR]        Specify install prefix of mecab], [
+  if test "$withval" = "yes"; then
+    MECAB_PREFIX=""
+  else
+    MECAB_PREFIX="$withval"
+  fi
+  AC_DEFINE([ENABLE_MECAB], [1], [Define to 1 if MeCab is enabled])
+
+  if test -z "$MECAB_PREFIX"; then
+    if eval 'mecab-config --prefix 2>&1 >/dev/null'; then
+      MECAB_CONFIG='mecab-config'
+      MECAB_PREFIX='mecab-config --prefix'
+      MECAB_INCLUDES="`\"$MECAB_CONFIG\" --cflags`"
+      MECAB_LIBS="${LDFLAGS} `\"$MECAB_CONFIG\" --libs`"
+    fi
+  else
+    MECAB_CONFIG="$MECAB_PREFIX/bin/mecab-config"
+
+    if test -x "$MECAB_CONFIG"; then
+      MECAB_INCLUDES="`\"$MECAB_CONFIG\" --cflags`"
+      MECAB_LIBS="`\"$MECAB_CONFIG\" --libs`"
+    else
+      MECAB_INCLUDES="-I$MECAB_PREFIX/include"
+      MECAB_LIBS="-L$MECAB_PREFIX/lib"
+    fi
+  fi
+], [
+  MECAB_PREFIX=""
+])
+ 
+_CPPFLAGS="${CPPFLAGS}"
+_LIBS="${LIBS}"
+CPPFLAGS="${CPPFLAGS} ${MECAB_INCLUDES}"
+LIBS="${LIBS} ${MECAB_LIBS}"
+ 
+AC_CHECK_FUNC(mecab_new, [
+  AC_DEFINE([HAVE_MECAB], [1], [Define to 1 if libmecab is available])
+  HAVE_MECAB=1
+], [
+  HAVE_MECAB=
+  MECAB_INCLUDES=
+  MECAB_LIBS=
+])
+
+CPPFLAGS="${_CPPFLAGS}"
+LIBS="${_LIBS}"
+
+AC_SUBST(MECAB_INCLUDES)
+AC_SUBST(MECAB_LIBS)
+
+SENNA_INCLUDES=
+SENNA_LIBS=
+
+AC_ARG_WITH(senna,
+[  --with-senna[=DIR]        Enable Senna fulltext search support], [
+  case "$withval" in
+  no) : ;;
+  yes|*)
+    if test "$withval" = "yes"; then
+      if eval 'senna-cfg --cflags 2>&1 >/dev/null'; then
+        SENNA_CFG="senna-cfg"
+        SENNA_PREFIX="senna-cfg --prefix"
+        SENNA_INCLUDES="`\"$SENNA_CFG\" --cflags` $MECAB_INCLUDES"
+        SENNA_LIBS="`\"$SENNA_CFG\" --libs` -lsenna $MECAB_LIBS"
+      else 
+        SENNA_INCLUDES="$MECAB_INCLUDES"
+        SENNA_LIBS="-lsenna $MECAB_LIBS"
+      fi
+    else
+      SENNA_PREFIX="$withval"
+      SENNA_CFG="$SENNA_PREFIX/bin/senna-cfg"
+      if test -x "$SENNA_CFG"; then
+        SENNA_INCLUDES="`\"$SENNA_CFG\" --cflags` $MECAB_INCLUDES"
+        SENNA_LIBS="`\"$SENNA_CFG\" --libs` -lsenna $MECAB_LIBS"
+      else
+        SENNA_INCLUDES="-I$SENNA_PREFIX/include $MECAB_INCLUDES"
+        SENNA_LIBS="-L$SENNA_PREFIX/lib -lsenna $MECAB_LIBS"
+      fi
+    fi
+
+    _CPPFLAGS="${CPPFLAGS}"
+    _LIBS="${LIBS}"
+    CPPFLAGS="${CPPFLAGS} ${SENNA_INCLUDES}"
+    LIBS="${LIBS} ${SENNA_LIBS}"
+ 
+    AC_CHECK_FUNC(sen_init, [
+      AC_DEFINE([ENABLE_SENNA], [1], [Define to 1 if Senna is enabled])
+    ], [
+      AC_MSG_ERROR([Could not find libsenna. Check your Senna installation.])
+    ])
+
+    SENNA_MIN_VERSION_FOR_TRITONN="1.1.4"
+
+    SENNA_VERSION=`$SENNA_CFG --version`
+    SENNA_VERSION_ID=`get_version_id $SENNA_VERSION`
+    SENNA_MIN_REQ_ID=`get_version_id $SENNA_MIN_VERSION_FOR_TRITONN`
+
+    if test $SENNA_VERSION_ID -lt $SENNA_MIN_REQ_ID; then
+      AC_MSG_ERROR([Senna $SENNA_MIN_VERSION_FOR_TRITONN \
+or later is needed. Your senna is $SENNA_VERSION.])
+    fi
+
+    AC_CHECK_FUNC(sen_index_set_abort_callback,[
+      AC_DEFINE(USE_QUERY_ABORT, [1], [use SQL query abort for senna])
+    ])
+
+    CPPFLAGS="${_CPPFLAGS}"
+    LIBS="${_LIBS}"
+    ;;
+  esac
+])
+
+AC_SUBST([SENNA_INCLUDES])
+AC_SUBST([SENNA_LIBS])
+
 #--------------------------------------------------------------------
 # Check for system header files
 #--------------------------------------------------------------------
--- orig/include/my_base.h	2009-10-16 06:19:03.000000000 +0900
+++ new/include/my_base.h	2009-11-16 17:45:02.000000000 +0900
@@ -329,6 +329,38 @@ enum ha_base_keytype {
   update handler::auto_increment_value
 */
 #define HA_STATUS_AUTO          64
+/*
+  get the information about senna fulltext key
+*/
+#ifdef ENABLE_SENNA
+#define HA_STATUS_SENNA         (1 << 31)
+#endif
+
+/*
+   The following defines are for senna.2ind patch.
+
+   1. For (output|filesort|grouping), record value is needed?
+   2. If so, each code checks if filescan is needed.
+   3. If filescan is needed, read_record will be executed.
+*/
+#ifdef ENABLE_SENNA
+#define SENNA_USE_2IND          (1 << 0) /* senna_2ind is on */
+#define SENNA_MATCH             (1 << 1) /* query has match...agains */
+#define SENNA_FILESORT          (1 << 2) /* query needs filesort */
+#define SENNA_DO_READ_RECORD    (1 << 3) /* query needs read_record when filescan, ft_read_next */
+#define SENNA_IF_READ_RECORD    (1 << 4) /* decide_read_or_skip told read_record is needed */
+#define SENNA_DISTINCT          (1 << 5) /* query has distict */
+#define SENNA_FIRST_CALL        (1 << 6)
+#endif
+
+/*
+  create table or like or truncate
+*/
+#ifdef ENABLE_SENNA           
+#define SENNA_CREATE_TABLE      0
+#define SENNA_CREATE_TABLE_LIKE (1 << 0)
+#define SENNA_TRUNCATE_TABLE    (1 << 1)
+#endif
 
 	/* Errorcodes given by functions */
 
--- orig/include/my_global.h	2009-10-16 06:19:03.000000000 +0900
+++ new/include/my_global.h	2009-11-16 17:45:02.000000000 +0900
@@ -1409,3 +1409,23 @@ static inline double rint(double x)
 #endif /* HAVE_RINT */
 
 #endif /* my_global_h */
+
+#ifdef ENABLE_SENNA
+#ifdef SENNA_DEBUG_2IND
+#define DEBUG_2IND(sxp) sxp; \
+  { \
+    int sf = my_thread_var->sen_flags;					\
+    printf("%s#%s:%d sen_flags=%d (",__FUNCTION__,__FILE__, __LINE__, sf); \
+    if (sf & SENNA_USE_2IND) printf("USE2IND ");			\
+    if (sf & SENNA_MATCH) printf("MATCH ");				\
+    if (sf & SENNA_FILESORT) printf("FILESORT ");			\
+    if (sf & SENNA_DO_READ_RECORD) printf("DO_READ_RECORD ");		\
+    if (sf & SENNA_IF_READ_RECORD) printf("IF_READ_RECORD ");		\
+    if (sf & SENNA_DISTINCT) printf("DISTINCT ");			\
+    if (sf & SENNA_FIRST_CALL) printf("FIRST_CALL ");			\
+    printf(")\n"); \
+  }
+#else
+#define DEBUG_2IND(x) x
+#endif
+#endif
--- orig/include/my_pthread.h	2009-10-16 06:19:03.000000000 +0900
+++ new/include/my_pthread.h	2009-11-16 17:45:02.000000000 +0900
@@ -746,6 +746,10 @@ struct st_my_thread_var
   gptr dbug;
   char name[THREAD_NAME_SIZE+1];
 #endif
+#ifdef ENABLE_SENNA /* nkjm SFID:10294 */
+  int sen_flags;
+  uint sen_connection_id;
+#endif /* nkjm SFID:10294 */
 };
 
 extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
--- orig/include/myisam.h	2009-10-16 06:19:04.000000000 +0900
+++ new/include/myisam.h	2009-11-16 17:45:02.000000000 +0900
@@ -32,6 +32,12 @@ extern "C" {
 #endif
 #include "my_handler.h"
 
+#ifdef ENABLE_SENNA
+#include <senna.h>
+#define SEN_DISABLE_SENNA	0x80000000 /* Don't use Senna fulltext search engine */
+extern sen_logger_info senna_logger;
+#endif /* ENABLE_SENNA */
+
 /*
   There is a hard limit for the maximum number of keys as there are only
   8 bits in the index file header for the number of keys in a table.
@@ -198,6 +204,18 @@ typedef struct st_mi_keydef		/* Key defi
   uint32 version;			/* For concurrent read/write */
 
   HA_KEYSEG *seg,*end;
+#ifdef ENABLE_SENNA
+  int senna_flags;
+  int senna_initial_n_segments;
+  uint senna_keys_size;
+  uint senna_keys_file_size;
+  uint senna_lexicon_size;
+  uint senna_lexicon_file_size;
+  ulonglong senna_inv_seg_size;
+  ulonglong senna_inv_chunk_size;
+  sen_index *senna;
+  sen_encoding senna_encoding;
+#endif /* ENABLE_SENNA */
   int (*bin_search)(struct st_myisam_info *info,struct st_mi_keydef *keyinfo,
 		    uchar *page,uchar *key,
 		    uint key_len,uint comp_flag,uchar * *ret_pos,
--- orig/libmysqld/Makefile.am	2009-10-16 06:19:09.000000000 +0900
+++ new/libmysqld/Makefile.am	2009-11-16 17:45:02.000000000 +0900
@@ -30,7 +30,8 @@ INCLUDES=		@bdb_includes@  @innodb_inclu
 			-I$(top_builddir)/sql -I$(top_srcdir)/sql \
 			-I$(top_srcdir)/sql/examples \
 			-I$(top_srcdir)/regex \
-			$(openssl_includes) @ZLIB_INCLUDES@
+			$(openssl_includes) @ZLIB_INCLUDES@ \
+			@SENNA_INCLUDES@ @MECAB_INCLUDES@
 
 noinst_LIBRARIES =	libmysqld_int.a
 pkglib_LIBRARIES =	libmysqld.a
--- orig/libmysqld/examples/Makefile.am	2009-10-16 06:19:09.000000000 +0900
+++ new/libmysqld/examples/Makefile.am	2009-11-16 17:45:02.000000000 +0900
@@ -34,7 +34,8 @@ DEFS = 		-DEMBEDDED_LIBRARY
 INCLUDES =	-I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir) \
 		-I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \
 		$(openssl_includes)
-LIBS =		@LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
+LIBS =		@LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs) \
+                @SENNA_LIBS@ @MECAB_LIBS@
 LDADD =		@CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) \
                 @NDB_SCI_LIBS@
 
--- orig/libmysqld/filesort.cc	2009-10-16 06:20:32.000000000 +0900
+++ new/libmysqld/filesort.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1374,6 +1374,10 @@ sortlength(THD *thd, SORT_FIELD *sortord
       }
       if (sortorder->field->maybe_null())
 	length++;				// Place for NULL marker
+#ifdef ENABLE_SENNA
+      if (my_thread_var->sen_flags & SENNA_USE_2IND)
+	DEBUG_2IND(my_thread_var->sen_flags |= SENNA_FILESORT);
+#endif /* ENABLE_SENNA */
     }
     else
     {
--- orig/libmysqld/ha_myisam.cc	2009-10-16 06:20:33.000000000 +0900
+++ new/libmysqld/ha_myisam.cc	2009-11-16 17:45:02.000000000 +0900
@@ -128,6 +128,45 @@ static void mi_check_print_msg(MI_CHECK 
   return;
 }
 
+#ifdef ENABLE_SENNA
+typedef struct st_senna_enc_map {
+  char* enc_mysql;
+  sen_encoding enc_senna;
+} SENNA_ENC_MAP;
+
+SENNA_ENC_MAP senna_enc_mapping[] = {
+  {"utf8", sen_enc_utf8},
+  {"cp932", sen_enc_sjis},
+  {"sjis", sen_enc_sjis},
+  {"eucjpms", sen_enc_euc_jp},
+  {"ujis", sen_enc_euc_jp},
+  {"latin1", sen_enc_latin1},
+  {"koi8r", sen_enc_koi8r},
+  {0, sen_enc_default},
+  {0, sen_enc_none}};  /* this must be last */
+
+sen_encoding senna_enc_senna(const char *csname)
+{
+  if (!csname) return sen_enc_none;
+  int i;
+  for (i = 0; senna_enc_mapping[i].enc_mysql; i++) {
+    if (!(my_strcasecmp(system_charset_info, csname,
+                       senna_enc_mapping[i].enc_mysql)))
+      return senna_enc_mapping[i].enc_senna;
+  }
+  return sen_enc_none;
+}
+
+char *senna_enc_mysql(sen_encoding encoding)
+{
+  int i;
+  for (i = 0; (senna_enc_mapping[i].enc_senna != sen_enc_default); i++) {
+    if (senna_enc_mapping[i].enc_senna == encoding)
+      return senna_enc_mapping[i].enc_mysql;
+  }
+  return 0;
+}
+#endif /* ENABLE_SENNA */
 
 /*
   Convert TABLE object to MyISAM key and column definition
@@ -174,6 +213,18 @@ int table2myisam(TABLE *table_arg, MI_KE
   for (i= 0; i < share->keys; i++, pos++)
   {
     keydef[i].flag= ((uint16) pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL));
+#ifdef ENABLE_SENNA
+    if ((keydef[i].flag & HA_FULLTEXT)) {
+      if (table_arg->key_info) {
+	keydef[i].senna_flags=pos->senna_flags;
+	keydef[i].senna_initial_n_segments=pos->senna_initial_n_segments;
+	keydef[i].senna_encoding=senna_enc_senna(pos->senna_encoding);
+      } else {
+	keydef[i].senna_flags=SEN_DISABLE_SENNA;
+	keydef[i].senna_initial_n_segments=0;
+      }
+    }
+#endif /* ENABLE_SENNA */
     keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ?
       (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) :
       pos->algorithm;
@@ -461,7 +512,6 @@ int check_definition(MI_KEYDEF *t1_keyin
   DBUG_RETURN(0);
 }
 
-
 extern "C" {
 
 volatile int *killed_ptr(MI_CHECK *param)
@@ -533,9 +583,12 @@ const char **ha_myisam::bas_ext() const
 
 const char *ha_myisam::index_type(uint key_number)
 {
-  return ((table->key_info[key_number].flags & HA_FULLTEXT) ? 
-	  "FULLTEXT" :
-	  (table->key_info[key_number].flags & HA_SPATIAL) ?
+  if (table->key_info[key_number].flags & HA_FULLTEXT)
+  {
+    return "FULLTEXT";
+  }
+  else
+  return ((table->key_info[key_number].flags & HA_SPATIAL) ?
 	  "SPATIAL" :
 	  (table->key_info[key_number].algorithm == HA_KEY_ALG_RTREE) ?
 	  "RTREE" :
@@ -1664,6 +1717,30 @@ int ha_myisam::info(uint flag)
     delete_length=     misam_info.delete_length;
     check_time=        misam_info.check_time;
     mean_rec_length= misam_info.mean_reclength;
+#ifdef ENABLE_SENNA
+    if (flag & HA_STATUS_SENNA) {
+      int i;
+      for (i = 0; i < table->s->keys; i++) {
+	KEY *key = &table->key_info[i];
+	MI_KEYDEF *mi_keydef = &file->s->keyinfo[i];
+	sen_index *senna = mi_keydef->senna;
+	if (senna) {
+	  key->is_senna = true;
+	  key->senna_flags = mi_keydef->senna_flags;
+	  key->senna_initial_n_segments = mi_keydef->senna_initial_n_segments;
+	  key->senna_keys_size = mi_keydef->senna_keys_size;
+	  key->senna_keys_file_size = mi_keydef->senna_keys_file_size;
+	  key->senna_lexicon_size = mi_keydef->senna_lexicon_size;
+	  key->senna_lexicon_file_size = mi_keydef->senna_lexicon_file_size;
+	  key->senna_inv_seg_size = mi_keydef->senna_inv_seg_size;
+	  key->senna_inv_chunk_size = mi_keydef->senna_inv_chunk_size;
+
+	  key->senna_encoding = senna_enc_mysql(mi_keydef->senna_encoding);
+	} else
+	  key->senna_flags = false;
+      }
+    }
+#endif /* ENABLE_SENNA */
   }
   if (flag & HA_STATUS_CONST)
   {
@@ -1760,7 +1837,12 @@ THR_LOCK_DATA **ha_myisam::store_lock(TH
 
 void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
 {
+#ifdef ENABLE_SENNA
+  ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST |
+		  HA_STATUS_VARIABLE | HA_STATUS_SENNA);
+#else
   ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST);
+#endif
   if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
   {
     create_info->auto_increment_value=auto_increment_value;
@@ -1788,8 +1870,36 @@ int ha_myisam::create(const char *name, 
   TABLE_SHARE *share= table->s;
   uint options= share->db_options_in_use;
   DBUG_ENTER("ha_myisam::create");
+#ifdef ENABLE_SENNA
+  if ((ha_create_info->query_type == SENNA_CREATE_TABLE))
+  {
+    int i;
+    for (i=0; i < share->keys; i++)
+    {
+      if ((ha_create_info->key_info[i].flags & HA_FULLTEXT))
+      {
+	table_arg->key_info[i].senna_flags = ha_create_info->key_info[i].senna_flags;
+	table_arg->key_info[i].senna_initial_n_segments = ha_create_info->key_info[i].senna_initial_n_segments; 
+	table_arg->key_info[i].senna_encoding = ha_create_info->key_info[i].senna_encoding;
+      }
+    }
+  }
+  else if ((ha_create_info->query_type == SENNA_TRUNCATE_TABLE) && file) /* file check for restore table */
+  {
+    table_arg->file->open(name,0,0);
+    table_arg->file->info(HA_STATUS_VARIABLE | HA_STATUS_SENNA);
+  }
+  else if ((ha_create_info->query_type == SENNA_CREATE_TABLE_LIKE))
+  {
+    SEN_LOG(sen_log_warning, "ha_myisam::create: create table %s like ... may lost senna extention", name);
+  }
+#endif /* ENABLE_SENNA */
   if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
     DBUG_RETURN(error); /* purecov: inspected */
+#ifdef ENABLE_SENNA
+  if ((ha_create_info->query_type == SENNA_TRUNCATE_TABLE) && file)
+    table_arg->file->close();
+#endif
   bzero((char*) &create_info, sizeof(create_info));
   create_info.max_rows= share->max_rows;
   create_info.reloc_rows= share->min_rows;
--- orig/libmysqld/item_cmpfunc.cc	2009-10-16 06:20:33.000000000 +0900
+++ new/libmysqld/item_cmpfunc.cc	2009-11-16 17:45:02.000000000 +0900
@@ -3375,6 +3375,22 @@ bool Item_func_in::nulls_in_row()
   return 0;
 }
 
+#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 */
 
 /*
   Perform context analysis of an IN item tree
--- orig/libmysqld/item_func.cc	2009-10-16 06:20:33.000000000 +0900
+++ new/libmysqld/item_func.cc	2009-11-16 18:01:30.000000000 +0900
@@ -5069,9 +5069,12 @@ bool Item_func_match::fix_index()
   for (keynr=0 ; keynr < table->s->keys ; keynr++)
   {
     if ((table->key_info[keynr].flags & HA_FULLTEXT) &&
-        (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) :
-                           table->s->keys_in_use.is_set(keynr)))
-
+        ((flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) :
+	  table->s->keys_in_use.is_set(keynr))
+#ifdef ENABLE_SENNA
+	 || my_thread_var->sen_flags
+#endif /* ENABLE_SENNA */
+	 ))
     {
       ft_to_key[fts]=keynr;
       ft_cnt[fts]=0;
--- orig/libmysqld/item_strfunc.cc	2009-10-16 06:20:34.000000000 +0900
+++ new/libmysqld/item_strfunc.cc	2009-11-16 17:45:02.000000000 +0900
@@ -34,6 +34,9 @@
 C_MODE_START
 #include "../mysys/my_static.h"			// For soundex_map
 C_MODE_END
+#ifdef ENABLE_SENNA
+#include <senna.h>
+#endif /* ENABLE_SENNA */
 
 String my_empty_string("",default_charset_info);
 
@@ -3422,3 +3425,213 @@ String *Item_func_uuid::val_str(String *
   strmov(s+18, clock_seq_and_node_str);
   return str;
 }
+
+#ifdef ENABLE_SENNA
+static sen_encoding senna_enc_type(const char *csname)
+{
+  if (!my_strcasecmp(system_charset_info, csname, "latin1"))
+    return sen_enc_latin1;
+  else if (!my_strcasecmp(system_charset_info, csname, "utf8"))
+    return sen_enc_utf8;
+  else if (!my_strcasecmp(system_charset_info, csname, "cp932"))
+    return sen_enc_sjis;
+  else if (!my_strcasecmp(system_charset_info, csname, "sjis"))
+    return sen_enc_sjis;
+  else if (!my_strcasecmp(system_charset_info, csname, "eucjpms"))
+    return sen_enc_euc_jp;
+  else if (!my_strcasecmp(system_charset_info, csname, "ujis"))
+    return sen_enc_euc_jp;
+  else if (!my_strcasecmp(system_charset_info, csname, "koi8r"))
+    return sen_enc_koi8r;
+  else
+    return sen_enc_default;
+}
+
+
+String *Item_func_senna_kwic::val_str(String *str)
+{
+  String *target, target_tmp;
+  int max_snip_len;
+  int max_snips;
+  int html_encoding;
+  String *start, start_tmp;
+  String *end, end_tmp;
+  String *keyword, keyword_tmp;
+  String *open_tag, open_tmp;
+  String *close_tag, close_tmp;
+
+  sen_snip *snip;
+  sen_encoding encoding;
+  sen_rc rc;
+  uint nresults;
+  uint max_tagged_len;
+  sen_snip_mapping *mapping;
+
+  char *result;
+  uint result_len;
+  int i;
+
+  null_value=0;
+
+  if (arg_count < 9 || arg_count % 3 != 0) {
+    SEN_LOG(sen_log_warning, "Incorrect number of arguments for kwic: %d", arg_count);
+    return &my_empty_string;
+  }
+
+  for (i = 0; i < arg_count; i++) {
+    if (!(args[i]->val_str(str))) {
+      SEN_LOG(sen_log_warning, "kwic argument #%d is null", i+1);
+      goto err_null;
+    }
+  }
+
+  target        = args[0]->str_result(&target_tmp);
+  max_snip_len  = args[1]->val_int();
+  max_snips     = args[2]->val_int();
+  html_encoding = args[3]->val_int();
+  start         = args[4]->str_result(&start_tmp);
+  end           = args[5]->str_result(&end_tmp);
+
+  if (max_snip_len <= 0) {
+    SEN_LOG(sen_log_warning, "kwic argument #2 must be positive value, passed %d", max_snip_len);
+    return &my_empty_string;
+  }
+
+  if (max_snips <= 0) {
+    SEN_LOG(sen_log_warning, "kwic argument #3 must be positive value, passed %d", max_snips);
+    return &my_empty_string;
+  }
+
+  if (target == NULL) return &my_empty_string;
+  encoding = senna_enc_senna(target->charset()->csname);
+  if (html_encoding == 1) {
+    mapping = (sen_snip_mapping *) -1;
+  } else {
+    mapping = NULL;
+  }
+
+  SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_open: " \
+	  "%d, SEN_SNIP_NORMALIZE | SEN_SNIP_SKIP_LEADING_SPACES, %d, %d, \"\", 0, \"\", 0, %p",
+	  encoding, max_snip_len, max_snips, mapping);
+  if (!(snip = sen_snip_open(encoding, SEN_SNIP_NORMALIZE | SEN_SNIP_SKIP_LEADING_SPACES, 
+			     max_snip_len, max_snips, "", 0,
+			     "", 0, mapping))) {
+    SEN_LOG(sen_log_error, "sen_snip_open failed: snip = %p", snip);
+    return &my_empty_string;
+  }
+
+  for (i = 6; i < arg_count; i+=3) {
+    keyword       = args[i]->str_result(&keyword_tmp);
+    open_tag      = args[i+1]->str_result(&open_tmp);
+    close_tag     = args[i+2]->str_result(&close_tmp);
+
+    SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_add_cond: " \
+	    "%p, %p, %d, %p, %d, %p, %d", snip, keyword->ptr(), keyword->length(),
+	    open_tag->ptr(), open_tag->length(), close_tag->ptr(), close_tag->length());
+    if ((rc = sen_snip_add_cond(snip, keyword->ptr(), keyword->length(),
+				open_tag->ptr(), open_tag->length(),
+				close_tag->ptr(), close_tag->length()))) {
+      SEN_LOG(sen_log_error, "sen_snip_add_cond failed: sen_rc= %d", rc);
+      SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	      "snip = %p", snip);
+      if ((rc = sen_snip_close(snip))) {
+	SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+      }
+      return &my_empty_string;
+    }
+  }
+
+  SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_exec: " \
+	  "%p, %p, %d, %p, %p", snip, target->ptr(), target->length(),
+	  &nresults, &max_tagged_len);
+  if ((rc = sen_snip_exec(snip, target->ptr(), target->length(),
+			  &nresults, &max_tagged_len))) {
+    SEN_LOG(sen_log_error, "sen_snip_exec failed: sen_rc= %d", rc);
+    SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	    "snip = %p", snip);
+    if ((rc = sen_snip_close(snip))) {
+      SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+    }
+    return &my_empty_string;
+  }
+
+
+  if (!(result = sql_alloc(max_tagged_len))) {
+    SEN_LOG(sen_log_error, "sql_alloc failed", rc);
+    SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+            "snip = %p\n", snip);
+    if ((rc = sen_snip_close(snip))) {
+      SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d\n", rc);
+    }
+    return &my_empty_string;
+  }
+
+  str->copy("", 0, target->charset());
+
+  for (i = 0; i < nresults; i++) {
+    SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_get_result: " \
+	    "%p, 0, %p, %p", snip, result, &result_len);
+    if ((rc = sen_snip_get_result(snip, i, result, &result_len))) {
+      SEN_LOG(sen_log_error, "sen_snip_get_result failed: sen_rc= %d", rc);
+      SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	      "snip = %p", snip);
+      if ((rc = sen_snip_close(snip))) {
+	SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+      }
+      return &my_empty_string;
+    }
+    
+    if (result_len <= 0) {
+      SEN_LOG(sen_log_error, "result_len is not positive value: %d", result_len);
+      SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	      "snip = %p", snip);
+      if ((rc = sen_snip_close(snip))) {
+	SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+      }
+      return &my_empty_string;
+    }
+    
+    str->append(start->ptr(), start->length(), target->charset());
+    str->append(result, result_len, target->charset());
+    str->append(end->ptr(), end->length(), target->charset());
+  }
+
+  SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	  "snip = %p", snip);
+  if ((rc = sen_snip_close(snip))) {
+    SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+  }
+
+  return str;
+
+err_null:
+  null_value= 1;
+  return 0;
+}
+
+
+void Item_func_senna_kwic::fix_length_and_dec()
+{
+  ulonglong max_result_length= 0;
+
+  if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
+    return;
+
+  for (uint i=0 ; i < arg_count ; i++)
+  {
+    if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
+      max_result_length+= (args[i]->max_length /
+                           args[i]->collation.collation->mbmaxlen) *
+                           collation.collation->mbmaxlen;
+    else
+      max_result_length+= args[i]->max_length;
+  }
+
+  if (max_result_length >= MAX_BLOB_WIDTH)
+  {
+    max_result_length= MAX_BLOB_WIDTH;
+    maybe_null= 1;
+  }
+  max_length= (ulong) max_result_length;
+}
+#endif /* ENABLE_SENNA */
--- orig/libmysqld/item_sum.cc	2009-10-16 06:20:34.000000000 +0900
+++ new/libmysqld/item_sum.cc	2009-11-16 17:45:02.000000000 +0900
@@ -2552,6 +2552,10 @@ bool Item_sum_count_distinct::setup(THD 
     return TRUE;
 
   /* Create a table with an unique key over all parameters */
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND)
+    DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DISTINCT);
+#endif /* ENABLE_SENNA */
   for (uint i=0; i < arg_count ; i++)
   {
     Item *item=args[i];
--- orig/libmysqld/records.cc	2009-10-16 06:20:35.000000000 +0900
+++ new/libmysqld/records.cc	2009-11-16 17:45:02.000000000 +0900
@@ -193,6 +193,10 @@ void init_read_record(READ_RECORD *info,
                     table->sort.found_records*info->ref_length;
     info->read_record= (table->sort.addon_field ?
                         rr_unpack_from_buffer : rr_from_pointers);
+#ifdef ENABLE_SENNA
+    if (my_thread_var->sen_flags & SENNA_USE_2IND)
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+#endif /* ENABLE_SENNA */
   }
   else
   {
@@ -357,6 +361,16 @@ static int rr_from_tempfile(READ_RECORD 
   {
     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 & SENNA_USE_2IND) {
+      if ((my_thread_var->sen_flags & 
+	   (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	  == (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+	SEN_LOG(sen_log_debug, "rr_from_tempfile: 2ind return 0");
+	return 0;
+      }
+    }
+#endif /* ENABLE_SENNA */
     if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos)))
       break;
     /* The following is extremely unlikely to happen */
@@ -410,6 +424,16 @@ static int rr_from_pointers(READ_RECORD 
     cache_pos= info->cache_pos;
     info->cache_pos+= info->ref_length;
 
+#ifdef ENABLE_SENNA
+    if (my_thread_var->sen_flags & SENNA_USE_2IND) {
+      if ((my_thread_var->sen_flags &
+	   (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD)) 
+	  == (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+	SEN_LOG(sen_log_debug, "rr_from_pointers: 2ind return 0");
+	return 0;
+      }
+    }
+#endif /* ENABLE_SENNA */
     if (!(tmp=info->file->rnd_pos(info->record,cache_pos)))
       break;
 
--- orig/libmysqld/set_var.cc	2009-10-16 06:20:35.000000000 +0900
+++ new/libmysqld/set_var.cc	2009-11-16 17:45:02.000000000 +0900
@@ -82,6 +82,25 @@ TYPELIB delay_key_write_typelib=
   delay_key_write_type_names, NULL
 };
 
+#ifdef ENABLE_SENNA
+const char *senna_log_level_type_names[] = { "NONE", "EMERG", "ALERT",
+					     "CRIT", "ERROR", "WARNING",
+					     "NOTICE", "INFO", "DEBUG",
+					     "DUMP", NullS };
+TYPELIB senna_log_level_typelib=
+{
+  array_elements(senna_log_level_type_names)-1, "",
+  senna_log_level_type_names, NULL
+};
+
+const char *senna_index_type_type_names[] = { "NGRAM", "MECAB", NullS};
+TYPELIB senna_index_type_typelib=
+{
+  array_elements(senna_index_type_type_names)-1, "",
+  senna_index_type_type_names, NULL
+};
+#endif
+
 static int  sys_check_ftb_syntax(THD *thd,  set_var *var);
 static bool sys_update_ftb_syntax(THD *thd, set_var * var);
 static void sys_default_ftb_syntax(THD *thd, enum_var_type type);
@@ -478,6 +497,15 @@ sys_var_const_os_str_ptr sys_innodb_log_
                                                        &innobase_log_group_home_dir);
 #endif
 
+#ifdef ENABLE_SENNA
+sys_var_enum            sys_senna_index_type("senna_index_type",&senna_index_type_options,
+					     &senna_index_type_typelib, fix_senna_index_type);
+sys_var_bool_ptr        sys_senna_log("senna_log", &opt_senna_log);
+sys_var_enum            sys_senna_log_level("senna_log_level",&senna_log_level_options,
+					    &senna_log_level_typelib, fix_senna_log_level);
+sys_var_thd_bool        sys_senna_2ind("senna_2ind", &SV::senna_2ind, fix_senna_2ind);
+#endif
+
 /* Condition pushdown to storage engine */
 sys_var_thd_bool
 sys_engine_condition_pushdown("engine_condition_pushdown",
@@ -765,6 +793,11 @@ sys_var *sys_variables[]=
   &sys_secure_auth,
   &sys_secure_file_priv,
   &sys_select_limit,
+#ifdef ENABLE_SENNA
+  &sys_senna_2ind,
+  &sys_senna_index_type,
+  &sys_senna_log_level,
+#endif
   &sys_server_id,
 #ifdef HAVE_REPLICATION
   &sys_slave_compressed_protocol,
@@ -1092,6 +1125,12 @@ struct show_var_st init_vars[]= {
   {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank,       SHOW_SYS},
   {"secure_auth",             (char*) &sys_secure_auth,             SHOW_SYS},
   {"secure_file_priv",        (char*) &sys_secure_file_priv,        SHOW_SYS},
+#ifdef ENABLE_SENNA
+  {"senna_2ind",              (char*) &sys_senna_2ind,              SHOW_SYS},
+  {"senna_index_type",        (char*) &sys_senna_index_type,        SHOW_SYS},
+  {"senna_log",               (char*) &opt_senna_log,               SHOW_MY_BOOL},
+  {"senna_log_level",         (char*) &sys_senna_log_level,         SHOW_SYS},
+#endif
 #ifdef HAVE_SMEM
   {"shared_memory",           (char*) &opt_enable_shared_memory,    SHOW_MY_BOOL},
   {"shared_memory_base_name", (char*) &shared_memory_base_name,     SHOW_CHAR_PTR},
@@ -1414,6 +1453,33 @@ extern void fix_delay_key_write(THD *thd
   }
 }
 
+#ifdef ENABLE_SENNA
+extern void fix_senna_index_type(THD *thd, enum_var_type type)
+{
+  DBUG_ENTER("fix_senna_index_type");
+  if (senna_index_type_options == 0) {
+    senna_default_flags = (SEN_INDEX_NORMALIZE | SEN_INDEX_NGRAM);
+  } else {
+    senna_default_flags = (SEN_INDEX_NORMALIZE);
+  }
+  DBUG_VOID_RETURN;
+}
+
+extern void fix_senna_log_level(THD *thd, enum_var_type type)
+{
+  DBUG_ENTER("fix_senna_log_level");
+  senna_logger.max_level = (sen_log_level) senna_log_level_options;
+  DBUG_VOID_RETURN;
+}
+
+extern void fix_senna_2ind(THD *thd, enum_var_type type)
+{
+  DBUG_ENTER("fix_senna_2ind");
+  DEBUG_2IND(my_thread_var->sen_flags = (thd->variables.senna_2ind ? SENNA_USE_2IND : 0));
+  DBUG_VOID_RETURN;
+}
+#endif
+
 static void fix_max_binlog_size(THD *thd, enum_var_type type)
 {
   DBUG_ENTER("fix_max_binlog_size");
--- orig/libmysqld/sp_head.cc	2009-10-16 06:20:36.000000000 +0900
+++ new/libmysqld/sp_head.cc	2009-11-16 17:45:02.000000000 +0900
@@ -193,6 +193,9 @@ sp_get_flags_for_command(LEX *lex)
   case SQLCOM_SHOW_OPEN_TABLES:
   case SQLCOM_SHOW_PRIVILEGES:
   case SQLCOM_SHOW_PROCESSLIST:
+#ifdef ENABLE_SENNA
+  case SQLCOM_SHOW_SENNA_STATUS:
+#endif
   case SQLCOM_SHOW_SLAVE_HOSTS:
   case SQLCOM_SHOW_SLAVE_STAT:
   case SQLCOM_SHOW_STATUS:
--- orig/libmysqld/sql_db.cc	2009-10-16 06:20:36.000000000 +0900
+++ new/libmysqld/sql_db.cc	2009-11-16 17:45:02.000000000 +0900
@@ -874,6 +874,11 @@ static long mysql_rm_known_files(THD *th
        (file->name[1] == '.' &&  !file->name[2])))
       continue;
 
+#ifdef ENABLE_SENNA
+    /* senna files is skip */
+    /* ".SEN",".SEN.i",".SEN.i.c",".SEN.l", ".SEN.i.c.001",.. and so on */
+    if (strstr(file->name, ".SEN")) { continue; }
+#endif /* ENABLE_SENNA */
     /* Check if file is a raid directory */
     if ((my_isdigit(system_charset_info, file->name[0]) ||
 	 (file->name[0] >= 'a' && file->name[0] <= 'f')) &&
--- orig/libmysqld/sql_delete.cc	2009-10-16 06:20:36.000000000 +0900
+++ new/libmysqld/sql_delete.cc	2009-11-16 17:45:02.000000000 +0900
@@ -939,6 +939,9 @@ bool mysql_truncate(THD *thd, TABLE_LIST
     if (thd->slave_thread)
       --slave_open_temp_tables;
     *fn_ext(path)=0;				// Remove the .frm extension
+#ifdef ENABLE_SENNA
+    create_info.key_info=table->key_info;
+#endif /* ENABLE_SENNA */
     ha_create_table(path, &create_info,1);
     // We don't need to call invalidate() because this table is not in cache
     if ((error= (int) !(open_temporary_table(thd, path, table_list->db,
@@ -971,6 +974,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST
       DBUG_RETURN(TRUE);
   }
 
+#ifdef ENABLE_SENNA
+  create_info.query_type = SENNA_TRUNCATE_TABLE;
+#endif
+
   *fn_ext(path)=0;				// Remove the .frm extension
   error= ha_create_table(path,&create_info,1);
   query_cache_invalidate3(thd, table_list, 0);
--- orig/libmysqld/sql_insert.cc	2009-10-16 06:20:36.000000000 +0900
+++ new/libmysqld/sql_insert.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1867,6 +1867,9 @@ bool delayed_get_table(THD *thd, TABLE_L
       di->table_list.alias= di->table_list.table_name= di->thd.query;
       di->table_list.db= di->thd.db;
       di->lock();
+#ifdef ENABLE_SENNA
+      di->thd.thread_id= thd->thread_id;
+#endif
       pthread_mutex_lock(&di->mutex);
       if ((error= pthread_create(&di->thd.real_id, &connection_attrib,
                                  handle_delayed_insert, (void*) di)))
@@ -2204,6 +2207,9 @@ pthread_handler_t handle_delayed_insert(
 {
   Delayed_insert *di=(Delayed_insert*) arg;
   THD *thd= &di->thd;
+#ifdef ENABLE_SENNA
+  uint sen_thread_id = thd->thread_id;
+#endif
 
   pthread_detach_this_thread();
   /* Add thread to THD list so that's it's visible in 'show processlist' */
@@ -2229,6 +2235,12 @@ pthread_handler_t handle_delayed_insert(
     strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
     goto end;
   }
+#ifdef ENABLE_SENNA /* nkjm SFID:10294 */
+  struct st_my_thread_var *sen_tmp;
+  extern pthread_key_t THR_KEY_mysys;
+  sen_tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
+  sen_tmp->sen_connection_id= sen_thread_id;
+#endif /* nkjm SFID:10294 */
 #endif
 
   DBUG_ENTER("handle_delayed_insert");
--- orig/libmysqld/sql_parse.cc	2009-10-16 06:20:37.000000000 +0900
+++ new/libmysqld/sql_parse.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1142,6 +1142,12 @@ pthread_handler_t handle_one_connection(
     end_thread(thd,0);
     return 0;
   }
+#ifdef ENABLE_SENNA /* nkjm SFID:10294 */
+  struct st_my_thread_var *sen_tmp;
+  extern pthread_key_t THR_KEY_mysys;
+  sen_tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
+  sen_tmp->sen_connection_id= thd->thread_id;
+#endif /* nkjm SFID:10294 */
 #endif
 
   /*
@@ -1221,6 +1227,9 @@ pthread_handler_t handle_one_connection(
       thd_proc_info(thd, 0);
       thd->init_for_queries();
     }
+#ifdef ENABLE_SENNA
+    DEBUG_2IND(my_thread_var->sen_flags = (thd->variables.senna_2ind ? SENNA_USE_2IND : 0));
+#endif
 
     /* Connect completed, set read/write timeouts back to tdefault */
     my_net_set_read_timeout(net, thd->variables.net_read_timeout);
@@ -3144,6 +3153,13 @@ mysql_execute_command(THD *thd)
       break;
     }
 #endif
+#ifdef ENABLE_SENNA
+  case SQLCOM_SHOW_SENNA_STATUS:
+  {
+    res = senna_show_status(thd, lex);
+    break;
+  }
+#endif
 #ifdef HAVE_REPLICATION
   case SQLCOM_LOAD_MASTER_TABLE:
   {
--- orig/libmysqld/sql_select.cc	2009-10-16 06:20:37.000000000 +0900
+++ new/libmysqld/sql_select.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1479,6 +1479,11 @@ JOIN::optimize()
       DBUG_RETURN(-1);                         /* purecov: inspected */
   }
 
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND)
+    DEBUG_2IND(my_thread_var->sen_flags |= SENNA_FIRST_CALL);
+#endif /* ENABLE_SENNA */
+
   error= 0;
   DBUG_RETURN(0);
 }
@@ -2101,6 +2106,11 @@ JOIN::exec()
   curr_join->fields= curr_fields_list;
   curr_join->procedure= procedure;
 
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND)
+    DEBUG_2IND(my_thread_var->sen_flags &= ~SENNA_FIRST_CALL);
+#endif /* ENABLE_SENNA */
+
   if (is_top_level_join() && thd->cursor && tables != const_tables)
   {
     /*
@@ -2301,7 +2311,16 @@ mysql_select(THD *thd, Item ***rref_poin
       goto err;
     }
   }
-
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND) {
+    if (select_lex->ftfunc_list->elements) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_MATCH);
+    }
+    if (join->select_distinct) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DISTINCT);
+    }
+  }
+#endif /* ENABLE_SENNA */
   if ((err= join->optimize()))
   {
     goto err;					// 1
@@ -2335,6 +2354,9 @@ mysql_select(THD *thd, Item ***rref_poin
   }
 
 err:
+#ifdef ENABLE_SENNA
+  DEBUG_2IND(my_thread_var->sen_flags &= SENNA_USE_2IND);
+#endif
   if (free_join)
   {
     thd_proc_info(thd, "end");
@@ -3730,7 +3752,11 @@ update_ref_and_keys(THD *thd, DYNAMIC_AR
       return TRUE;
   }
 
-  if (select_lex->ftfunc_list->elements)
+  if (select_lex->ftfunc_list->elements
+#ifdef ENABLE_SENNA
+      && !join_tab->table->force_index
+#endif /* ENABLE_SENNA */
+      )
   {
     if (add_ft_keys(keyuse,join_tab,cond,normal_tables))
       return TRUE;
@@ -6254,6 +6280,10 @@ make_join_readinfo(JOIN *join, ulonglong
       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
+      if (my_thread_var->sen_flags & SENNA_USE_2IND) 
+	DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+#endif /* ENABLE_SENNA */
       break;
     case JT_ALL:
       /*
@@ -10589,6 +10619,21 @@ do_select(JOIN *join,List<Item> *fields,
   DBUG_RETURN(join->thd->net.report_error ? -1 : rc);
 }
 
+#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 & (SENNA_DISTINCT | SENNA_FIRST_CALL)) ||
+      (((*join->sum_funcs && (*join->sum_funcs)->sum_func() != Item_sum::COUNT_FUNC) ||
+	join_tab->next_select != end_send_group)
+       && !join->unit->offset_limit_cnt &&
+       join->send_records < join->unit->select_limit_cnt)) {
+    DEBUG_2IND(my_thread_var->sen_flags |= SENNA_IF_READ_RECORD);
+  } else {
+    DEBUG_2IND(my_thread_var->sen_flags &= ~SENNA_IF_READ_RECORD);
+  }
+}
+#endif /* ENABLE_SENNA */
 
 enum_nested_loop_state
 sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
@@ -10734,6 +10779,11 @@ sub_select_cache(JOIN *join,JOIN_TAB *jo
 enum_nested_loop_state
 sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
 {
+#ifdef ENABLE_SENNA
+  if ((my_thread_var->sen_flags & SENNA_USE_2IND) && (join_tab->next_select == end_update)) {
+    DEBUG_2IND(my_thread_var->sen_flags &= ~SENNA_DO_READ_RECORD);
+  }
+#endif /* ENABLE_SENNA */
   join_tab->table->null_row=0;
   if (end_of_records)
     return (*join_tab->next_select)(join,join_tab+1,end_of_records);
@@ -10742,6 +10792,10 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
   enum_nested_loop_state rc;
   my_bool *report_error= &(join->thd->net.report_error);
   READ_RECORD *info= &join_tab->read_record;
+#ifdef ENABLE_SENNA
+  COND *select_cond = join_tab->select_cond;
+  bool needs_record = select_cond ? select_cond->needs_record() : false;
+#endif /* ENABLE_SENNA */
 
   if (join->resume_nested_loop)
   {
@@ -10771,12 +10825,20 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
     }
     join->thd->row_count= 0;
 
+#ifdef ENABLE_SENNA
+    if (my_thread_var->sen_flags & SENNA_USE_2IND)
+      decide_read_or_skip(join, join_tab, needs_record);
+#endif /* ENABLE_SENNA */
     error= (*join_tab->read_first_record)(join_tab);
     rc= evaluate_join_record(join, join_tab, error, report_error);
   }
 
   while (rc == NESTED_LOOP_OK)
   {
+#ifdef ENABLE_SENNA
+    if (my_thread_var->sen_flags & SENNA_USE_2IND)
+      decide_read_or_skip(join, join_tab, needs_record);
+#endif /* ENABLE_SENNA */
     error= info->read_record(info);
     rc= evaluate_join_record(join, join_tab, error, report_error);
   }
@@ -11458,7 +11520,22 @@ join_read_first(JOIN_TAB *tab)
   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 & SENNA_USE_2IND) {
+    if (my_thread_var->sen_flags & SENNA_MATCH) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+    }
+    if ((my_thread_var->sen_flags & 
+	 (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	== (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+      //error=tab->table->file->index_first(NULL);
+      //statistic_increment(tab->table->in_use->status_var.senna_2ind_count, &LOCK_status);
+      return 0;
+    }
+  }
+#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);
@@ -11472,7 +11549,19 @@ static int
 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 & SENNA_USE_2IND) {
+    if ((my_thread_var->sen_flags & 
+	 (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	== (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+      //error=info->file->index_next(NULL);
+      //statistic_increment(info->thd->status_var.senna_2ind_count, &LOCK_status);
+      return 0;
+    }
+  }
+#endif /* ENABLE_SENNA */
+    error=info->file->index_next(info->record);
+  if (error)
     return report_error(info->table, error);
   return 0;
 }
@@ -11497,7 +11586,22 @@ join_read_last(JOIN_TAB *tab)
   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 & SENNA_USE_2IND) {
+    if (my_thread_var->sen_flags & SENNA_MATCH) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+    }
+    if ((my_thread_var->sen_flags & 
+	 (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	== (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+      //error=tab->table->file->index_last(NULL);
+      //statistic_increment(tab->table->in_use->status_var.senna_2ind_count, &LOCK_status);
+      return 0;
+    }
+  }
+#endif /* ENABLE_SENNA */
+    error=tab->table->file->index_last(tab->table->record[0]);
+  if (error)
     return report_error(table, error);
   return 0;
 }
@@ -11507,7 +11611,19 @@ static int
 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 & SENNA_USE_2IND) {
+    if ((my_thread_var->sen_flags & 
+	 (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	== (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+      //error=info->file->index_prev(NULL);
+      //statistic_increment(info->thd->status_var.senna_2ind_count, &LOCK_status);
+      return 0;
+    }
+  } 
+#endif /* ENABLE_SENNA */
+    error=info->file->index_prev(info->record);
+  if (error)
     return report_error(info->table, error);
   return 0;
 }
@@ -11521,6 +11637,12 @@ join_ft_read_first(JOIN_TAB *tab)
 
   if (!table->file->inited)
     table->file->ha_index_init(tab->ref.key);
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND)
+    if (my_thread_var->sen_flags & SENNA_MATCH) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+    }
+#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()
@@ -12833,6 +12955,14 @@ create_sort_index(THD *thd, JOIN *join, 
   table=  tab->table;
   select= tab->select;
 
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND) {
+    if (tab->select_cond && tab->select_cond->needs_record()) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_IF_READ_RECORD);
+    }
+  }
+#endif /* ENABLE_SENNA */
+
   /*
     When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
     and thus force sorting on disk unless a group min-max optimization
--- orig/libmysqld/sql_show.cc	2009-10-16 06:20:37.000000000 +0900
+++ new/libmysqld/sql_show.cc	2009-11-16 17:45:02.000000000 +0900
@@ -28,6 +28,13 @@
 #include "ha_berkeley.h"			// For berkeley_show_logs
 #endif
 
+#ifdef ENABLE_SENNA
+#define SECTIONALIZE  0x00080000
+#ifdef HAVE_ISAM
+#include "ha_myisam.h"                 // For isam
+#endif
+#endif /* ENABLE_SENNA */
+
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
 static const char *grant_names[]={
   "select","insert","update","delete","create","drop","reload","shutdown",
@@ -1021,6 +1028,45 @@ store_create_info(THD *thd, TABLE_LIST *
 	  !(key_info->flags & HA_SPATIAL))
         packet->append(STRING_WITH_LEN(" USING RTREE"));
 
+#ifdef ENABLE_SENNA
+      {
+	char ins[32];
+	char *insp;
+	int inslen;
+	if (key_info->is_senna)
+	{
+	  if (key_info->senna_flags & SEN_INDEX_NGRAM)
+	    packet->append(STRING_WITH_LEN(" USING NGRAM"));
+	  else if (key_info->senna_flags & SEN_INDEX_DELIMITED)
+	    packet->append(STRING_WITH_LEN(" USING DELIMITED"));
+	  else
+	    packet->append(STRING_WITH_LEN(" USING MECAB"));
+
+	  if (key_info->senna_flags & SEN_INDEX_NORMALIZE)
+	    packet->append(STRING_WITH_LEN(", NORMALIZE"));
+	  else
+	    packet->append(STRING_WITH_LEN(", NO NORMALIZE"));
+
+	  if (key_info->senna_flags & SECTIONALIZE)
+	    packet->append(STRING_WITH_LEN(", SECTIONALIZE"));
+
+	  if (key_info->senna_flags & SEN_INDEX_SPLIT_ALPHA)
+	    packet->append(STRING_WITH_LEN(", SPLIT_ALPHA"));
+	  if (key_info->senna_flags & SEN_INDEX_SPLIT_DIGIT)
+	    packet->append(STRING_WITH_LEN(", SPLIT_DIGIT"));
+	  if (key_info->senna_flags & SEN_INDEX_SPLIT_SYMBOL)
+	    packet->append(STRING_WITH_LEN(", SPLIT_SYMBOL"));
+
+	/* TODO: initial_n_segments support */
+	  my_snprintf(ins, sizeof(ins), ", %d",key_info->senna_initial_n_segments);
+	  inslen = strlen(ins);
+	  insp = sql_alloc(inslen);
+	  memcpy(insp, ins, inslen);
+	  packet->append(insp, inslen);
+        }
+      }
+#endif
+
       // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY
     }
     packet->append(STRING_WITH_LEN(" ("));
@@ -1930,6 +1976,9 @@ void get_index_field_values(LEX *lex, IN
   case SQLCOM_SHOW_TABLES:
   case SQLCOM_SHOW_TABLE_STATUS:
   case SQLCOM_SHOW_TRIGGERS:
+#ifdef ENABLE_SENNA
+  case SQLCOM_SHOW_SENNA_STATUS: 
+#endif
     index_field_values->db_value= lex->select_lex.db;
     index_field_values->table_value= wild;
     break;
@@ -4505,3 +4554,120 @@ ST_SCHEMA_TABLE schema_tables[]=
 template class List_iterator_fast<char>;
 template class List<char>;
 #endif
+
+#ifdef ENABLE_SENNA
+bool senna_show_status(THD *thd, LEX *lex)
+{
+  List<char> files;
+  List<Item> field_list;  
+  char path[FN_LEN];
+  char *file_name;
+  DBUG_ENTER("senna_show_status");
+  Protocol* protocol = thd->protocol;
+  char *db = lex->select_lex.db ? lex->select_lex.db : thd->db;
+  if (!db) {
+    my_error(ER_NO_DB_ERROR, MYF(0));
+    DBUG_RETURN(TRUE);
+  }
+
+  const char *wild = lex->wild ? lex->wild->ptr() : "%";
+  
+  (void) my_snprintf(path, FN_LEN, "%s/%s", mysql_data_home, db);
+  (void) unpack_dirname(path, path);
+  
+  field_list.push_back(new Item_empty_string("Table", 20));
+  field_list.push_back(new Item_empty_string("Key_name", 20));
+  field_list.push_back(new Item_empty_string("Column_name", 20));
+  field_list.push_back(new Item_empty_string("Encoding", 20));
+  field_list.push_back(new Item_empty_string("Index_type", 20));
+  field_list.push_back(new Item_empty_string("Sectionalize", 20));
+  field_list.push_back(new Item_empty_string("Normalize", 20));
+  field_list.push_back(new Item_empty_string("Split_alpha", 20));
+  field_list.push_back(new Item_empty_string("Split_digit", 20));
+  field_list.push_back(new Item_empty_string("Split_symbol", 20));
+  field_list.push_back(new Item_int("Initial_n_segments", 20));
+  field_list.push_back(new Item_int("Senna_keys_size", 20));
+  field_list.push_back(new Item_int("Senna_keys_file_size", 20));
+  field_list.push_back(new Item_int("Senna_lexicon_size", 20));
+  field_list.push_back(new Item_int("Senna_lexicon_file_size", 20));
+  field_list.push_back(new Item_int("Senna_inv_seg_size", 20));
+  field_list.push_back(new Item_int("Senna_inv_chunk_size", 20));
+  if (protocol->send_fields(&field_list,
+			    Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+    DBUG_RETURN(TRUE);
+  
+  if (find_files(thd, &files, db, path, wild, 0))
+    DBUG_RETURN(-1);
+  List_iterator_fast<char> it(files);
+  while (file_name = it++)
+  {
+    TABLE tmp_table;
+    TABLE_LIST table_list;
+
+    /* to skip views */
+    (void) my_snprintf(path, FN_LEN, "%s/%s", db, file_name);
+    openfrm(thd, path, "", 0, SENNA_CHECK_VIEW, 0, &tmp_table);
+    if(!(tmp_table.file)) continue;
+    closefrm(&tmp_table);
+
+    bzero((char*) &table_list, sizeof(table_list));
+    table_list.db = db;
+    table_list.table_name = file_name;
+    table_list.alias = file_name;
+    TABLE *table = open_ltable(thd, &table_list, TL_READ);
+    if (!strcmp(table->file->table_type(), "MyISAM"))
+    {
+      uint nkeys = table->s->keys;
+      int i = 0;
+      table->file->info(HA_STATUS_VARIABLE | HA_STATUS_SENNA);
+      for (; i < nkeys; i++)
+      {
+	const char* tkey;
+	KEY *key = &table->key_info[i];
+	
+        if (key->algorithm == HA_KEY_ALG_FULLTEXT
+	    &&!(key->senna_flags & SEN_DISABLE_SENNA))
+	{
+	  uint nkey_parts = key->key_parts;
+	  int j = 0;
+	  for (; j < nkey_parts; j++)
+	  {
+	    KEY_PART_INFO *key_part = &key->key_part[j];
+	    uint16 fieldnr = key_part->fieldnr;
+	    Field *field = table->field[fieldnr-1];
+	    const char *field_name = field->field_name;
+	    
+	    protocol->prepare_for_resend();
+	    protocol->store(key->table->s->table_name, system_charset_info);
+	    protocol->store(key->name, system_charset_info);
+	    protocol->store(field_name, system_charset_info);
+	    protocol->store(key->senna_encoding, system_charset_info);
+	    if (key->senna_flags & SEN_INDEX_NGRAM)
+	      protocol->store("NGRAM", system_charset_info); 
+	    else if (key->senna_flags & SEN_INDEX_DELIMITED)
+	      protocol->store("DELIMITED", system_charset_info);
+	    else
+	      protocol->store("MECAB", system_charset_info);
+	    protocol->store(key->senna_flags & SECTIONALIZE ? "ON" : "OFF", system_charset_info);
+	    protocol->store(key->senna_flags & SEN_INDEX_NORMALIZE ? "ON" : "OFF", system_charset_info);
+	    protocol->store(key->senna_flags & SEN_INDEX_SPLIT_ALPHA ? "ON" : "OFF", system_charset_info);
+	    protocol->store(key->senna_flags & SEN_INDEX_SPLIT_DIGIT ? "ON" : "OFF", system_charset_info);
+	    protocol->store(key->senna_flags & SEN_INDEX_SPLIT_SYMBOL ? "ON" : "OFF", system_charset_info);
+	    protocol->store((longlong) key->senna_initial_n_segments);
+	    protocol->store((longlong) key->senna_keys_size);
+	    protocol->store((longlong) key->senna_keys_file_size);
+	    protocol->store((longlong) key->senna_lexicon_size);
+	    protocol->store((longlong) key->senna_lexicon_file_size);
+	    protocol->store((longlong) key->senna_inv_seg_size);
+	    protocol->store((longlong) key->senna_inv_chunk_size);
+	    if (protocol->write()) DBUG_RETURN(TRUE);
+	  }
+	}
+      }
+    }
+    close_thread_tables(thd, 0);
+  }
+  send_eof(thd);
+  DBUG_RETURN(TRUE);
+}
+#endif
--- orig/libmysqld/sql_table.cc	2009-10-16 06:20:37.000000000 +0900
+++ new/libmysqld/sql_table.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1129,6 +1129,9 @@ static int mysql_prepare_table(THD *thd,
   if (!*key_info_buffer || ! key_part_info)
     DBUG_RETURN(-1);				// Out of memory
 
+#ifdef ENABLE_SENNA
+  create_info->key_info=*key_info_buffer;
+#endif /* ENABLE_SENNA */
   key_iterator.rewind();
   key_number=0;
   for (; (key=key_iterator++) ; key_number++)
@@ -1172,6 +1175,10 @@ static int mysql_prepare_table(THD *thd,
     if (key->generated)
       key_info->flags|= HA_GENERATED_KEY;
 
+#ifdef ENABLE_SENNA
+    key_info->senna_flags=key->senna_flags;
+    key_info->senna_initial_n_segments=key->senna_initial_n_segments;
+#endif /* ENABLE_SENNA */
     key_info->key_parts=(uint8) key->columns.elements;
     key_info->key_part=key_part_info;
     key_info->usable_key_parts= key_number;
@@ -1271,6 +1278,9 @@ static int mysql_prepare_table(THD *thd,
 	    DBUG_RETURN(-1);
 	}
 	ft_key_charset=sql_field->charset;
+#ifdef ENABLE_SENNA
+	key_info->senna_encoding=ft_key_charset->csname;
+#endif
 	/*
 	  for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
 	  code anyway, and 0 (set to column width later) for char's. it has
@@ -2834,6 +2844,10 @@ bool mysql_create_like_table(THD* thd, T
 
   DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
 
+#ifdef ENABLE_SENNA
+  create_info->query_type = SENNA_CREATE_TABLE_LIKE;
+#endif
+
   /*
     Validate the destination table
 
@@ -3199,6 +3213,10 @@ view_err:
   if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
     DBUG_RETURN(TRUE);
 
+#ifdef ENABLE_SENNA
+  table->file->info(HA_STATUS_VARIABLE | HA_STATUS_SENNA);
+#endif
+
   /* Check that we are not trying to rename to an existing table */
   if (new_name)
   {
@@ -3646,10 +3664,19 @@ view_err:
       else
         key_type= Key::MULTIPLE;
 
+#ifdef ENABLE_SENNA
+      key= new Key(key_type, key_name,
+		   key_info->algorithm,
+		   test(key_info->flags & HA_GENERATED_KEY),
+		   key_parts,
+		   key_info->senna_flags,
+		   key_info->senna_initial_n_segments);
+#else /* ENABLE_SENNA */
       key= new Key(key_type, key_name,
                    key_info->algorithm,
                    test(key_info->flags & HA_GENERATED_KEY),
                    key_parts);
+#endif /* ENABLE_SENNA */
       new_info.key_list.push_back(key);
     }
   }
--- orig/libmysqld/table.cc	2009-10-16 06:20:38.000000000 +0900
+++ new/libmysqld/table.cc	2009-11-16 17:45:02.000000000 +0900
@@ -109,6 +109,18 @@ int openfrm(THD *thd, const char *name, 
   if (my_read(file,(byte*) head,64,MYF(MY_NABP)))
     goto err;
 
+#ifdef ENABLE_SENNA
+  if (prgflag & SENNA_CHECK_VIEW)
+  {
+    if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW")) == 0)
+    {
+      error_reported = TRUE;
+      error = 0;
+      goto err;
+    }
+  }
+#endif
+
   if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0)
   {
     // new .frm
--- orig/myisam/Makefile.am	2009-10-16 06:19:09.000000000 +0900
+++ new/myisam/Makefile.am	2009-11-16 17:45:02.000000000 +0900
@@ -16,11 +16,13 @@
 EXTRA_DIST =		mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt
 pkgdata_DATA =		mi_test_all mi_test_all.res
 
-INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include
+INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include \
+			@SENNA_INCLUDES@ @MECAB_INCLUDES@
 LDADD =			@CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
 			$(top_builddir)/mysys/libmysys.a \
 			$(top_builddir)/dbug/libdbug.a \
-			$(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+			$(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ \
+			@SENNA_LIBS@ @MECAB_LIBS@
 pkglib_LIBRARIES =	libmyisam.a
 bin_PROGRAMS =		myisamchk myisamlog myisampack myisam_ftdump
 myisamchk_DEPENDENCIES=	$(LIBRARIES)
--- orig/myisam/ft_boolean_search.c	2009-10-16 06:19:09.000000000 +0900
+++ new/myisam/ft_boolean_search.c	2009-11-16 17:45:02.000000000 +0900
@@ -20,6 +20,11 @@
 #define FT_CORE
 #include "ftdefs.h"
 
+#ifdef ENABLE_SENNA
+#include <senna.h>
+#define SENNA_MAX_N_EXPR 32
+#endif /* ENABLE_SENNA */
+
 /* search with boolean queries */
 
 static double _wghts[11]=
@@ -103,6 +108,9 @@ typedef struct st_ft_info
   uint       keynr;
   uchar      with_scan;
   enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE } state;
+#ifdef ENABLE_SENNA
+  sen_records *sir;
+#endif /* ENABLE_SENNA */
 } FTB;
 
 static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b)
@@ -400,6 +408,40 @@ FT_INFO * ft_init_boolean_search(MI_INFO
   DBUG_ASSERT(keynr==NO_SUCH_KEY || cs == info->s->keyinfo[keynr].seg->charset);
   ftb->with_scan=0;
   ftb->lastpos=HA_OFFSET_ERROR;
+#ifdef ENABLE_SENNA
+  if ((ftb->keynr != NO_SUCH_KEY) && ftb->info->s->keyinfo[ftb->keynr].senna)
+  {
+    sen_index *i;
+    sen_query *q;
+    const char *rest;
+    unsigned int rest_len;
+    if (keynr==NO_SUCH_KEY ||
+	!(i = info->s->keyinfo[keynr].senna)) {
+      SEN_LOG(sen_log_warning, "ft_init_boolean_serch: keynr==NO_SUCH_KEY");
+      my_free((gptr)ftb,MYF(0));
+      return 0;
+    }
+    SEN_LOG(sen_log_info, "ft_init_boolean_search => sen_query_open: str='%s', str_len=%d, max_exprs=%d",
+	    query, query_len, SENNA_MAX_N_EXPR);
+    if (!(q = sen_query_open(query, query_len, sen_sel_or, SENNA_MAX_N_EXPR, 
+			     info->s->keyinfo[keynr].senna_encoding))) {
+      SEN_LOG(sen_log_error, "ft_init_boolean_serch: sen_query_open returned error");
+      my_free((gptr)ftb,MYF(0));
+      return 0;
+    }
+    SEN_LOG(sen_log_debug, "ft_init_boolean_search => sen_query_rest: q=%p, rest=%p", q, &rest);
+    if ((rest_len = sen_query_rest(q, &rest))) {
+      SEN_LOG(sen_log_warning, "ft_init_boolean_search: too long query. rest(%.*s) are ignored", rest_len, rest);
+    }
+    SEN_LOG(sen_log_debug, "ft_init_boolean_search => sen_records_open");
+    ftb->sir = sen_records_open(sen_rec_document, sen_rec_none, 0);
+    SEN_LOG(sen_log_info, "ft_init_boolean_search => sen_query_exec: i=%p, q=%p, r=%p", i, q, ftb->sir);
+    sen_query_exec(i, q, ftb->sir, sen_sel_or);
+    SEN_LOG(sen_log_debug, "ft_init_boolean_search => sen_query_close: q=%p", q);
+    sen_query_close(q);
+    return ftb;
+  }
+#endif /* ENABLE_SENNA */ 
   bzero(& ftb->no_dupes, sizeof(TREE));
 
   init_alloc_root(&ftb->mem_root, 1024, 1024);
@@ -559,6 +601,33 @@ static void _ftb_climb_the_tree(FTB *ftb
 
 int ft_boolean_read_next(FT_INFO *ftb, char *record)
 {
+#ifdef ENABLE_SENNA
+  if ((ftb->keynr != NO_SUCH_KEY) && ftb->info->s->keyinfo[ftb->keynr].senna)
+  {
+    my_off_t pos;
+    MI_INFO   *info=ftb->info;
+    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 & SENNA_USE_2IND) {
+	if (!(my_thread_var->sen_flags & (SENNA_IF_READ_RECORD | SENNA_FILESORT))) {
+	  SEN_LOG(sen_log_debug, "ft_boolean_read_next: 2ind return 0");
+	  return 0;
+	}
+      }
+      if (!(*info->read_record)(info,info->lastpos,record)) {
+        info->update|= HA_STATE_AKTIV;          /* Record is read */
+        return 0;
+      }
+      SEN_LOG(sen_log_error, "ft_boolean_read_next: my_errno=%d pos=%lld", my_errno, pos);
+      if (my_errno == 127) { continue; }
+      return my_errno;
+    }
+    return HA_ERR_END_OF_FILE;
+  }
+  else
+#endif /* ENABLE_SENNA */
+ {
   FTB_EXPR  *ftbe;
   FTB_WORD  *ftbw;
   MI_INFO   *info=ftb->info;
@@ -624,11 +693,26 @@ int ft_boolean_read_next(FT_INFO *ftb, c
 err:
   ftb->queue.first_cmp_arg=(void *)0;
   return my_errno;
+ }
 }
 
 
 float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
 {
+#ifdef ENABLE_SENNA
+  if ((ftb->keynr != NO_SUCH_KEY) && ftb->info->s->keyinfo[ftb->keynr].senna)
+  {
+    my_off_t  docid=ftb->info->lastpos;
+    if (!ftb->sir) { return 0.0; }
+    if (docid == HA_OFFSET_ERROR)
+      return -2.0;
+    SEN_LOG(sen_log_dump, "ft_boolean_find_relevance => sen_records_find: records=%p, key=%p",
+	    ftb->sir, &docid);
+    return 1.0 * sen_records_find(ftb->sir, &docid);
+  }
+  else
+#endif /* ENABLE_SENNA */
+ {
   FT_WORD word;
   FTB_WORD *ftbw;
   FTB_EXPR *ftbe;
@@ -733,11 +817,21 @@ float ft_boolean_find_relevance(FT_INFO 
   { /* match failed ! */
     return 0.0;
   }
+ }
 }
 
 
 void ft_boolean_close_search(FT_INFO *ftb)
 {
+#ifdef ENABLE_SENNA
+  if ((ftb->keynr != NO_SUCH_KEY) && ftb->info->s->keyinfo[ftb->keynr].senna)
+  {
+    SEN_LOG(sen_log_debug, "ft_boolean_close_search => sen_records_close: records=%p", ftb->sir);
+    sen_records_close(ftb->sir);
+    my_free((gptr)ftb,MYF(0));
+    return;
+  }
+#endif /* ENABLE_SENNA */
   if (is_tree_inited(& ftb->no_dupes))
   {
     delete_tree(& ftb->no_dupes);
@@ -749,12 +843,28 @@ void ft_boolean_close_search(FT_INFO *ft
 
 float ft_boolean_get_relevance(FT_INFO *ftb)
 {
+#ifdef ENABLE_SENNA
+  if ((ftb->keynr != NO_SUCH_KEY) && ftb->info->s->keyinfo[ftb->keynr].senna)
+  {
+    if (!ftb->sir) { return 0.0; }
+    SEN_LOG(sen_log_dump, "ft_boolean_get_relevance => sen_records_curr_score: r=%p", ftb->sir);
+    return 1.0 * sen_records_curr_score(ftb->sir);
+  }
+#endif /* ENABLE_SENNA */
   return ftb->root->cur_weight;
 }
 
 
 void ft_boolean_reinit_search(FT_INFO *ftb)
 {
+#ifdef ENABLE_SENNA
+  if ((ftb->keynr != NO_SUCH_KEY) && ftb->info->s->keyinfo[ftb->keynr].senna)
+  {
+    SEN_LOG(sen_log_debug, "ft_boolean_reinit_search => sen_records_rewind: records=%p", ftb->sir);
+    sen_records_rewind(ftb->sir);
+    return;
+  }
+#endif /* ENABLE_SENNA */
   _ftb_init_index_search(ftb);
 }
 
--- orig/myisam/ft_nlq_search.c	2009-10-16 06:19:09.000000000 +0900
+++ new/myisam/ft_nlq_search.c	2009-11-16 17:45:02.000000000 +0900
@@ -32,6 +32,9 @@ struct st_ft_info
   MI_INFO  *info;
   int       ndocs;
   int       curdoc;
+#ifdef ENABLE_SENNA
+  sen_records *sir;
+#endif /* ENABLE_SENNA */
   FT_DOC    doc[1];
 };
 
@@ -209,8 +212,22 @@ FT_INFO *ft_init_nlq_search(MI_INFO *inf
   FT_DOC     *dptr;
   FT_INFO    *dlist=NULL;
   my_off_t    saved_lastpos=info->lastpos;
+#ifdef ENABLE_SENNA
+  sen_records *sir;
+#endif /* ENABLE_SENNA */
   DBUG_ENTER("ft_init_nlq_search");
-
+#ifdef ENABLE_SENNA
+  if (info->s->keyinfo[keynr].senna)
+  {
+    SEN_LOG(sen_log_info, "ft_init_nlq_search => sen_index_sel index=%p, string='%s', string_len=%d",
+	    info->s->keyinfo[keynr].senna, query, query_len);
+    sir = sen_index_sel(info->s->keyinfo[keynr].senna, query, query_len);
+  }
+  else
+  {
+    sir = NULL;
+  }
+#endif /* ENABLE_SENNA */
 /* black magic ON */
   if ((int) (keynr = _mi_check_index(info,keynr)) < 0)
     DBUG_RETURN(NULL);
@@ -277,6 +294,9 @@ FT_INFO *ft_init_nlq_search(MI_INFO *inf
   dlist->info=aio.info;
   dptr=dlist->doc;
 
+#ifdef ENABLE_SENNA
+  dlist->sir = sir;
+#endif /* ENABLE_SENNA */
   tree_walk(&aio.dtree, (tree_walk_action) &walk_and_copy,
 	    &dptr, left_root_right);
 
@@ -295,6 +315,33 @@ err:
 int ft_nlq_read_next(FT_INFO *handler, char *record)
 {
   MI_INFO *info= (MI_INFO *) handler->info;
+#ifdef ENABLE_SENNA
+  if (handler->sir)
+  {
+    my_off_t pos;
+    info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+    SEN_LOG(sen_log_dump, "ft_nlq_read_next => sen_records_next in while loop");
+    while (sen_records_next(handler->sir, &pos, sizeof(my_off_t), NULL))
+    {
+      info->lastpos=pos;
+      if (my_thread_var->sen_flags & SENNA_USE_2IND) {
+	if (!(my_thread_var->sen_flags & (SENNA_IF_READ_RECORD | SENNA_FILESORT))) {
+	  SEN_LOG(sen_log_debug, "ft_nlq_read_next => 2ind return 0");
+	  return 0;
+	}
+      }
+      if (!(*info->read_record)(info,info->lastpos,record))
+      {
+	info->update|= HA_STATE_AKTIV;		/* Record is read */
+	return 0;
+      }
+      SEN_LOG(sen_log_error, "ft_nlq_read_next => my_errno=%d pos=%lld", my_errno, pos);
+      if (my_errno == 127) { continue; }
+      return my_errno;
+    }
+    return HA_ERR_END_OF_FILE;
+  }
+#endif /* ENABLE_SENNA */
 
   if (++handler->curdoc >= handler->ndocs)
   {
@@ -325,6 +372,14 @@ float ft_nlq_find_relevance(FT_INFO *han
   if (docid == HA_POS_ERROR)
     return -5.0;
 
+#ifdef ENABLE_SENNA
+  if (handler->sir) {
+    SEN_LOG(sen_log_dump, "ft_nlq_find_relevance => sen_records_find: records=%p, key=%p",
+	    handler->sir, &docid);
+    return 1.0 * sen_records_find(handler->sir, &docid);
+  }
+#endif /* ENABLE_SENNA */
+
   /* Assuming docs[] is sorted by dpos... */
 
   for (a=0, b=handler->ndocs, c=(a+b)/2; b-a>1; c=(a+b)/2)
@@ -344,18 +399,46 @@ float ft_nlq_find_relevance(FT_INFO *han
 
 void ft_nlq_close_search(FT_INFO *handler)
 {
+#ifdef ENABLE_SENNA
+  if (handler->sir)
+  {
+    SEN_LOG(sen_log_debug, "ft_nlq_close_search => sen_records_close: records=%p",
+	    handler->sir);
+    sen_records_close(handler->sir);
+  }
+#endif /* ENABLE_SENNA */
   my_free((gptr)handler,MYF(0));
 }
 
 
 float ft_nlq_get_relevance(FT_INFO *handler)
 {
+#ifdef ENABLE_SENNA
+  if (!handler->sir) {
+    if (handler->doc) {
+      return (float) handler->doc[handler->curdoc].weight;
+    }
+    return 0.0; 
+  }
+  SEN_LOG(sen_log_dump, "ft_nlq_get_relevance => sen_records_curr_score: r=%p",
+	  handler->sir);
+  return 1.0 * sen_records_curr_score(handler->sir);
+#else /* ENABLE_SENNA */
   return (float) handler->doc[handler->curdoc].weight;
+#endif /* ENABLE_SENNA */
 }
 
 
 void ft_nlq_reinit_search(FT_INFO *handler)
 {
+#ifdef ENABLE_SENNA
+  if (handler->sir)
+  {
+    SEN_LOG(sen_log_debug, "ft_nlq_reinit_search => sen_records_rewind: r=%p",
+	    handler->sir);
+    sen_records_rewind(handler->sir);
+  }
+#endif /* ENABLE_SENNA */
   handler->curdoc=-1;
 }
 
--- orig/myisam/ft_update.c	2009-10-16 06:19:09.000000000 +0900
+++ new/myisam/ft_update.c	2009-11-16 17:45:02.000000000 +0900
@@ -114,6 +114,19 @@ uint _mi_ft_parse(TREE *parsed, MI_INFO 
 
 FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, const byte *record)
 {
+#ifdef ENABLE_SENNA
+  if (info->s->keyinfo[keynr].senna)
+  {
+    FT_WORD *wlist;
+    if (!(wlist = (FT_WORD *) my_malloc(sizeof(FT_WORD), MYF(0)))) {
+      return NULL;
+    }
+    wlist->pos = 0;
+    return wlist;
+  }
+  else
+#endif /* ENABLE_SENNA */
+ {
   TREE ptree;
   DBUG_ENTER("_mi_ft_parserecord");
 
@@ -122,6 +135,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *in
     DBUG_RETURN(NULL);
 
   DBUG_RETURN(ft_linearize(&ptree));
+ }
 }
 
 static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf,
@@ -186,6 +200,129 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr
   DBUG_RETURN(GEE_THEY_ARE_ABSOLUTELY_IDENTICAL);
 }
 
+#ifdef ENABLE_SENNA
+#define SECTIONALIZE 0x00080000
+int ft_sen_index_add(MI_INFO *info, uint keynr, const byte *record, my_off_t pos)
+{
+  DBUG_ENTER("ft_sen_index_add");
+  if (info->s->keyinfo[keynr].senna_flags & SECTIONALIZE) {
+    FT_SEG_ITERATOR ftsi;
+    unsigned int section;
+    sen_values *values;
+    _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+    while (_mi_ft_segiterator(&ftsi)) {
+      if (ftsi.pos) {
+	if (ftsi.len > 1048576) { SEN_LOG(sen_log_debug, "ft_sen_index_add: ftsi.len=%d", ftsi.len); }
+      }
+    }
+    _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+    while (_mi_ft_segiterator(&ftsi)) {
+      if (ftsi.pos) {
+	section = ftsi.num + 1;
+	SEN_LOG(sen_log_debug, "ft_sen_index_add => sen_values_open");
+	values = sen_values_open();
+	SEN_LOG(sen_log_debug, "ft_sen_index_add => sen_values_add: values=%p, str=%s, str_len=%d, weight=%d",
+		values, ftsi.pos, ftsi.len, 0);
+	sen_values_add(values, ftsi.pos, ftsi.len, 0);
+	SEN_LOG(sen_log_info, "ft_sen_index_add => sen_index_update: index=%p, key=%p (pos=%d), section=%d, oldvalue=%p, newvalue=%p",
+		info->s->keyinfo[keynr].senna, &pos, (uint) pos,  section, NULL, values);
+	sen_index_update(info->s->keyinfo[keynr].senna, &pos, ftsi.num+1, NULL, values);
+	SEN_LOG(sen_log_debug, "ft_sen_index_add => sen_values_close: values=%p", values);
+	sen_values_close(values);
+      }
+    }
+    DBUG_RETURN(0);
+  } else {
+    FT_SEG_ITERATOR ftsi;
+    char *buf, *p;
+    uint len = 0;
+    _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+    while (_mi_ft_segiterator(&ftsi)) {
+      if (ftsi.pos) {
+	if (ftsi.len > 1048576) { SEN_LOG(sen_log_debug, "ft_sen_index_add: ftsi.len=%d", ftsi.len); }
+	len += ftsi.len + 1;
+      }
+    }
+    if (!len) { return -1; }
+    if (!(p = buf = malloc(len))) { return -1; }
+    _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+    while (_mi_ft_segiterator(&ftsi)) {
+      if (ftsi.pos) {
+	if (p != buf) { *p++ = ' '; }
+	memcpy(p, ftsi.pos, ftsi.len);
+	p += ftsi.len;
+      }
+    }
+    *p = '\0';
+    SEN_LOG(sen_log_info, "ft_sen_index_add => sen_index_upd: index=%p, key=%p (pos=%d), oldvalue=%s,"
+	    "oldvalue_len=%d, newvalue=%s, newvalue_len=%d",
+	    info->s->keyinfo[keynr].senna, &pos, (uint) pos, NULL, 0, buf, (p - buf));
+    sen_index_upd(info->s->keyinfo[keynr].senna, &pos, NULL, 0, buf, (p - buf));
+    free(buf);
+    DBUG_RETURN(0);
+  }
+}
+
+int ft_sen_index_del(MI_INFO *info, uint keynr, const byte *record, my_off_t pos)
+{
+  if (info->s->keyinfo[keynr].senna_flags & SECTIONALIZE) {
+    FT_SEG_ITERATOR ftsi;
+    unsigned int section;
+    sen_values *values;
+    _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+    while (_mi_ft_segiterator(&ftsi)) {
+      if (ftsi.pos) {
+	if (ftsi.len > 1048576) { SEN_LOG(sen_log_debug, "ft_sen_index_del: ftsi.len=%d", ftsi.len); }
+      }
+    }
+    _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+    while (_mi_ft_segiterator(&ftsi)) {
+      if (ftsi.pos) {
+	section = ftsi.num + 1;
+        SEN_LOG(sen_log_debug, "ft_sen_index_del => sen_values_open");
+        values = sen_values_open();
+        SEN_LOG(sen_log_debug, "ft_sen_index_del => sen_values_add: values=%p, str=%s, str_len=%d, weight=%d",
+                values, ftsi.pos, ftsi.len, 0);
+        sen_values_add(values, ftsi.pos, ftsi.len, 0);
+        SEN_LOG(sen_log_info, "ft_sen_index_del => sen_index_update: index=%p, key=%p (pos=%d), section=%d, oldvalue=%p, newvalue=%p",
+                info->s->keyinfo[keynr].senna, &pos, (uint) pos, section, values, NULL);
+        sen_index_update(info->s->keyinfo[keynr].senna, &pos, section, values, NULL);
+        SEN_LOG(sen_log_debug, "ft_sen_index_del => sen_values_close: values=%p", values);
+        sen_values_close(values);
+      }
+    }
+    return 0;
+  } else {
+    FT_SEG_ITERATOR ftsi;
+    char *buf, *p;
+    uint len = 0;
+    _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+    while (_mi_ft_segiterator(&ftsi)) {
+      if (ftsi.pos) {
+	if (ftsi.len > 1048576) { SEN_LOG(sen_log_debug, "ft_sen_index_del: ftsi.len=%d", ftsi.len); }
+	len += ftsi.len + 1;
+      }
+    }
+    if (!len) { return -1; }
+    if (!(p = buf = malloc(len))) { return -1; }
+    _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+    while (_mi_ft_segiterator(&ftsi)) {
+      if (ftsi.pos) {
+	if (p != buf) { *p++ = ' '; }
+	memcpy(p, ftsi.pos, ftsi.len);
+	p += ftsi.len;
+      }
+    }
+    *p = '\0';
+    SEN_LOG(sen_log_info, "ft_sen_index_add => sen_index_upd: index=%p, key=%p (pos=%d), oldvalue=%p,"
+            "oldvalue_len=%d, newvalue=%p, newvalue_len=%d",
+            info->s->keyinfo[keynr].senna, &pos, (uint) pos, buf, (p - buf), NULL, 0);
+    sen_index_upd(info->s->keyinfo[keynr].senna, &pos, buf, (p - buf), NULL, 0);
+    free(buf);
+    return 0;
+  }
+}
+#endif /* ENABLE_SENNA */
 
 /* update a document entry */
 
@@ -199,6 +336,13 @@ int _mi_ft_update(MI_INFO *info, uint ke
   int cmp, cmp2;
   DBUG_ENTER("_mi_ft_update");
 
+#ifdef ENABLE_SENNA
+  if (info->s->keyinfo[keynr].senna)
+  {
+    ft_sen_index_del(info, keynr, oldrec, pos);
+    ft_sen_index_add(info, keynr, newrec, pos);
+  }
+#endif /* ENABLE_SENNA */
   if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, oldrec)))
     goto err0;
   if (!(new_word=newlist=_mi_ft_parserecord(info, keynr, newrec)))
@@ -249,6 +393,10 @@ int _mi_ft_add(MI_INFO *info, uint keynr
   FT_WORD *wlist;
   DBUG_ENTER("_mi_ft_add");
 
+#ifdef ENABLE_SENNA
+  if (info->s->keyinfo[keynr].senna)
+    ft_sen_index_add(info, keynr, record, pos);
+#endif /* ENABLE_SENNA */
   if ((wlist=_mi_ft_parserecord(info, keynr, record)))
   {
     error=_mi_ft_store(info,keynr,keybuf,wlist,pos);
@@ -268,6 +416,10 @@ int _mi_ft_del(MI_INFO *info, uint keynr
   DBUG_ENTER("_mi_ft_del");
   DBUG_PRINT("enter",("keynr: %d",keynr));
 
+#ifdef ENABLE_SENNA
+  if (info->s->keyinfo[keynr].senna)
+    ft_sen_index_del(info, keynr, record, pos);
+#endif /* ENABLE_SENNA */
   if ((wlist=_mi_ft_parserecord(info, keynr, record)))
   {
     error=_mi_ft_erase(info,keynr,keybuf,wlist,pos);
@@ -351,3 +503,43 @@ uint _mi_ft_convert_to_ft2(MI_INFO *info
                                      SEARCH_SAME));
 }
 
+#ifdef ENABLE_SENNA
+/*
+  this function is called by myisamchk only.
+*/
+void ft_sen_index_truncate(MI_INFO *info)
+{
+  char buf[FN_REFLEN];
+  MYISAM_SHARE *share= info->s;
+  uint i, keys= (uint) share->state.header.keys;
+  DBUG_ENTER("ft_sen_index_truncate");
+  for (i=0 ; i < keys ; i++)
+  {
+    if (share->keyinfo[i].flag & HA_FULLTEXT)
+    {
+      if (share->keyinfo[i].senna)
+      {
+        sen_index_close(share->keyinfo[i].senna);
+      }
+      strcpy(buf, share->unique_file_name);
+      sprintf(buf + strlen(buf) - 3, "%03d", i);
+      if (share->keyinfo[i].senna_flags & SEN_DISABLE_SENNA)
+      {
+        share->keyinfo[i].senna = NULL;
+      } else {
+        if (!(share->keyinfo[i].senna_encoding >= 0 && share->keyinfo[i].senna_encoding <= 6))
+        {
+          share->keyinfo[i].senna = NULL;
+          DBUG_VOID_RETURN;
+        } else {
+          share->keyinfo[i].senna = sen_index_create(buf, sizeof(my_off_t),
+                                                     share->keyinfo[i].senna_flags,
+                                                     share->keyinfo[i].senna_initial_n_segments,
+                                                     share->keyinfo[i].senna_encoding);
+        }
+      }
+    }
+  }
+  DBUG_VOID_RETURN;
+}
+#endif /* ENABLE_SENNA */
--- orig/myisam/fulltext.h	2009-10-16 06:19:09.000000000 +0900
+++ new/myisam/fulltext.h	2009-11-16 17:45:02.000000000 +0900
@@ -35,3 +35,7 @@ int  _mi_ft_del(MI_INFO *, uint, byte *,
 
 uint _mi_ft_convert_to_ft2(MI_INFO *, uint, uchar *);
 
+#ifdef ENABLE_SENNA 
+int ft_sen_index_add(MI_INFO *info, uint keynr, const byte *record, my_off_t pos);
+void ft_sen_index_truncate(MI_INFO *info);
+#endif
--- orig/myisam/mi_check.c	2009-10-16 06:19:09.000000000 +0900
+++ new/myisam/mi_check.c	2009-11-16 17:45:02.000000000 +0900
@@ -3130,6 +3130,11 @@ static int sort_ft_key_read(MI_SORT_PARA
       my_free((char*) wptr, MYF(MY_ALLOW_ZERO_PTR));
       if ((error=sort_get_next_record(sort_param)))
         DBUG_RETURN(error);
+#ifdef ENABLE_SENNA
+      if (info->s->keyinfo[sort_param->key].senna) {
+	ft_sen_index_add(info, sort_param->key, sort_param->record, sort_param->filepos);
+      }
+#endif /* ENABLE_SENNA */
       if (!(wptr=_mi_ft_parserecord(info,sort_param->key,sort_param->record)))
         DBUG_RETURN(1);
       if (wptr->pos)
--- orig/myisam/mi_close.c	2009-10-16 06:19:09.000000000 +0900
+++ new/myisam/mi_close.c	2009-11-16 17:45:02.000000000 +0900
@@ -30,7 +30,6 @@ int mi_close(register MI_INFO *info)
   DBUG_PRINT("enter",("base: 0x%lx  reopen: %u  locks: %u",
 		      (long) info, (uint) share->reopen,
                       (uint) share->tot_locks));
-
   pthread_mutex_lock(&THR_LOCK_myisam);
   if (info->lock_type == F_EXTRA_LCK)
     info->lock_type=F_UNLCK;			/* HA_EXTRA_NO_USER_CHANGE */
@@ -98,6 +97,26 @@ int mi_close(register MI_INFO *info)
       keys = share->state.header.keys;
       for(i=0; i<keys; i++) {
 	VOID(rwlock_destroy(&share->key_root_lock[i]));
+
+#ifdef ENABLE_SENNA
+	if (share->keyinfo[i].flag & HA_FULLTEXT)
+	{
+	  {
+	    char buf[FN_REFLEN];
+	    strncpy(buf, share->unique_file_name, FN_REFLEN - 1);
+	    buf[FN_REFLEN - 1] = '\0';
+	    sprintf(buf + strlen(buf) - 3, "%03d", i);
+	    if (share->keyinfo[i].senna) {
+	      SEN_LOG(sen_log_notice, "mi_close => sen_index_close: "
+		      "delay_key_write=%d, unique_file_name=%s, data_file_name=%s, index_file_name=%s",
+		      share->delay_key_write, share->unique_file_name, share->data_file_name, share->index_file_name);
+	      sen_index_close(share->keyinfo[i].senna);
+	    }
+	  }
+	}
+#endif /* ENABLE_SENNA */
+
+
       }
     }
 #endif
--- orig/myisam/mi_create.c	2009-10-16 06:19:09.000000000 +0900
+++ new/myisam/mi_create.c	2009-11-16 17:45:02.000000000 +0900
@@ -284,6 +284,59 @@ int mi_create(const char *name,uint keys
     }
     else if (keydef->flag & HA_FULLTEXT)
     {
+#ifdef ENABLE_SENNA
+      sen_index *senna;
+      char buf[FN_REFLEN];
+      strncpy(buf, name, FN_REFLEN - 1);
+      buf[FN_REFLEN - 1] = '\0';
+      sprintf(buf + strlen(buf), ".%03d", i);
+      if (!(keydef->senna_flags & SEN_DISABLE_SENNA))
+      {
+	/* make index files */
+	SEN_LOG(sen_log_notice,
+		"mi_create => sen_index_create: path=%s, key_size=%d, flags=%x, ins=%d", buf,
+		sizeof(my_off_t), keydef->senna_flags, keydef->senna_initial_n_segments);
+        if (!(keydef->senna_encoding >= 0 && keydef->senna_encoding <= 6))
+        {
+          my_errno= HA_WRONG_CREATE_OPTION;
+          goto err;
+        }
+	senna = sen_index_create(buf, sizeof(my_off_t),
+				 keydef->senna_flags,
+				 keydef->senna_initial_n_segments,
+				 keydef->senna_encoding);
+	SEN_LOG(sen_log_notice, "mi_create => sen_index_close: index=%p", senna);
+	sen_index_close(senna);
+      } else {
+	SEN_LOG(sen_log_notice, "mi_create => sen_index_open: path=%s", buf);
+	senna = sen_index_open(buf);
+	if (senna) {
+	  int senna_flags, senna_initial_n_segments;
+	  sen_encoding senna_encoding;
+	  SEN_LOG(sen_log_info, "mi_create => sen_index_info: index=%p", senna);
+	  sen_index_info(senna, NULL, &senna_flags, &senna_initial_n_segments,
+			 &senna_encoding, NULL, NULL, NULL, NULL, NULL, NULL);
+	  SEN_LOG(sen_log_notice, "mi_create => sen_index_close: index=%p", senna);
+	  sen_index_close(senna);
+	  SEN_LOG(sen_log_notice, "mi_create => sen_index_remove: path=%s", buf);
+	  sen_index_remove(buf);
+	  SEN_LOG(sen_log_notice,
+		  "mi_create => sen_index_create: path=%s, key_size=%d, flags=%x ins=%d)", buf,
+		  sizeof(my_off_t), senna_flags, senna_initial_n_segments);
+        if (!(senna_encoding >= 0 && senna_encoding <= 6))
+        {
+          my_errno= HA_WRONG_CREATE_OPTION;
+          goto err;
+        }
+	  senna = sen_index_create(buf, sizeof(my_off_t),
+				   senna_flags,
+				   senna_initial_n_segments,
+				   senna_encoding);
+	  SEN_LOG(sen_log_notice, "mi_create => sen_index_close: index=%p", senna);
+	  sen_index_close(senna);
+	}
+      }
+#endif /* ENABLE_SENNA */
       keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY;
       options|=HA_OPTION_PACK_KEYS;             /* Using packed keys */
 
--- orig/myisam/mi_delete_all.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/mi_delete_all.c	2009-11-16 17:45:02.000000000 +0900
@@ -34,6 +34,34 @@ int mi_delete_all_rows(MI_INFO *info)
   if (_mi_mark_file_changed(info))
     goto err;
 
+#ifdef ENABLE_SENNA
+  for (i = 0; i < share->base.keys; i++) {
+    sen_index *senna = share->keyinfo[i].senna;
+    if (senna)
+    {
+      char buf[FN_REFLEN];
+      if (!(share->keyinfo[i].senna_encoding >= 0 && share->keyinfo[i].senna_encoding <= 6))
+      {
+        my_errno= HA_WRONG_CREATE_OPTION;
+        goto err;
+      }
+      SEN_LOG(sen_log_debug, "mi_delete_all_rows => sen_index_path: index=%p, buf=%s", senna, buf);
+      sen_index_path(senna, buf, FN_REFLEN);
+      SEN_LOG(sen_log_notice, "mi_delete_all_rows => sen_index_close: index=%p", senna);
+      sen_index_close(senna);
+      SEN_LOG(sen_log_notice, "mi_delete_all_rows => sen_index_remove: buf=%s", buf);
+      sen_index_remove(buf);
+      SEN_LOG(sen_log_notice, "mi_delete_all_rows => sen_index_create: path=%s, flags=%x, ins=%d",
+	      buf, share->keyinfo[i].senna_flags, share->keyinfo[i].senna_initial_n_segments);
+      senna = sen_index_create(buf, sizeof(my_off_t),
+			       share->keyinfo[i].senna_flags,
+			       share->keyinfo[i].senna_initial_n_segments,
+			       share->keyinfo[i].senna_encoding);
+      share->keyinfo[i].senna = senna;
+    }
+  }
+#endif /* ENABLE_SENNA */
+
   info->state->records=info->state->del=state->split=0;
   state->dellink = HA_OFFSET_ERROR;
   state->sortkey=  (ushort) ~0;
--- orig/myisam/mi_delete_table.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/mi_delete_table.c	2009-11-16 17:45:02.000000000 +0900
@@ -57,6 +57,32 @@ int mi_delete_table(const char *name)
 #endif
 #endif /* USE_RAID */
 
+#ifdef ENABLE_SENNA
+  {
+    int i,j,keys;
+    int should_be_deleted[1024];
+    MI_INFO *mi_info;
+    MI_INFO cp_of_mi_info;
+
+    if (!(mi_info = mi_open(name, O_RDONLY, 0)))
+    {  
+      SEN_LOG(sen_log_warning, "mi_delete_table => cannot get MI_INFO");
+      DBUG_RETURN(my_errno);
+    }
+    keys = mi_info->s->base.keys;
+    for (i=0,j=0; i<keys; i++)
+    {
+      if (mi_info->s->keyinfo[i].senna) should_be_deleted[j++]=i;
+    }
+    mi_close(mi_info);
+    for (i=0; i<j; i++)
+    {
+      my_snprintf(from, FN_REFLEN, "%s.%03d", name, should_be_deleted[i]);
+      SEN_LOG(sen_log_notice, "mi_delete_table => sen_index_remove: path=%s", from);
+      sen_index_remove(from);
+    }
+  }
+#endif /* ENABLE_SENNA */
   fn_format(from,name,"",MI_NAME_IEXT,4);
   if (my_delete_with_symlink(from, MYF(MY_WME)))
     DBUG_RETURN(my_errno);
--- orig/myisam/mi_info.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/mi_info.c	2009-11-16 17:45:02.000000000 +0900
@@ -60,6 +60,26 @@ int mi_status(MI_INFO *info, register MI
     x->mean_reclength= x->records ?
       (ulong) ((x->data_file_length - x->delete_length) / x->records) :
       (ulong) share->min_pack_length;
+#ifdef ENABLE_SENNA
+    if ((flag & HA_STATUS_SENNA) && share->keyinfo) 
+    {
+      int i;
+      for (i = 0; i < share->base.keys; i++)
+      {
+	MI_KEYDEF *keydef = &share->keyinfo[i];
+	sen_index *senna = keydef->senna;
+	if (senna)
+	{
+	  SEN_LOG(sen_log_info, "mi_info => sen_index_info: index=%p", senna);
+	  sen_index_info(senna, NULL, &keydef->senna_flags,
+			 &keydef->senna_initial_n_segments, &keydef->senna_encoding,
+			 &keydef->senna_keys_size, &keydef->senna_keys_file_size,
+			 &keydef->senna_lexicon_size, &keydef->senna_lexicon_file_size,
+			 &keydef->senna_inv_seg_size, &keydef->senna_inv_chunk_size);
+	}
+      }
+    }
+#endif /* ENABLE_SENNA */
   }
   if (flag & HA_STATUS_ERRKEY)
   {
--- orig/myisam/mi_open.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/mi_open.c	2009-11-16 17:45:02.000000000 +0900
@@ -357,6 +357,11 @@ MI_INFO *mi_open(const char *name, int m
 	  else if (pos->type == HA_KEYTYPE_BINARY)
 	    pos->charset= &my_charset_bin;
 	}
+#ifdef ENABLE_SENNA
+	share->keyinfo[i].senna = NULL;
+	share->keyinfo[i].senna_flags = 0;
+	share->keyinfo[i].senna_initial_n_segments = 0;
+#endif /* ENABLE_SENNA */
 	if (share->keyinfo[i].flag & HA_SPATIAL)
 	{
 #ifdef HAVE_SPATIAL
@@ -370,6 +375,29 @@ MI_INFO *mi_open(const char *name, int m
 	}
         else if (share->keyinfo[i].flag & HA_FULLTEXT)
 	{
+#ifdef ENABLE_SENNA
+	  if (!(share->keyinfo[i].senna_flags & SEN_DISABLE_SENNA))
+	  {
+	    {
+	      char buf[FN_REFLEN];
+	      strncpy(buf, share->unique_file_name, FN_REFLEN - 1);
+	      buf[FN_REFLEN - 1] = '\0';
+	      sprintf(buf + strlen(buf) - 3, "%03d", i);
+	      SEN_LOG(sen_log_notice, "mi_open => "
+		      "sen_index_open: path=%s, delay_key_write=%d, unique_file_name=%s, data_file_name=%s, " 
+		      "index_file_name=%s, keyinfo[%d].seg=%d", 
+		      buf, share->delay_key_write, share->unique_file_name, share->data_file_name,
+		      share->index_file_name, i, pos-FT_SEGS);
+	      share->keyinfo[i].senna = sen_index_open(buf);
+	      SEN_LOG(sen_log_info, "mi_open => sen_index_info: index=%p", share->keyinfo[i].senna);
+	      sen_index_info(share->keyinfo[i].senna, NULL,
+			     &share->keyinfo[i].senna_flags,
+			     &share->keyinfo[i].senna_initial_n_segments,
+			     &share->keyinfo[i].senna_encoding,
+                             NULL, NULL, NULL, NULL, NULL, NULL);
+	    }
+	  }
+#endif /* ENABLE_SENNA */
           if (!fulltext_keys)
           { /* 4.0 compatibility code, to be removed in 5.0 */
             share->keyinfo[i].seg=pos-FT_SEGS;
--- orig/myisam/mi_rename.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/mi_rename.c	2009-11-16 17:45:02.000000000 +0900
@@ -45,6 +45,30 @@ int mi_rename(const char *old_name, cons
 #endif
 #endif /* USE_RAID */
 
+#ifdef ENABLE_SENNA /* nkjm modified 2007/06/04 SFID:10291 */
+  {
+    int i, j;
+    MI_INFO *mi_info;
+    int senna_indexes[MAX_INDEXES];
+    
+    if (!(mi_info = mi_open(old_name, O_RDONLY, 0)))
+    {
+      SEN_LOG(sen_log_warning, "mi_rename => cannot get MI_INFO");
+      DBUG_RETURN(my_errno);
+    }
+    for (i = 0, j = 0; i < mi_info->s->base.keys; i++)
+      if (mi_info->s->keyinfo[i].senna)
+	senna_indexes[j++] = i;
+    mi_close(mi_info);
+    for (i = 0; i < j; i++)
+    {
+      my_snprintf(from, FN_REFLEN, "%s.%03d", old_name, senna_indexes[i]);
+      my_snprintf(to, FN_REFLEN, "%s.%03d", new_name, senna_indexes[i]);
+      SEN_LOG(sen_log_notice, "mi_rename => sen_index_rename: from=%s, to=%s", from, to);
+      sen_index_rename(from, to);
+    }
+  }
+#endif /* ENABLE_SENNA */
   fn_format(from,old_name,"",MI_NAME_IEXT,4);
   fn_format(to,new_name,"",MI_NAME_IEXT,4);
   if (my_rename_with_symlink(from, to, MYF(MY_WME)))
--- orig/myisam/myisam_ftdump.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/myisam_ftdump.c	2009-11-16 17:45:02.000000000 +0900
@@ -63,6 +63,9 @@ int main(int argc,char *argv[])
   struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */
 
   MY_INIT(argv[0]);
+#ifdef ENABLE_SENNA
+  sen_init();
+#endif /* ENABLE_SENNA */
   if ((error= handle_options(&argc, &argv, my_long_options, get_one_option)))
     exit(error);
   if (count || dump)
--- orig/myisam/myisamchk.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/myisamchk.c	2009-11-16 17:45:02.000000000 +0900
@@ -101,6 +101,9 @@ int main(int argc, char **argv)
   get_options(&argc,(char***) &argv);
   myisam_quick_table_bits=decode_bits;
   error=0;
+#ifdef ENABLE_SENNA
+  sen_init();
+#endif /* ENABLE_SENNA */
   while (--argc >= 0)
   {
     int new_error=myisamchk(&check_param, *(argv++));
@@ -1010,6 +1013,9 @@ static int myisamchk(MI_CHECK *param, my
       }
       if (!error)
       {
+#ifdef ENABLE_SENNA
+	ft_sen_index_truncate(info);
+#endif /* ENABLE_SENNA */
 	if ((param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL)) &&
 	    (mi_is_any_key_active(share->state.key_map) ||
 	     (rep_quick && !param->keys_in_use && !recreate)) &&
@@ -1066,6 +1072,9 @@ static int myisamchk(MI_CHECK *param, my
 	  {
 	    if (param->verbose)
 	      puts("Table had a compressed index;  We must now recreate the index");
+#ifdef ENABLE_SENNA
+	    ft_sen_index_truncate(info);
+#endif /* ENABLE_SENNA */
 	    error=mi_repair_by_sort(param,info,filename,1);
 	  }
 	}
--- orig/myisam/myisamlog.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/myisamlog.c	2009-11-16 17:45:02.000000000 +0900
@@ -84,6 +84,9 @@ int main(int argc, char **argv)
   int error,i,first;
   ulong total_count,total_error,total_recover;
   MY_INIT(argv[0]);
+#ifdef ENABLE_SENNA
+  sen_init();
+#endif /* ENABLE_SENNA */
 
   log_filename=myisam_log_filename;
   get_options(&argc,&argv);
--- orig/myisam/myisampack.c	2009-10-16 06:19:10.000000000 +0900
+++ new/myisam/myisampack.c	2009-11-16 17:45:02.000000000 +0900
@@ -207,6 +207,9 @@ int main(int argc, char **argv)
   PACK_MRG_INFO merge;
   char **default_argv;
   MY_INIT(argv[0]);
+#ifdef ENABLE_SENNA
+  sen_init();
+#endif /* ENABLE_SENNA */
 
   load_defaults("my",load_default_groups,&argc,&argv);
   default_argv= argv;
--- orig/myisammrg/Makefile.am	2009-10-16 06:19:11.000000000 +0900
+++ new/myisammrg/Makefile.am	2009-11-16 17:45:02.000000000 +0900
@@ -13,7 +13,8 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include
+INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include \
+			@SENNA_INCLUDES@ @MECAB_INCLUDES@
 pkglib_LIBRARIES =	libmyisammrg.a
 noinst_HEADERS =	myrg_def.h
 libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
--- orig/mysql-test/suite/mecab/r/mecab_utf8.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/mecab/r/mecab_utf8.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,798 @@
+SET NAMES utf8;
+SELECT "===== TESTS for MeCab started =====";
+===== TESTS for MeCab started =====
+===== TESTS for MeCab started =====
+SELECT "===== creating test data started =====";
+===== creating test data started =====
+===== creating test data started =====
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY AUTO_INCREMENT, 
+c2 TEXT,
+FULLTEXT INDEX ft USING MECAB (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(11) NOT NULL auto_increment,
+  `c2` text,
+  PRIMARY KEY  (`c1`),
+  FULLTEXT KEY `ft` USING MECAB, NORMALIZE, 512 (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	utf8	MECAB	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	宛名書きは住商情報システム㈱でお願いいたします。
+20	ファイナルファンタジーⅶを1本下さい。
+21	NEC選定IBM拡張文字の淼について今日はお話いたします。
+22	日本語の文字の種類のひとつとして半角カタカナがある。
+23	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== creating test data finished =====";
+===== creating test data finished =====
+===== creating test data finished =====
+SELECT "===== tests for FULLTEXT search started =====";
+===== tests for FULLTEXT search started =====
+===== tests for FULLTEXT search started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	宛名書きは住商情報システム㈱でお願いいたします。
+20	ファイナルファンタジーⅶを1本下さい。
+21	NEC選定IBM拡張文字の淼について今日はお話いたします。
+22	日本語の文字の種類のひとつとして半角カタカナがある。
+23	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+c1	score	c2
+4	1	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	1	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+c1	score	c2
+7	1	MySQLは優れたセキュリティ機能を提供しています。
+12	2	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+c1	score	c2
+2	5	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	10	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+c1	score	c2
+4	4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+c1	score	c2
+4	9	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+c1	c2
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+c1	c2
+5	信頼性と可用性は、MySQLの大きな特徴です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+19	宛名書きは住商情報システム㈱でお願いいたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+20	ファイナルファンタジーⅶを1本下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+21	NEC選定IBM拡張文字の淼について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+22	日本語の文字の種類のひとつとして半角カタカナがある。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+c1	c2
+23	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== tests for FULLTEXT search finished =====";
+===== tests for FULLTEXT search finished =====
+===== tests for FULLTEXT search finished =====
+SELECT "===== tests for INSERT started =====";
+===== tests for INSERT started =====
+===== tests for INSERT started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	宛名書きは住商情報システム㈱でお願いいたします。
+20	ファイナルファンタジーⅶを1本下さい。
+21	NEC選定IBM拡張文字の淼について今日はお話いたします。
+22	日本語の文字の種類のひとつとして半角カタカナがある。
+23	御両親の印鑑を押してもらって明日持ってきてください、成績表
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+24	普段から緊急事態に備えておかなければならない。
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+19	宛名書きは住商情報システム㈱でお願いいたします。
+25	宛名書きは住商情報システム㈱でお願いいたします。
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+20	ファイナルファンタジーⅶを1本下さい。
+26	ファイナルファンタジーⅶを1本下さい。
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+21	NEC選定IBM拡張文字の淼について今日はお話いたします。
+27	NEC選定IBM拡張文字の淼について今日はお話いたします。
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+22	日本語の文字の種類のひとつとして半角カタカナがある。
+28	日本語の文字の種類のひとつとして半角カタカナがある。
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+c1	c2
+29	職員室に忘れて置いてきてしまった出席表
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	宛名書きは住商情報システム㈱でお願いいたします。
+20	ファイナルファンタジーⅶを1本下さい。
+21	NEC選定IBM拡張文字の淼について今日はお話いたします。
+22	日本語の文字の種類のひとつとして半角カタカナがある。
+23	御両親の印鑑を押してもらって明日持ってきてください、成績表
+24	普段から緊急事態に備えておかなければならない。
+25	宛名書きは住商情報システム㈱でお願いいたします。
+26	ファイナルファンタジーⅶを1本下さい。
+27	NEC選定IBM拡張文字の淼について今日はお話いたします。
+28	日本語の文字の種類のひとつとして半角カタカナがある。
+29	職員室に忘れて置いてきてしまった出席表
+SELECT "===== tests for INSERT finished =====";
+===== tests for INSERT finished =====
+===== tests for INSERT finished =====
+SELECT "===== tests for DELETE started =====";
+===== tests for DELETE started =====
+===== tests for DELETE started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	宛名書きは住商情報システム㈱でお願いいたします。
+20	ファイナルファンタジーⅶを1本下さい。
+21	NEC選定IBM拡張文字の淼について今日はお話いたします。
+22	日本語の文字の種類のひとつとして半角カタカナがある。
+23	御両親の印鑑を押してもらって明日持ってきてください、成績表
+24	普段から緊急事態に備えておかなければならない。
+25	宛名書きは住商情報システム㈱でお願いいたします。
+26	ファイナルファンタジーⅶを1本下さい。
+27	NEC選定IBM拡張文字の淼について今日はお話いたします。
+28	日本語の文字の種類のひとつとして半角カタカナがある。
+29	職員室に忘れて置いてきてしまった出席表
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+c1	c2
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+SELECT "===== tests for DELETE finished =====";
+===== tests for DELETE finished =====
+===== tests for DELETE finished =====
+SELECT "===== tests for errors started =====";
+===== tests for errors started =====
+===== tests for errors started =====
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+ERROR HY000: Can't find FULLTEXT index matching the column list
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT "===== tests for error finished =====";
+===== tests for error finished =====
+===== tests for error finished =====
+DROP TABLE t1;
+SELECT "===== TESTS for MeCab finished =====";
+===== TESTS for MeCab finished =====
+===== TESTS for MeCab finished =====
+SELECT "===== TESTS for Ngram started =====";
+===== TESTS for Ngram started =====
+===== TESTS for Ngram started =====
+SELECT "===== creating test data started =====";
+===== creating test data started =====
+===== creating test data started =====
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY AUTO_INCREMENT, 
+c2 TEXT,
+FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(11) NOT NULL auto_increment,
+  `c2` text,
+  PRIMARY KEY  (`c1`),
+  FULLTEXT KEY `ft` USING NGRAM, NORMALIZE, 512 (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== creating test data finished =====";
+===== creating test data finished =====
+===== creating test data finished =====
+SELECT "===== tests for FULLTEXT search started =====";
+===== tests for FULLTEXT search started =====
+===== tests for FULLTEXT search started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+c1	score	c2
+4	1	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	1	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+c1	score	c2
+7	1	MySQLは優れたセキュリティ機能を提供しています。
+12	2	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+c1	score	c2
+2	5	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	10	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+c1	score	c2
+4	4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+c1	score	c2
+4	9	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+c1	c2
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+19	先生、その件について詳しく教えて下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+c1	c2
+5	信頼性と可用性は、MySQLの大きな特徴です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム㈱でお願いいたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+21	ファイナルファンタジーⅶを1本下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+c1	c2
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== tests for FULLTEXT search finished =====";
+===== tests for FULLTEXT search finished =====
+===== tests for FULLTEXT search finished =====
+SELECT "===== tests for INSERT started =====";
+===== tests for INSERT started =====
+===== tests for INSERT started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+25	普段から緊急事態に備えておかなければならない。
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム㈱でお願いいたします。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+21	ファイナルファンタジーⅶを1本下さい。
+27	ファイナルファンタジーⅶを1本下さい。
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+c1	c2
+30	職員室に忘れて置いてきてしまった出席表
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+27	ファイナルファンタジーⅶを1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+SELECT "===== tests for INSERT finished =====";
+===== tests for INSERT finished =====
+===== tests for INSERT finished =====
+SELECT "===== tests for DELETE started =====";
+===== tests for DELETE started =====
+===== tests for DELETE started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+27	ファイナルファンタジーⅶを1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+c1	c2
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+SELECT "===== tests for DELETE finished =====";
+===== tests for DELETE finished =====
+===== tests for DELETE finished =====
+SELECT "===== tests for errors started =====";
+===== tests for errors started =====
+===== tests for errors started =====
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+ERROR HY000: Can't find FULLTEXT index matching the column list
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT "===== tests for error finished =====";
+===== tests for error finished =====
+===== tests for error finished =====
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
+===== TESTS for Ngram finished =====
+===== TESTS for Ngram finished =====
--- orig/mysql-test/suite/mecab/t/mecab_utf8.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/mecab/t/mecab_utf8.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,318 @@
+# utf8 test
+
+SET NAMES utf8;
+
+# TESTS for MeCab
+SELECT "===== TESTS for MeCab started =====";
+
+SELECT "===== creating test data started =====";
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  c1 INT PRIMARY KEY AUTO_INCREMENT, 
+  c2 TEXT,
+  FULLTEXT INDEX ft USING MECAB (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+SHOW CREATE TABLE t1;
+SHOW SENNA STATUS;
+
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+
+SELECT * FROM t1;
+SELECT "===== creating test data finished =====";
+
+# tests for FULLTEXT search
+
+SELECT "===== tests for FULLTEXT search started =====";
+SELECT * FROM t1;
+
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+
+SELECT "===== tests for FULLTEXT search finished =====";
+
+# tests for INSERT
+
+SELECT "===== tests for INSERT started =====";
+SELECT * FROM t1;
+
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+
+SELECT * FROM t1;
+SELECT "===== tests for INSERT finished =====";
+
+# tests for DELETE
+
+SELECT "===== tests for DELETE started =====";
+SELECT * FROM t1;
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+
+SELECT * FROM t1;
+SELECT "===== tests for DELETE finished =====";
+
+# tests for errors
+
+SELECT "===== tests for errors started =====";
+
+--error 1191
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+
+SELECT "===== tests for error finished =====";
+
+DROP TABLE t1;
+SELECT "===== TESTS for MeCab finished =====";
+
+##########################################################
+
+# TESTS for Ngram
+SELECT "===== TESTS for Ngram started =====";
+
+SELECT "===== creating test data started =====";
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  c1 INT PRIMARY KEY AUTO_INCREMENT, 
+  c2 TEXT,
+  FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+SHOW CREATE TABLE t1;
+SHOW SENNA STATUS;
+
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+
+SELECT * FROM t1;
+SELECT "===== creating test data finished =====";
+
+# tests for FULLTEXT search
+
+SELECT "===== tests for FULLTEXT search started =====";
+SELECT * FROM t1;
+
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+
+SELECT "===== tests for FULLTEXT search finished =====";
+
+# tests for INSERT
+
+SELECT "===== tests for INSERT started =====";
+SELECT * FROM t1;
+
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+
+SELECT * FROM t1;
+SELECT "===== tests for INSERT finished =====";
+
+# tests for DELETE
+
+SELECT "===== tests for DELETE started =====";
+SELECT * FROM t1;
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+
+SELECT * FROM t1;
+SELECT "===== tests for DELETE finished =====";
+
+# tests for errors
+
+SELECT "===== tests for errors started =====";
+
+--error 1191
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+
+SELECT "===== tests for error finished =====";
+
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
--- orig/mysql-test/suite/senna/r/senna_2ind.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_2ind.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,47 @@
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+drop table if exists t1;
+Warnings:
+Note	1051	Unknown table 't1'
+create table t1(c1 int, c2 varchar(255), index(c1)) default charset utf8;
+insert into t1 values (1,"aaa");
+insert into t1 values (2,"aaa");
+insert into t1 values (3,"bbb");
+insert into t1 values (4,"bbb");
+create fulltext index ft using
+ngram,split_alpha,split_digit,split_symbol on t1(c2);
+set senna_2ind=OFF;
+select sum(c1) from t1 where match(c2) against("a");
+sum(c1)
+3
+set senna_2ind=ON;
+select sum(c1) from t1 where match(c2) against("a");
+sum(c1)
+3
+drop table t1;
+drop table if exists test;
+Warnings:
+Note	1051	Unknown table 'test'
+create table test (
+id int not null,
+title varchar(200) not null,
+primary key (id),
+fulltext key fkey1 using ngram, normalize, 512 (title)
+) engine=myisam default charset=utf8;
+INSERT INTO test (id, title) VALUES(1, "今日の天気は晴れです。");
+INSERT INTO test (id, title) VALUES(2, "明日の天気は雨です。");
+set session senna_2ind=ON;
+SELECT * FROM test WHERE MATCH(title) AGAINST("晴れ");
+id	title
+1	今日の天気は晴れです。
+SELECT * FROM test WHERE MATCH(title) AGAINST("雨");
+id	title
+2	明日の天気は雨です。
+SET SESSION senna_2ind=OFF;
+SELECT * FROM test WHERE MATCH(title) AGAINST("晴れ");
+id	title
+1	今日の天気は晴れです。
+SELECT * FROM test WHERE MATCH(title) AGAINST("雨");
+id	title
+2	明日の天気は雨です。
+drop table test;
--- orig/mysql-test/suite/senna/r/senna_cp932.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_cp932.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,404 @@
+SET NAMES utf8;
+SELECT "===== TESTS for Ngram started =====";
+===== TESTS for Ngram started =====
+===== TESTS for Ngram started =====
+SELECT "===== creating test data started =====";
+===== creating test data started =====
+===== creating test data started =====
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY AUTO_INCREMENT, 
+c2 TEXT,
+FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET cp932;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(11) NOT NULL auto_increment,
+  `c2` text,
+  PRIMARY KEY  (`c1`),
+  FULLTEXT KEY `ft` USING NGRAM, NORMALIZE, 512 (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=cp932
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	cp932	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== creating test data finished =====";
+===== creating test data finished =====
+===== creating test data finished =====
+SELECT "===== tests for FULLTEXT search started =====";
+===== tests for FULLTEXT search started =====
+===== tests for FULLTEXT search started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+c1	score	c2
+4	1	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	1	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+c1	score	c2
+7	1	MySQLは優れたセキュリティ機能を提供しています。
+12	2	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+c1	score	c2
+2	5	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	10	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+c1	score	c2
+4	4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+c1	score	c2
+4	9	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+c1	c2
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+19	先生、その件について詳しく教えて下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+c1	c2
+5	信頼性と可用性は、MySQLの大きな特徴です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム㈱でお願いいたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+21	ファイナルファンタジーⅶを1本下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+c1	c2
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== tests for FULLTEXT search finished =====";
+===== tests for FULLTEXT search finished =====
+===== tests for FULLTEXT search finished =====
+SELECT "===== tests for INSERT started =====";
+===== tests for INSERT started =====
+===== tests for INSERT started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+25	普段から緊急事態に備えておかなければならない。
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム㈱でお願いいたします。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+21	ファイナルファンタジーⅶを1本下さい。
+27	ファイナルファンタジーⅶを1本下さい。
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+c1	c2
+30	職員室に忘れて置いてきてしまった出席表
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+27	ファイナルファンタジーⅶを1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+SELECT "===== tests for INSERT finished =====";
+===== tests for INSERT finished =====
+===== tests for INSERT finished =====
+SELECT "===== tests for DELETE started =====";
+===== tests for DELETE started =====
+===== tests for DELETE started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+27	ファイナルファンタジーⅶを1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+c1	c2
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+SELECT "===== tests for DELETE finished =====";
+===== tests for DELETE finished =====
+===== tests for DELETE finished =====
+SELECT "===== tests for errors started =====";
+===== tests for errors started =====
+===== tests for errors started =====
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+ERROR HY000: Can't find FULLTEXT index matching the column list
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT "===== tests for error finished =====";
+===== tests for error finished =====
+===== tests for error finished =====
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
+===== TESTS for Ngram finished =====
+===== TESTS for Ngram finished =====
--- orig/mysql-test/suite/senna/r/senna_create.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_create.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,248 @@
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 CHAR(100),
+c3 VARCHAR(100),
+c4 TINYTEXT,
+c5 TEXT,
+c6 MEDIUMTEXT,
+c7 LONGTEXT,
+FULLTEXT INDEX USING NGRAM (c2),
+FULLTEXT INDEX USING NGRAM (c3),
+FULLTEXT INDEX USING NGRAM (c4),
+FULLTEXT INDEX USING NGRAM (c5),
+FULLTEXT INDEX USING NGRAM (c6),
+FULLTEXT INDEX USING NGRAM (c7)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	c2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	c3	c3	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	c4	c4	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	c5	c5	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	c6	c6	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	c7	c7	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 INT,
+FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+ERROR HY000: Column 'c2' cannot be part of FULLTEXT index
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 DOUBLE,
+FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+ERROR HY000: Column 'c2' cannot be part of FULLTEXT index
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 DATETIME,
+FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+ERROR HY000: Column 'c2' cannot be part of FULLTEXT index
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 BLOB,
+FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+ERROR HY000: Column 'c2' cannot be part of FULLTEXT index
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 CHAR(100),
+FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MEMORY DEFAULT CHARSET utf8;
+ERROR HY000: The used table type doesn't support FULLTEXT indexes
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 CHAR(100),
+FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = InnoDB DEFAULT CHARSET utf8;
+ERROR HY000: The used table type doesn't support FULLTEXT indexes
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 VARCHAR(128),
+c3 TEXT,
+FULLTEXT INDEX USING NGRAM (c2, c3)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	c2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	c2	c3	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 VARCHAR(128),
+c3 TEXT,
+c4 TEXT,
+FULLTEXT INDEX USING NGRAM (c2, c3, c4)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	c2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	c2	c3	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	c2	c4	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 TEXT
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+CREATE FULLTEXT INDEX ft USING NGRAM ON t1(c2);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP INDEX ft ON t1;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 TEXT,
+c3 TEXT,
+c4 TEXT,
+c5 TEXT,
+c6 TEXT,
+c7 TEXT,
+c8 TEXT
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+ALTER TABLE t1 ADD FULLTEXT INDEX ft2 USING NGRAM, 20 (c2);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	20	0	4268032	0	4268032	135168	8192
+ALTER TABLE t1 ADD FULLTEXT INDEX ft3 USING NGRAM, NO NORMALIZE (c3);
+ALTER TABLE t1 ADD FULLTEXT INDEX ft4 USING NGRAM, NO NORMALIZE, 40 (c4);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	20	0	4268032	0	4268032	135168	8192
+t1	ft3	c3	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft4	c4	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	40	0	4268032	0	4268032	135168	12288
+ALTER TABLE t1 ADD FULLTEXT INDEX ft5 USING NGRAM (c5);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	20	0	4268032	0	4268032	135168	8192
+t1	ft3	c3	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft4	c4	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	40	0	4268032	0	4268032	135168	12288
+t1	ft5	c5	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+ALTER TABLE t1 ADD FULLTEXT INDEX ft6 USING NGRAM, NO NORMALIZE (c6);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	20	0	4268032	0	4268032	135168	8192
+t1	ft3	c3	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft4	c4	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	40	0	4268032	0	4268032	135168	12288
+t1	ft5	c5	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft6	c6	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+ALTER TABLE t1 ADD FULLTEXT INDEX ft7 USING NGRAM, 70 (c7);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	20	0	4268032	0	4268032	135168	8192
+t1	ft3	c3	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft4	c4	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	40	0	4268032	0	4268032	135168	12288
+t1	ft5	c5	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft6	c6	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft7	c7	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	70	0	4268032	0	4268032	139264	20480
+ALTER TABLE t1 ADD FULLTEXT INDEX ft8 USING NGRAM, NO NORMALIZE, 80 (c8);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft2	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	20	0	4268032	0	4268032	135168	8192
+t1	ft3	c3	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft4	c4	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	40	0	4268032	0	4268032	135168	12288
+t1	ft5	c5	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft6	c6	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft7	c7	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	70	0	4268032	0	4268032	139264	20480
+t1	ft8	c8	utf8	NGRAM	OFF	OFF	OFF	OFF	OFF	80	0	4268032	0	4268032	139264	24576
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 TEXT
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING DUMMY;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DUMMY' at line 1
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING -100;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-100' at line 1
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING 10, NGRAM;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING NGRAM, 10, NO NORMALIZE;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 TEXT,
+FULLTEXT INDEX ft USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+DROP INDEX dummy ON t1;
+ERROR 42000: Can't DROP 'dummy'; check that column/key exists
+DROP INDEX ft ON t1;
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 TEXT,
+FULLTEXT INDEX ft USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET cp932;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	cp932	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 TEXT CHARSET sjis,
+c3 TEXT CHARSET cp932,
+c4 TEXT CHARSET utf8,
+c5 TEXT CHARSET eucjpms,
+c6 TEXT CHARSET ujis,
+FULLTEXT INDEX ft2 USING NGRAM (c2),
+FULLTEXT INDEX ft3 USING NGRAM (c3),
+FULLTEXT INDEX ft4 USING NGRAM (c4),
+FULLTEXT INDEX ft5 USING NGRAM (c5),
+FULLTEXT INDEX ft6 USING NGRAM (c6)
+) ENGINE = MyISAM;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft2	c2	cp932	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft3	c3	cp932	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft4	c4	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft5	c5	eucjpms	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft6	c6	eucjpms	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+c2 TEXT CHARSET sjis,
+c3 TEXT CHARSET ujis,
+FULLTEXT INDEX ft USING NGRAM (c2, c3)
+) ENGINE = MyISAM;
+ERROR HY000: Column 'c3' cannot be part of FULLTEXT index
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM (c1)) DEFAULT CHARSET utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DELETE FROM t1;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING DELIMITED (c1)) DEFAULT CHARSET utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	DELIMITED	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, c3 INT, c4 TEXT, c5 TEXT) DEFAULT CHARSET utf8;
+CREATE INDEX c2 ON t1(c2);
+CREATE FULLTEXT INDEX ft1 ON t1(c4);
+CREATE FULLTEXT INDEX ft2 USING NGRAM, SECTIONALIZE, 64 ON t1(c5);
+CREATE FULLTEXT INDEX ft3 USING DELIMITED, NO NORMALIZE, 128 ON t1(c5);
+CREATE FULLTEXT INDEX ft4 USING SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL, 48 ON t1(c5);
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(11) NOT NULL,
+  `c2` int(11) default NULL,
+  `c3` int(11) default NULL,
+  `c4` text,
+  `c5` text,
+  PRIMARY KEY  (`c1`),
+  KEY `c2` (`c2`),
+  FULLTEXT KEY `ft1` USING NGRAM, NORMALIZE, 512 (`c4`),
+  FULLTEXT KEY `ft2` USING NGRAM, NORMALIZE, SECTIONALIZE, 64 (`c5`),
+  FULLTEXT KEY `ft3` USING DELIMITED, NO NORMALIZE, 128 (`c5`),
+  FULLTEXT KEY `ft4` USING NGRAM, NORMALIZE, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL, 48 (`c5`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft1	c4	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft2	c5	utf8	NGRAM	ON	ON	OFF	OFF	OFF	64	0	4268032	0	4268032	139264	20480
+t1	ft3	c5	utf8	DELIMITED	OFF	OFF	OFF	OFF	OFF	128	0	4268032	0	4268032	143360	36864
+t1	ft4	c5	utf8	NGRAM	OFF	ON	ON	ON	ON	48	0	4268032	0	4268032	135168	16384
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 TEXT, FULLTEXT INDEX ft (c2));
+CREATE VIEW v1 AS SELECT * FROM t1;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	latin1	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP VIEW v1;
+DROP TABLE t1;
--- orig/mysql-test/suite/senna/r/senna_eucjpms.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_eucjpms.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,404 @@
+SET NAMES utf8;
+SELECT "===== TESTS for Ngram started =====";
+===== TESTS for Ngram started =====
+===== TESTS for Ngram started =====
+SELECT "===== creating test data started =====";
+===== creating test data started =====
+===== creating test data started =====
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY AUTO_INCREMENT, 
+c2 TEXT,
+FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET eucjpms;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(11) NOT NULL auto_increment,
+  `c2` text,
+  PRIMARY KEY  (`c1`),
+  FULLTEXT KEY `ft` USING NGRAM, NORMALIZE, 512 (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=eucjpms
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	eucjpms	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== creating test data finished =====";
+===== creating test data finished =====
+===== creating test data finished =====
+SELECT "===== tests for FULLTEXT search started =====";
+===== tests for FULLTEXT search started =====
+===== tests for FULLTEXT search started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+c1	score	c2
+4	1	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	1	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+c1	score	c2
+7	1	MySQLは優れたセキュリティ機能を提供しています。
+12	2	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+c1	score	c2
+2	5	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	10	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+c1	score	c2
+4	4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+c1	score	c2
+4	9	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+c1	c2
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+19	先生、その件について詳しく教えて下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+c1	c2
+5	信頼性と可用性は、MySQLの大きな特徴です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム㈱でお願いいたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+21	ファイナルファンタジーⅶを1本下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+c1	c2
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== tests for FULLTEXT search finished =====";
+===== tests for FULLTEXT search finished =====
+===== tests for FULLTEXT search finished =====
+SELECT "===== tests for INSERT started =====";
+===== tests for INSERT started =====
+===== tests for INSERT started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+25	普段から緊急事態に備えておかなければならない。
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム㈱でお願いいたします。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+21	ファイナルファンタジーⅶを1本下さい。
+27	ファイナルファンタジーⅶを1本下さい。
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+c1	c2
+30	職員室に忘れて置いてきてしまった出席表
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+27	ファイナルファンタジーⅶを1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+SELECT "===== tests for INSERT finished =====";
+===== tests for INSERT finished =====
+===== tests for INSERT finished =====
+SELECT "===== tests for DELETE started =====";
+===== tests for DELETE started =====
+===== tests for DELETE started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+27	ファイナルファンタジーⅶを1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+c1	c2
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+SELECT "===== tests for DELETE finished =====";
+===== tests for DELETE finished =====
+===== tests for DELETE finished =====
+SELECT "===== tests for errors started =====";
+===== tests for errors started =====
+===== tests for errors started =====
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+ERROR HY000: Can't find FULLTEXT index matching the column list
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT "===== tests for error finished =====";
+===== tests for error finished =====
+===== tests for error finished =====
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
+===== TESTS for Ngram finished =====
+===== TESTS for Ngram finished =====
--- orig/mysql-test/suite/senna/r/senna_general.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_general.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,7 @@
+set names utf8;
+DROP TABLE IF EXISTS t1;
+create table t1 (c1 char(100) unique) engine = innodb;
+insert into t1 values ("test");
+delete from t1 where c1 = "test";
+insert into t1 values ("test");
+drop table t1;
--- orig/mysql-test/suite/senna/r/senna_kwic.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_kwic.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,178 @@
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> >>> 明日は
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>")
+<span class='word1'>東京</span> >>> 明日は<span class='word2'>埼玉</span>に
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 1, "","", "東京", "<span class='word'>", "</span>");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 1, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> &gt;&gt;&gt; 明日は
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>")
+... 今日は<span class='word'>東京</span> >>> 明日は埼玉に行き ...
+CREATE TABLE t1 (c1 CHAR(100)) DEFAULT CHARSET utf8;
+INSERT INTO t1 VALUES("今日は東京 >>> 明日は埼玉に行きます。");
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> >>> 明日は
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>")
+<span class='word1'>東京</span> >>> 明日は<span class='word2'>埼玉</span>に
+SELECT KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> &gt;&gt;&gt; 明日は
+SELECT KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>")
+... 今日は<span class='word'>東京</span> >>> 明日は埼玉に行き ...
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(100)) DEFAULT CHARSET utf8;
+INSERT INTO t1 VALUES("今日は東京 >>> 明日は埼玉に行きます。");
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> >>> 明日は
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>")
+<span class='word1'>東京</span> >>> 明日は<span class='word2'>埼玉</span>に
+SELECT KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> &gt;&gt;&gt; 明日は
+SELECT KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>")
+... 今日は<span class='word'>東京</span> >>> 明日は埼玉に行き ...
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT) DEFAULT CHARSET utf8;
+INSERT INTO t1 VALUES("今日は東京 >>> 明日は埼玉に行きます。");
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> >>> 明日は
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>")
+<span class='word1'>東京</span> >>> 明日は<span class='word2'>埼玉</span>に
+SELECT KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> &gt;&gt;&gt; 明日は
+SELECT KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>")
+... 今日は<span class='word'>東京</span> >>> 明日は埼玉に行き ...
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT) DEFAULT CHARSET utf8;
+INSERT INTO t1 VALUES("今日は東京 >>> 明日は埼玉に行きます。");
+PREPARE pstmt FROM 'SELECT KWIC(c1, 30, 1, 0, "","", ?, "<span class=\'word\'>", "</span>") FROM t1';
+SET @a = "東京";
+EXECUTE pstmt USING @a;
+KWIC(c1, 30, 1, 0, "","", ?, "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> >>> 明日は
+DROP TABLE t1;
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>"),
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>")	KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>")
+今日は<span class='word'>東京</span> >>> 明日は	今日は<span class='word'>東京</span> >>> 明日は
+SELECT KWIC(KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>"),
+30, 1, 0, "","", "東京", "<span class='word'>", "</span>");
+KWIC(KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>"),
+30, 1, 0, "","", "東京", "<span class='word'>", "</span>")
+lass='word'><span class='word'>東京</span></span> >>> 
+SELECT KWIC(null, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>");
+KWIC(null, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>")
+NULL
+SELECT KWIC(null, null, null, null, null, null, null, null, null);
+KWIC(null, null, null, null, null, null, null, null, null)
+NULL
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>", "");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>", "")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>", "");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>", "")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 0, 1, 0, "","", "東京", "<span class='word'>", "</span>", "");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 0, 1, 0, "","", "東京", "<span class='word'>", "</span>", "")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", -10, 1, 0, "","", "東京", "<span class='word'>", "</span>", "");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", -10, 1, 0, "","", "東京", "<span class='word'>", "</span>", "")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 0, 0, "","", "東京", "<span class='word'>", "</span>", "");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 0, 0, "","", "東京", "<span class='word'>", "</span>", "")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, -10, 0, "","", "東京", "<span class='word'>", "</span>", "");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, -10, 0, "","", "東京", "<span class='word'>", "</span>", "")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 10, "","", "東京", "<span class='word'>", "</span>", "");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 10, "","", "東京", "<span class='word'>", "</span>", "")
+
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, -30, "","", "東京", "<span class='word'>", "</span>", "");
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, -30, "","", "東京", "<span class='word'>", "</span>", "")
+
+drop table if exists t1;
+create table t1 (c1 text) default charset utf8 engine = myisam;
+insert into t1 values("今日は埼玉あああああああああああああああああああああああああああああああああああああ。
+明日も埼玉ああああああああああいいいいいいいいいいいいあああああああああああああああああああああ。
+明後日も埼玉あああああああああああああああああああああああああああああああああああ。
+いつでも埼玉あああああああああああああああああああああああああああああああああ。");
+select kwic(c1, 20, 1, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+kwic(c1, 20, 1, 0, "", " ...", "埼玉", "<span id=word>", "</span>")
+日は<span id=word>埼玉</span>ああ ...
+select kwic(c1, 20, 2, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+kwic(c1, 20, 2, 0, "", " ...", "埼玉", "<span id=word>", "</span>")
+日は<span id=word>埼玉</span>ああ ...日も<span id=word>埼玉</span>ああ ...
+select kwic(c1, 20, 3, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+kwic(c1, 20, 3, 0, "", " ...", "埼玉", "<span id=word>", "</span>")
+日は<span id=word>埼玉</span>ああ ...日も<span id=word>埼玉</span>ああ ...日も<span id=word>埼玉</span>ああ ...
+select kwic(c1, 20, 4, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+kwic(c1, 20, 4, 0, "", " ...", "埼玉", "<span id=word>", "</span>")
+日は<span id=word>埼玉</span>ああ ...日も<span id=word>埼玉</span>ああ ...日も<span id=word>埼玉</span>ああ ...でも<span id=word>埼玉</span>ああ ...
+select kwic(c1, 20, 5, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+kwic(c1, 20, 5, 0, "", " ...", "埼玉", "<span id=word>", "</span>")
+日は<span id=word>埼玉</span>ああ ...日も<span id=word>埼玉</span>ああ ...日も<span id=word>埼玉</span>ああ ...でも<span id=word>埼玉</span>ああ ...
+select kwic(c1, 20, 1, 0, "(", ")", "埼玉", "[", "]") from t1;
+kwic(c1, 20, 1, 0, "(", ")", "埼玉", "[", "]")
+(日は[埼玉]ああ)
+select kwic(c1, 20, 2, 0, "(", ")", "埼玉", "[", "]") from t1;
+kwic(c1, 20, 2, 0, "(", ")", "埼玉", "[", "]")
+(日は[埼玉]ああ)(日も[埼玉]ああ)
+select kwic(c1, 20, 3, 0, "(", ")", "埼玉", "[", "]") from t1;
+kwic(c1, 20, 3, 0, "(", ")", "埼玉", "[", "]")
+(日は[埼玉]ああ)(日も[埼玉]ああ)(日も[埼玉]ああ)
+select kwic(c1, 20, 4, 0, "(", ")", "埼玉", "[", "]") from t1;
+kwic(c1, 20, 4, 0, "(", ")", "埼玉", "[", "]")
+(日は[埼玉]ああ)(日も[埼玉]ああ)(日も[埼玉]ああ)(でも[埼玉]ああ)
+select kwic(c1, 20, 5, 0, "(", ")", "埼玉", "[", "]") from t1;
+kwic(c1, 20, 5, 0, "(", ")", "埼玉", "[", "]")
+(日は[埼玉]ああ)(日も[埼玉]ああ)(日も[埼玉]ああ)(でも[埼玉]ああ)
+drop table t1;
+CREATE TABLE t1 (c1 int, c2 TEXT) DEFAULT CHARSET utf8;
+INSERT INTO t1 (c1) VALUES (100);
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>")
+
+DROP TABLE t1;
+create table t1 (c1 longtext, time INT) default charset utf8 engine=myisam;
+insert into t1 (c1, time) VALUES('B A B', 1191299318);
+insert into t1 (c1, time) VALUES('B A B', 1191299722);
+select kwic(c1, 120, 3, 0, "", "", "B", "[", "]") from t1;
+kwic(c1, 120, 3, 0, "", "", "B", "[", "]")
+[B] A [B]
+[B] A [B]
+drop table t1;
+create table t1 (c1 longtext) default charset utf8 engine=myisam;
+insert into t1 (c1) VALUES('アイコンメニュー と ポートレット から検索');
+select * from t1;
+c1
+アイコンメニュー と ポートレット から検索
+select kwic(c1, 120, 3, 0, "", "", "アイコンメニュー", "[", "]") from t1;
+kwic(c1, 120, 3, 0, "", "", "アイコンメニュー", "[", "]")
+[アイコンメニュー] と ポートレット から検索
+select kwic(c1, 120, 3, 0, "", "", "から", "[", "]") from t1;
+kwic(c1, 120, 3, 0, "", "", "から", "[", "]")
+アイコンメニュー と ポートレット [から]検索
+select kwic(c1, 120, 3, 0, "", "", "検索", "[", "]") from t1;
+kwic(c1, 120, 3, 0, "", "", "検索", "[", "]")
+アイコンメニュー と ポートレット から[検索]
+drop table t1;
--- orig/mysql-test/suite/senna/r/senna_section.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_section.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,140 @@
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 VARCHAR(20), c3 TEXT) DEFAULT CHARSET utf8;
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING NGRAM, SECTIONALIZE (c2,c3);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	utf8	NGRAM	ON	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft	c3	utf8	NGRAM	ON	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 VALUES(1, "c2あたりc2", "c3あたりc3");
+INSERT INTO t1 VALUES(2, "c2あたりc2", "c3はずれc3");
+INSERT INTO t1 VALUES(3, "c2はずれc2", "c3あたりc3");
+INSERT INTO t1 VALUES(4, "c2はずれc2", "c3はずれc3");
+SELECT * FROM t1;
+c1	c2	c3
+1	c2あたりc2	c3あたりc3
+2	c2あたりc2	c3はずれc3
+3	c2はずれc2	c3あたりc3
+4	c2はずれc2	c3はずれc3
+SELECT *, MATCH(c2,c3) AGAINST("あたり") AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("あたり") ORDER BY score DESC;
+c1	c2	c3	score
+1	c2あたりc2	c3あたりc3	2
+2	c2あたりc2	c3はずれc3	1
+3	c2はずれc2	c3あたりc3	1
+SELECT *, MATCH(c2,c3) AGAINST("あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("あたり" IN BOOLEAN MODE) ORDER BY score DESC;
+c1	c2	c3	score
+1	c2あたりc2	c3あたりc3	10
+2	c2あたりc2	c3はずれc3	5
+3	c2はずれc2	c3あたりc3	5
+SELECT *, MATCH(c2,c3) AGAINST("*W1 あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W1 あたり" IN BOOLEAN MODE);
+c1	c2	c3	score
+1	c2あたりc2	c3あたりc3	1
+2	c2あたりc2	c3はずれc3	1
+SELECT *, MATCH(c2,c3) AGAINST("*W2 あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W2 あたり" IN BOOLEAN MODE);
+c1	c2	c3	score
+1	c2あたりc2	c3あたりc3	1
+3	c2はずれc2	c3あたりc3	1
+SELECT *, MATCH(c2,c3) AGAINST("*W1,2 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W1,2 あたり" IN BOOLEAN MODE);
+c1	c2	c3	score
+1	c2あたりc2	c3あたりc3	2
+2	c2あたりc2	c3はずれc3	1
+3	c2はずれc2	c3あたりc3	1
+SELECT *, MATCH(c2,c3) AGAINST("*W3 あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W3 あたり" IN BOOLEAN MODE);
+c1	c2	c3	score
+SELECT *, MATCH(c2,c3) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+c1	c2	c3	score
+1	c2あたりc2	c3あたりc3	11
+2	c2あたりc2	c3はずれc3	10
+3	c2はずれc2	c3あたりc3	1
+DELETE FROM t1 WHERE c1 = 2;
+SELECT * FROM t1;
+c1	c2	c3
+1	c2あたりc2	c3あたりc3
+3	c2はずれc2	c3あたりc3
+4	c2はずれc2	c3はずれc3
+SELECT *, MATCH(c2,c3) AGAINST("あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("あたり" IN BOOLEAN MODE);
+c1	c2	c3	score
+1	c2あたりc2	c3あたりc3	10
+3	c2はずれc2	c3あたりc3	5
+DELETE FROM t1 WHERE c1 = 4;
+SELECT * FROM t1;
+c1	c2	c3
+1	c2あたりc2	c3あたりc3
+3	c2はずれc2	c3あたりc3
+DELETE FROM t1;
+SELECT * FROM t1;
+c1	c2	c3
+DROP INDEX ft ON t1;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note	1051	Unknown table 't1'
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 VARCHAR(20), c3 INT, c4 TEXT) DEFAULT CHARSET utf8;
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING NGRAM, SECTIONALIZE (c2,c4);
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	utf8	NGRAM	ON	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft	c4	utf8	NGRAM	ON	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 VALUES(1, "c2あたりc2", 100, "c4あたりc4");
+INSERT INTO t1 VALUES(2, "c2あたりc2", 200, "c4はずれc4");
+INSERT INTO t1 VALUES(3, "c2はずれc2", 300, "c4あたりc4");
+INSERT INTO t1 VALUES(4, "c2はずれc2", 400, "c4はずれc4");
+SELECT *, MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+c1	c2	c3	c4	score
+1	c2あたりc2	100	c4あたりc4	11
+2	c2あたりc2	200	c4はずれc4	10
+3	c2はずれc2	300	c4あたりc4	1
+DELETE FROM t1 WHERE c1 = 2;
+SELECT * FROM t1;
+c1	c2	c3	c4
+1	c2あたりc2	100	c4あたりc4
+3	c2はずれc2	300	c4あたりc4
+4	c2はずれc2	400	c4はずれc4
+SELECT *, MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+c1	c2	c3	c4	score
+1	c2あたりc2	100	c4あたりc4	11
+3	c2はずれc2	300	c4あたりc4	1
+INSERT INTO t1 VALUES(2, "c2あたりc2", 200, "c4はずれc4");
+ALTER TABLE t1 ADD c2a INT AFTER c2;
+UPDATE t1 SET c2a = 10;
+SELECT *, MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+c1	c2	c2a	c3	c4	score
+1	c2あたりc2	10	100	c4あたりc4	11
+2	c2あたりc2	10	200	c4はずれc4	10
+3	c2はずれc2	10	300	c4あたりc4	1
+DELETE FROM t1 WHERE c1 = 2;
+SELECT * FROM t1;
+c1	c2	c2a	c3	c4
+1	c2あたりc2	10	100	c4あたりc4
+3	c2はずれc2	10	300	c4あたりc4
+4	c2はずれc2	10	400	c4はずれc4
+SELECT *, MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+c1	c2	c2a	c3	c4	score
+1	c2あたりc2	10	100	c4あたりc4	11
+3	c2はずれc2	10	300	c4あたりc4	1
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	utf8	NGRAM	ON	ON	OFF	OFF	OFF	512	4	8462336	9	8462336	2789376	135168
+t1	ft	c4	utf8	NGRAM	ON	ON	OFF	OFF	OFF	512	4	8462336	9	8462336	2789376	135168
+DELETE FROM t1;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	utf8	NGRAM	ON	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+t1	ft	c4	utf8	NGRAM	ON	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
--- orig/mysql-test/suite/senna/r/senna_sjis.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_sjis.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,431 @@
+SET NAMES utf8;
+SELECT "===== TESTS for Ngram started =====";
+===== TESTS for Ngram started =====
+===== TESTS for Ngram started =====
+SELECT "===== creating test data started =====";
+===== creating test data started =====
+===== creating test data started =====
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY AUTO_INCREMENT, 
+c2 TEXT,
+FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET sjis;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(11) NOT NULL auto_increment,
+  `c2` text,
+  PRIMARY KEY  (`c1`),
+  FULLTEXT KEY `ft` USING NGRAM, NORMALIZE, 512 (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=sjis
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	cp932	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE3\x88\xB1\xE3\x81\xA7...' for column 'c2' at row 1
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE2\x85\xB6\xE3\x82\x92...' for column 'c2' at row 1
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE6\xB7\xBC\xE3\x81\xAB...' for column 'c2' at row 1
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== creating test data finished =====";
+===== creating test data finished =====
+===== creating test data finished =====
+SELECT "===== tests for FULLTEXT search started =====";
+===== tests for FULLTEXT search started =====
+===== tests for FULLTEXT search started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+c1	score	c2
+4	1	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	1	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+c1	score	c2
+7	1	MySQLは優れたセキュリティ機能を提供しています。
+12	2	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+c1	score	c2
+2	5	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	10	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+c1	score	c2
+4	4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+c1	score	c2
+4	9	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+c1	c2
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+19	先生、その件について詳しく教えて下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+c1	c2
+5	信頼性と可用性は、MySQLの大きな特徴です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+c1	c2
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== tests for FULLTEXT search finished =====";
+===== tests for FULLTEXT search finished =====
+===== tests for FULLTEXT search finished =====
+SELECT "===== tests for INSERT started =====";
+===== tests for INSERT started =====
+===== tests for INSERT started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+25	普段から緊急事態に備えておかなければならない。
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE3\x88\xB1\xE3\x81\xA7...' for column 'c2' at row 1
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+26	宛名書きは住商情報システム?でお願いいたします。
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE2\x85\xB6\xE3\x82\x92...' for column 'c2' at row 1
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+26	宛名書きは住商情報システム?でお願いいたします。
+27	ファイナルファンタジー?を1本下さい。
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE6\xB7\xBC\xE3\x81\xAB...' for column 'c2' at row 1
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+26	宛名書きは住商情報システム?でお願いいたします。
+27	ファイナルファンタジー?を1本下さい。
+28	NEC選定IBM拡張文字の?について今日はお話いたします。
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+c1	c2
+30	職員室に忘れて置いてきてしまった出席表
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム?でお願いいたします。
+27	ファイナルファンタジー?を1本下さい。
+28	NEC選定IBM拡張文字の?について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+SELECT "===== tests for INSERT finished =====";
+===== tests for INSERT finished =====
+===== tests for INSERT finished =====
+SELECT "===== tests for DELETE started =====";
+===== tests for DELETE started =====
+===== tests for DELETE started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の?について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム?でお願いいたします。
+27	ファイナルファンタジー?を1本下さい。
+28	NEC選定IBM拡張文字の?について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+c1	c2
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+SELECT "===== tests for DELETE finished =====";
+===== tests for DELETE finished =====
+===== tests for DELETE finished =====
+SELECT "===== tests for errors started =====";
+===== tests for errors started =====
+===== tests for errors started =====
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+ERROR HY000: Can't find FULLTEXT index matching the column list
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT "===== tests for error finished =====";
+===== tests for error finished =====
+===== tests for error finished =====
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
+===== TESTS for Ngram finished =====
+===== TESTS for Ngram finished =====
--- orig/mysql-test/suite/senna/r/senna_split.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_split.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,318 @@
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_ALPHA (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	ON	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_DIGIT (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	OFF	ON	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	OFF	OFF	ON	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	ON	ON	ON	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = cp932;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = cp932;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = eucjpms;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = eucjpms;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_ALPHA (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	ON	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_DIGIT (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	OFF	ON	OFF	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	OFF	OFF	ON	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c1	utf8	NGRAM	OFF	ON	ON	ON	ON	512	0	4268032	0	4268032	167936	135168
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = cp932;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = cp932;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = eucjpms;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = eucjpms;
+INSERT INTO t1 VALUES("FedoraCore500の技");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+c1
+FedoraCore500の技
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+c1
+FedoraCore500の技
+DROP TABLE t1;
--- orig/mysql-test/suite/senna/r/senna_ujis.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_ujis.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,417 @@
+SET NAMES utf8;
+SELECT "===== TESTS for Ngram started =====";
+===== TESTS for Ngram started =====
+===== TESTS for Ngram started =====
+SELECT "===== creating test data started =====";
+===== creating test data started =====
+===== creating test data started =====
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY AUTO_INCREMENT, 
+c2 TEXT,
+FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET ujis;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(11) NOT NULL auto_increment,
+  `c2` text,
+  PRIMARY KEY  (`c1`),
+  FULLTEXT KEY `ft` USING NGRAM, NORMALIZE, 512 (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=ujis
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	eucjpms	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE3\x88\xB1\xE3\x81\xA7...' for column 'c2' at row 1
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE2\x85\xB6\xE3\x82\x92...' for column 'c2' at row 1
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== creating test data finished =====";
+===== creating test data finished =====
+===== creating test data finished =====
+SELECT "===== tests for FULLTEXT search started =====";
+===== tests for FULLTEXT search started =====
+===== tests for FULLTEXT search started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+c1	score	c2
+4	1	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	1	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+c1	score	c2
+7	1	MySQLは優れたセキュリティ機能を提供しています。
+12	2	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+c1	score	c2
+2	5	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	10	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+c1	score	c2
+4	4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+c1	score	c2
+4	9	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+c1	c2
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+19	先生、その件について詳しく教えて下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+c1	c2
+5	信頼性と可用性は、MySQLの大きな特徴です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+c1	c2
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== tests for FULLTEXT search finished =====";
+===== tests for FULLTEXT search finished =====
+===== tests for FULLTEXT search finished =====
+SELECT "===== tests for INSERT started =====";
+===== tests for INSERT started =====
+===== tests for INSERT started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+25	普段から緊急事態に備えておかなければならない。
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE3\x88\xB1\xE3\x81\xA7...' for column 'c2' at row 1
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+26	宛名書きは住商情報システム?でお願いいたします。
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+Warnings:
+Warning	1366	Incorrect string value: '\xE2\x85\xB6\xE3\x82\x92...' for column 'c2' at row 1
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+26	宛名書きは住商情報システム?でお願いいたします。
+27	ファイナルファンタジー?を1本下さい。
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+c1	c2
+30	職員室に忘れて置いてきてしまった出席表
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム?でお願いいたします。
+27	ファイナルファンタジー?を1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+SELECT "===== tests for INSERT finished =====";
+===== tests for INSERT finished =====
+===== tests for INSERT finished =====
+SELECT "===== tests for DELETE started =====";
+===== tests for DELETE started =====
+===== tests for DELETE started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム?でお願いいたします。
+21	ファイナルファンタジー?を1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム?でお願いいたします。
+27	ファイナルファンタジー?を1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+c1	c2
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+SELECT "===== tests for DELETE finished =====";
+===== tests for DELETE finished =====
+===== tests for DELETE finished =====
+SELECT "===== tests for errors started =====";
+===== tests for errors started =====
+===== tests for errors started =====
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+ERROR HY000: Can't find FULLTEXT index matching the column list
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT "===== tests for error finished =====";
+===== tests for error finished =====
+===== tests for error finished =====
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
+===== TESTS for Ngram finished =====
+===== TESTS for Ngram finished =====
--- orig/mysql-test/suite/senna/r/senna_utf8.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_utf8.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,404 @@
+SET NAMES utf8;
+SELECT "===== TESTS for Ngram started =====";
+===== TESTS for Ngram started =====
+===== TESTS for Ngram started =====
+SELECT "===== creating test data started =====";
+===== creating test data started =====
+===== creating test data started =====
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY AUTO_INCREMENT, 
+c2 TEXT,
+FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(11) NOT NULL auto_increment,
+  `c2` text,
+  PRIMARY KEY  (`c1`),
+  FULLTEXT KEY `ft` USING NGRAM, NORMALIZE, 512 (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+SHOW SENNA STATUS;
+Table	Key_name	Column_name	Encoding	Index_type	Sectionalize	Normalize	Split_alpha	Split_digit	Split_symbol	Initial_n_segments	Senna_keys_size	Senna_keys_file_size	Senna_lexicon_size	Senna_lexicon_file_size	Senna_inv_seg_size	Senna_inv_chunk_size
+t1	ft	c2	utf8	NGRAM	OFF	ON	OFF	OFF	OFF	512	0	4268032	0	4268032	167936	135168
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== creating test data finished =====";
+===== creating test data finished =====
+===== creating test data finished =====
+SELECT "===== tests for FULLTEXT search started =====";
+===== tests for FULLTEXT search started =====
+===== tests for FULLTEXT search started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+c1	score	c2
+4	1	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	1	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+c1	score	c2
+7	1	MySQLは優れたセキュリティ機能を提供しています。
+12	2	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+c1	score	c2
+2	5	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	10	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+c1	score	c2
+4	4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+c1	score	c2
+4	9	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	5	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+c1	c2
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+c1	c2
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+19	先生、その件について詳しく教えて下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+c1	c2
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+c1	c2
+5	信頼性と可用性は、MySQLの大きな特徴です。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+c1	c2
+18	東の湖にて水泳大会を行います。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム㈱でお願いいたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+21	ファイナルファンタジーⅶを1本下さい。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+c1	c2
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+SELECT "===== tests for FULLTEXT search finished =====";
+===== tests for FULLTEXT search finished =====
+===== tests for FULLTEXT search finished =====
+SELECT "===== tests for INSERT started =====";
+===== tests for INSERT started =====
+===== tests for INSERT started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+25	普段から緊急事態に備えておかなければならない。
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+20	宛名書きは住商情報システム㈱でお願いいたします。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+21	ファイナルファンタジーⅶを1本下さい。
+27	ファイナルファンタジーⅶを1本下さい。
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+c1	c2
+30	職員室に忘れて置いてきてしまった出席表
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+27	ファイナルファンタジーⅶを1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+SELECT "===== tests for INSERT finished =====";
+===== tests for INSERT finished =====
+===== tests for INSERT finished =====
+SELECT "===== tests for DELETE started =====";
+===== tests for DELETE started =====
+===== tests for DELETE started =====
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+20	宛名書きは住商情報システム㈱でお願いいたします。
+21	ファイナルファンタジーⅶを1本下さい。
+22	NEC選定IBM拡張文字の淼について今日はお話いたします。
+23	日本語の文字の種類のひとつとして半角カタカナがある。
+24	御両親の印鑑を押してもらって明日持ってきてください、成績表
+25	普段から緊急事態に備えておかなければならない。
+26	宛名書きは住商情報システム㈱でお願いいたします。
+27	ファイナルファンタジーⅶを1本下さい。
+28	NEC選定IBM拡張文字の淼について今日はお話いたします。
+29	日本語の文字の種類のひとつとして半角カタカナがある。
+30	職員室に忘れて置いてきてしまった出席表
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+c1	c2
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+c1	c2
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+c1	c2
+SELECT * FROM t1;
+c1	c2
+1	世界で最もポピュラーなオープンソースデータベースMySQL
+2	住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。
+3	他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。
+4	商用ライセンスは有料ですが、再配布なども自由に行えます。
+5	信頼性と可用性は、MySQLの大きな特徴です。
+6	企業のデータを適切に管理することは、DBAの最も大きな仕事です。
+7	MySQLは優れたセキュリティ機能を提供しています。
+8	ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。
+9	MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。
+10	MySQL Clusterはメモリベースの高速ストレージエンジンです。
+11	GPLライセンスに基づいてソフトウェアの再配布を行うことができます
+12	高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。
+13	GPLソフトウェアは無料ですが、サービスは有料です。
+14	システム管理工学を担当している教授です。
+15	理工学部で物理学を担当している教授です。
+16	私の専攻は理工です。
+17	私の専攻は理工*です。
+18	東の湖にて水泳大会を行います。
+19	先生、その件について詳しく教えて下さい。
+SELECT "===== tests for DELETE finished =====";
+===== tests for DELETE finished =====
+===== tests for DELETE finished =====
+SELECT "===== tests for errors started =====";
+===== tests for errors started =====
+===== tests for errors started =====
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+ERROR HY000: Can't find FULLTEXT index matching the column list
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+c1	c2
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+ERROR 42S22: Unknown column 'c3' in 'where clause'
+SELECT "===== tests for error finished =====";
+===== tests for error finished =====
+===== tests for error finished =====
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
+===== TESTS for Ngram finished =====
+===== TESTS for Ngram finished =====
--- orig/mysql-test/suite/senna/r/senna_util.result	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/r/senna_util.result	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,106 @@
+SHOW VARIABLES LIKE 'senna_%';
+Variable_name	Value
+senna_2ind	OFF
+senna_index_type	NGRAM
+senna_log	OFF
+senna_log_level	NOTICE
+SET senna_log_level=INFO;
+ERROR HY000: Variable 'senna_log_level' is a GLOBAL variable and should be set with SET GLOBAL
+SET GLOBAL senna_log_level=NONE;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	NONE
+SET GLOBAL senna_log_level=EMERG;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	EMERG
+SET GLOBAL senna_log_level=ALERT;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	ALERT
+SET GLOBAL senna_log_level=CRIT;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	CRIT
+SET GLOBAL senna_log_level=ERROR;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	ERROR
+SET GLOBAL senna_log_level=WARNING;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	WARNING
+SET GLOBAL senna_log_level=NOTICE;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	NOTICE
+SET GLOBAL senna_log_level=INFO;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	INFO
+SET GLOBAL senna_log_level=DEBUG;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	DEBUG
+SET GLOBAL senna_log_level=DUMP;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	DUMP
+SET GLOBAL senna_log_level=DUMMY;
+ERROR 42000: Variable 'senna_log_level' can't be set to the value of 'DUMMY'
+SHOW VARIABLES LIKE 'senna_log_level';
+Variable_name	Value
+senna_log_level	DUMP
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	OFF
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	OFF
+SET senna_2ind=ON;
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	OFF
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	ON
+SET senna_2ind=OFF;
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	OFF
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	OFF
+SET GLOBAL senna_2ind=ON;
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	ON
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	OFF
+SET GLOBAL senna_2ind=OFF;
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	OFF
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+Variable_name	Value
+senna_2ind	OFF
+SET senna_2ind=DUMMY;
+ERROR 42000: Variable 'senna_2ind' can't be set to the value of 'DUMMY'
+SET GLOBAL senna_2ind=DUMMY;
+ERROR 42000: Variable 'senna_2ind' can't be set to the value of 'DUMMY'
+SHOW VARIABLES LIKE 'senna_index_type';
+Variable_name	Value
+senna_index_type	NGRAM
+SET GLOBAL senna_index_type=mecab;
+SHOW VARIABLES LIKE 'senna_index_type';
+Variable_name	Value
+senna_index_type	MECAB
+SET GLOBAL senna_index_type=ngram;
+SHOW VARIABLES LIKE 'senna_index_type';
+Variable_name	Value
+senna_index_type	NGRAM
+SET GLOBAL senna_index_type=hoge;
+ERROR 42000: Variable 'senna_index_type' can't be set to the value of 'hoge'
+SET SESSION senna_index_type=ngram;
+ERROR HY000: Variable 'senna_index_type' is a GLOBAL variable and should be set with SET GLOBAL
--- orig/mysql-test/suite/senna/t/senna_2ind.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_2ind.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,40 @@
+SET NAMES utf8;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# bugfix for 2ind, group functions. sum, count ...
+drop table if exists t1;
+create table t1(c1 int, c2 varchar(255), index(c1)) default charset utf8;
+insert into t1 values (1,"aaa");
+insert into t1 values (2,"aaa");
+insert into t1 values (3,"bbb");
+insert into t1 values (4,"bbb");
+
+create fulltext index ft using
+ngram,split_alpha,split_digit,split_symbol on t1(c2);
+
+set senna_2ind=OFF;
+select sum(c1) from t1 where match(c2) against("a");
+set senna_2ind=ON;
+select sum(c1) from t1 where match(c2) against("a");
+drop table t1;
+
+# bufgix for 2ind match select
+drop table if exists test;
+create table test (
+  id int not null,
+  title varchar(200) not null,
+  primary key (id),
+  fulltext key fkey1 using ngram, normalize, 512 (title)
+) engine=myisam default charset=utf8;
+INSERT INTO test (id, title) VALUES(1, "今日の天気は晴れです。");
+INSERT INTO test (id, title) VALUES(2, "明日の天気は雨です。");
+set session senna_2ind=ON;
+SELECT * FROM test WHERE MATCH(title) AGAINST("晴れ");
+SELECT * FROM test WHERE MATCH(title) AGAINST("雨");
+SET SESSION senna_2ind=OFF;
+SELECT * FROM test WHERE MATCH(title) AGAINST("晴れ");
+SELECT * FROM test WHERE MATCH(title) AGAINST("雨");
+drop table test;
--- orig/mysql-test/suite/senna/t/senna_cp932.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_cp932.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,160 @@
+# cp932 test
+
+SET NAMES utf8;
+
+# TESTS for Ngram
+SELECT "===== TESTS for Ngram started =====";
+
+SELECT "===== creating test data started =====";
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  c1 INT PRIMARY KEY AUTO_INCREMENT, 
+  c2 TEXT,
+  FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET cp932;
+
+SHOW CREATE TABLE t1;
+SHOW SENNA STATUS;
+
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+
+SELECT * FROM t1;
+SELECT "===== creating test data finished =====";
+
+# tests for FULLTEXT search
+
+SELECT "===== tests for FULLTEXT search started =====";
+SELECT * FROM t1;
+
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+
+SELECT "===== tests for FULLTEXT search finished =====";
+
+# tests for INSERT
+
+SELECT "===== tests for INSERT started =====";
+SELECT * FROM t1;
+
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+
+SELECT * FROM t1;
+SELECT "===== tests for INSERT finished =====";
+
+# tests for DELETE
+
+SELECT "===== tests for DELETE started =====";
+SELECT * FROM t1;
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+
+SELECT * FROM t1;
+SELECT "===== tests for DELETE finished =====";
+
+# tests for errors
+
+SELECT "===== tests for errors started =====";
+
+--error 1191
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+
+SELECT "===== tests for error finished =====";
+
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
--- orig/mysql-test/suite/senna/t/senna_create.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_create.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,240 @@
+-- source include/have_innodb.inc
+
+SET NAMES utf8;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+
+# test for column types
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 CHAR(100),
+  c3 VARCHAR(100),
+  c4 TINYTEXT,
+  c5 TEXT,
+  c6 MEDIUMTEXT,
+  c7 LONGTEXT,
+  FULLTEXT INDEX USING NGRAM (c2),
+  FULLTEXT INDEX USING NGRAM (c3),
+  FULLTEXT INDEX USING NGRAM (c4),
+  FULLTEXT INDEX USING NGRAM (c5),
+  FULLTEXT INDEX USING NGRAM (c6),
+  FULLTEXT INDEX USING NGRAM (c7)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+
+# test for colmun types - error
+
+--error 1283
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 INT,
+  FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+--error 1283
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 DOUBLE,
+  FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+--error 1283
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 DATETIME,
+  FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+--error 1283
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 BLOB,
+  FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+
+# fulltext unsupported storage engine 
+--error 1214
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 CHAR(100),
+  FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = MEMORY DEFAULT CHARSET utf8;
+
+--error 1214
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 CHAR(100),
+  FULLTEXT INDEX USING NGRAM (c2)
+) ENGINE = InnoDB DEFAULT CHARSET utf8;
+
+# multi column fulltext index
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 VARCHAR(128),
+  c3 TEXT,
+  FULLTEXT INDEX USING NGRAM (c2, c3)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+SHOW SENNA STATUS;
+DROP TABLE t1;
+ 
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 VARCHAR(128),
+  c3 TEXT,
+  c4 TEXT,
+  FULLTEXT INDEX USING NGRAM (c2, c3, c4)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+
+# create and drop index
+ 
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 TEXT
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+SHOW SENNA STATUS;
+CREATE FULLTEXT INDEX ft USING NGRAM ON t1(c2);
+SHOW SENNA STATUS;
+
+DROP INDEX ft ON t1;
+SHOW SENNA STATUS;
+
+DROP TABLE t1;
+
+# alter table and using expressions
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 TEXT,
+  c3 TEXT,
+  c4 TEXT,
+  c5 TEXT,
+  c6 TEXT,
+  c7 TEXT,
+  c8 TEXT
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+ALTER TABLE t1 ADD FULLTEXT INDEX ft2 USING NGRAM, 20 (c2);
+SHOW SENNA STATUS;
+
+ALTER TABLE t1 ADD FULLTEXT INDEX ft3 USING NGRAM, NO NORMALIZE (c3);
+
+ALTER TABLE t1 ADD FULLTEXT INDEX ft4 USING NGRAM, NO NORMALIZE, 40 (c4);
+SHOW SENNA STATUS;
+
+ALTER TABLE t1 ADD FULLTEXT INDEX ft5 USING NGRAM (c5);
+SHOW SENNA STATUS;
+
+ALTER TABLE t1 ADD FULLTEXT INDEX ft6 USING NGRAM, NO NORMALIZE (c6);
+SHOW SENNA STATUS;
+
+ALTER TABLE t1 ADD FULLTEXT INDEX ft7 USING NGRAM, 70 (c7);
+SHOW SENNA STATUS;
+
+ALTER TABLE t1 ADD FULLTEXT INDEX ft8 USING NGRAM, NO NORMALIZE, 80 (c8);
+SHOW SENNA STATUS;
+
+DROP TABLE t1;
+
+
+# parser error
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 TEXT
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+--error 1064
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING DUMMY;
+
+--error 1064
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING -100;
+
+--error 1064
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING 10, NGRAM;
+
+--error 1064
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING NGRAM, 10, NO NORMALIZE;
+
+DROP TABLE t1;
+
+
+# drop index and drop error
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 TEXT,
+  FULLTEXT INDEX ft USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+--error 1091
+DROP INDEX dummy ON t1;
+
+DROP INDEX ft ON t1;
+
+DROP TABLE t1;
+
+# charsets
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 TEXT,
+  FULLTEXT INDEX ft USING NGRAM (c2)
+) ENGINE = MyISAM DEFAULT CHARSET cp932;
+
+SHOW SENNA STATUS;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 TEXT CHARSET sjis,
+  c3 TEXT CHARSET cp932,
+  c4 TEXT CHARSET utf8,
+  c5 TEXT CHARSET eucjpms,
+  c6 TEXT CHARSET ujis,
+  FULLTEXT INDEX ft2 USING NGRAM (c2),
+  FULLTEXT INDEX ft3 USING NGRAM (c3),
+  FULLTEXT INDEX ft4 USING NGRAM (c4),
+  FULLTEXT INDEX ft5 USING NGRAM (c5),
+  FULLTEXT INDEX ft6 USING NGRAM (c6)
+) ENGINE = MyISAM;
+
+SHOW SENNA STATUS;
+
+DROP TABLE t1;
+
+--error 1283
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT,
+  c2 TEXT CHARSET sjis,
+  c3 TEXT CHARSET ujis,
+  FULLTEXT INDEX ft USING NGRAM (c2, c3)
+) ENGINE = MyISAM;
+
+# bugfix for delete_all_rows cause missing senna_encoding
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM (c1)) DEFAULT CHARSET utf8;
+SHOW SENNA STATUS;
+DELETE FROM t1;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+# bugfix for delimited flags was ignored
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING DELIMITED (c1)) DEFAULT CHARSET utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+# bugfix: show create table doesn't return senna_flags and ins
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, c3 INT, c4 TEXT, c5 TEXT) DEFAULT CHARSET utf8;
+CREATE INDEX c2 ON t1(c2);
+CREATE FULLTEXT INDEX ft1 ON t1(c4);
+CREATE FULLTEXT INDEX ft2 USING NGRAM, SECTIONALIZE, 64 ON t1(c5);
+CREATE FULLTEXT INDEX ft3 USING DELIMITED, NO NORMALIZE, 128 ON t1(c5);
+CREATE FULLTEXT INDEX ft4 USING SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL, 48 ON t1(c5);
+SHOW CREATE TABLE t1;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+# bugfix: got sig11 when show senna status with view
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 TEXT, FULLTEXT INDEX ft (c2));
+CREATE VIEW v1 AS SELECT * FROM t1;
+SHOW SENNA STATUS;
+DROP VIEW v1;
+DROP TABLE t1;
--- orig/mysql-test/suite/senna/t/senna_eucjpms.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_eucjpms.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,160 @@
+# eucjpms test
+
+SET NAMES utf8;
+
+# TESTS for Ngram
+SELECT "===== TESTS for Ngram started =====";
+
+SELECT "===== creating test data started =====";
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  c1 INT PRIMARY KEY AUTO_INCREMENT, 
+  c2 TEXT,
+  FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET eucjpms;
+
+SHOW CREATE TABLE t1;
+SHOW SENNA STATUS;
+
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+
+SELECT * FROM t1;
+SELECT "===== creating test data finished =====";
+
+# tests for FULLTEXT search
+
+SELECT "===== tests for FULLTEXT search started =====";
+SELECT * FROM t1;
+
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+
+SELECT "===== tests for FULLTEXT search finished =====";
+
+# tests for INSERT
+
+SELECT "===== tests for INSERT started =====";
+SELECT * FROM t1;
+
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+
+SELECT * FROM t1;
+SELECT "===== tests for INSERT finished =====";
+
+# tests for DELETE
+
+SELECT "===== tests for DELETE started =====";
+SELECT * FROM t1;
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+
+SELECT * FROM t1;
+SELECT "===== tests for DELETE finished =====";
+
+# tests for errors
+
+SELECT "===== tests for errors started =====";
+
+--error 1191
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+
+SELECT "===== tests for error finished =====";
+
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
--- orig/mysql-test/suite/senna/t/senna_general.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_general.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,14 @@
+-- source include/have_innodb.inc
+
+set names utf8;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# regression test if innodb won't get error by following sql.
+create table t1 (c1 char(100) unique) engine = innodb;
+insert into t1 values ("test");
+delete from t1 where c1 = "test";
+insert into t1 values ("test");
+drop table t1;
--- orig/mysql-test/suite/senna/t/senna_kwic.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_kwic.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,122 @@
+# test case for kwic native sql function
+SET NAMES utf8;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# string literal
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 1, "","", "東京", "<span class='word'>", "</span>");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>");
+
+# char column
+CREATE TABLE t1 (c1 CHAR(100)) DEFAULT CHARSET utf8;
+INSERT INTO t1 VALUES("今日は東京 >>> 明日は埼玉に行きます。");
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>") FROM t1;
+SELECT KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+SELECT KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>") FROM t1;
+DROP TABLE t1;
+
+# varchar column
+CREATE TABLE t1 (c1 VARCHAR(100)) DEFAULT CHARSET utf8;
+INSERT INTO t1 VALUES("今日は東京 >>> 明日は埼玉に行きます。");
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>") FROM t1;
+SELECT KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+SELECT KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>") FROM t1;
+DROP TABLE t1;
+
+# text column
+CREATE TABLE t1 (c1 TEXT) DEFAULT CHARSET utf8;
+INSERT INTO t1 VALUES("今日は東京 >>> 明日は埼玉に行きます。");
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>") FROM t1;
+SELECT KWIC(c1, 30, 1, 1, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+SELECT KWIC(c1, 45, 1, 0, "... "," ...", "東京", "<span class='word'>", "</span>") FROM t1;
+DROP TABLE t1;
+
+# prepared statement
+CREATE TABLE t1 (c1 TEXT) DEFAULT CHARSET utf8;
+INSERT INTO t1 VALUES("今日は東京 >>> 明日は埼玉に行きます。");
+PREPARE pstmt FROM 'SELECT KWIC(c1, 30, 1, 0, "","", ?, "<span class=\'word\'>", "</span>") FROM t1';
+SET @a = "東京";
+EXECUTE pstmt USING @a;
+DROP TABLE t1;
+
+# twice in one query
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>"),
+KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>");
+
+# nested
+SELECT KWIC(KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>"),
+30, 1, 0, "","", "東京", "<span class='word'>", "</span>");
+
+# null
+SELECT KWIC(null, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>");
+SELECT KWIC(null, null, null, null, null, null, null, null, null);
+
+# invalid number of arguments
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word'>", "</span>", "");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 0, "","", "東京", "<span class='word1'>", "</span>", "埼玉", "<span class='word2'>", "</span>", "");
+
+# invalid value of arguments
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 0, 1, 0, "","", "東京", "<span class='word'>", "</span>", "");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", -10, 1, 0, "","", "東京", "<span class='word'>", "</span>", "");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 0, 0, "","", "東京", "<span class='word'>", "</span>", "");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, -10, 0, "","", "東京", "<span class='word'>", "</span>", "");
+
+# this is acceptable
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, 10, "","", "東京", "<span class='word'>", "</span>", "");
+SELECT KWIC("今日は東京 >>> 明日は埼玉に行きます。", 30, 1, -30, "","", "東京", "<span class='word'>", "</span>", "");
+
+# bugfix for multiple-snippet
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (c1 text) default charset utf8 engine = myisam;
+
+insert into t1 values("今日は埼玉あああああああああああああああああああああああああああああああああああああ。
+明日も埼玉ああああああああああいいいいいいいいいいいいあああああああああああああああああああああ。
+明後日も埼玉あああああああああああああああああああああああああああああああああああ。
+いつでも埼玉あああああああああああああああああああああああああああああああああ。");
+
+select kwic(c1, 20, 1, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+select kwic(c1, 20, 2, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+select kwic(c1, 20, 3, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+select kwic(c1, 20, 4, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+select kwic(c1, 20, 5, 0, "", " ...", "埼玉", "<span id=word>", "</span>") from t1;
+
+select kwic(c1, 20, 1, 0, "(", ")", "埼玉", "[", "]") from t1;
+select kwic(c1, 20, 2, 0, "(", ")", "埼玉", "[", "]") from t1;
+select kwic(c1, 20, 3, 0, "(", ")", "埼玉", "[", "]") from t1;
+select kwic(c1, 20, 4, 0, "(", ")", "埼玉", "[", "]") from t1;
+select kwic(c1, 20, 5, 0, "(", ")", "埼玉", "[", "]") from t1;
+
+drop table t1;
+
+# bugfix colmun data is null
+CREATE TABLE t1 (c1 int, c2 TEXT) DEFAULT CHARSET utf8;
+INSERT INTO t1 (c1) VALUES (100);
+SELECT KWIC(c1, 30, 1, 0, "","", "東京", "<span class='word'>", "</span>") FROM t1;
+DROP TABLE t1;
+
+# bugfix senna buffer overflow.
+create table t1 (c1 longtext, time INT) default charset utf8 engine=myisam;
+insert into t1 (c1, time) VALUES('B A B', 1191299318);
+insert into t1 (c1, time) VALUES('B A B', 1191299722);
+select kwic(c1, 120, 3, 0, "", "", "B", "[", "]") from t1;
+drop table t1;
+
+# bugfix senna buffer overflow
+create table t1 (c1 longtext) default charset utf8 engine=myisam;
+insert into t1 (c1) VALUES('アイコンメニュー と ポートレット から検索');
+select * from t1;
+select kwic(c1, 120, 3, 0, "", "", "アイコンメニュー", "[", "]") from t1;
+select kwic(c1, 120, 3, 0, "", "", "から", "[", "]") from t1;
+select kwic(c1, 120, 3, 0, "", "", "検索", "[", "]") from t1;
+drop table t1;
--- orig/mysql-test/suite/senna/t/senna_section.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_section.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,94 @@
+# test case for multi-section function
+SET NAMES utf8;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 VARCHAR(20), c3 TEXT) DEFAULT CHARSET utf8;
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING NGRAM, SECTIONALIZE (c2,c3);
+SHOW SENNA STATUS;
+
+INSERT INTO t1 VALUES(1, "c2あたりc2", "c3あたりc3");
+INSERT INTO t1 VALUES(2, "c2あたりc2", "c3はずれc3");
+INSERT INTO t1 VALUES(3, "c2はずれc2", "c3あたりc3");
+INSERT INTO t1 VALUES(4, "c2はずれc2", "c3はずれc3"); 
+SELECT * FROM t1;
+
+# non-section search
+SELECT *, MATCH(c2,c3) AGAINST("あたり") AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("あたり") ORDER BY score DESC;
+
+SELECT *, MATCH(c2,c3) AGAINST("あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("あたり" IN BOOLEAN MODE) ORDER BY score DESC;
+
+# simple section search
+SELECT *, MATCH(c2,c3) AGAINST("*W1 あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W1 あたり" IN BOOLEAN MODE);
+
+SELECT *, MATCH(c2,c3) AGAINST("*W2 あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W2 あたり" IN BOOLEAN MODE);
+
+SELECT *, MATCH(c2,c3) AGAINST("*W1,2 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W1,2 あたり" IN BOOLEAN MODE);
+
+# non-existing section number
+SELECT *, MATCH(c2,c3) AGAINST("*W3 あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W3 あたり" IN BOOLEAN MODE);
+
+# section search with weight factor
+SELECT *, MATCH(c2,c3) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c3) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+
+# delete and select
+DELETE FROM t1 WHERE c1 = 2;
+SELECT * FROM t1;
+SELECT *, MATCH(c2,c3) AGAINST("あたり" IN BOOLEAN MODE) AS score  FROM t1
+WHERE MATCH(c2,c3) AGAINST("あたり" IN BOOLEAN MODE);
+
+DELETE FROM t1 WHERE c1 = 4;
+SELECT * FROM t1;
+
+DELETE FROM t1;
+SELECT * FROM t1;
+
+DROP INDEX ft ON t1;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+# complex test
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 VARCHAR(20), c3 INT, c4 TEXT) DEFAULT CHARSET utf8;
+ALTER TABLE t1 ADD FULLTEXT INDEX ft USING NGRAM, SECTIONALIZE (c2,c4);
+SHOW SENNA STATUS;
+
+INSERT INTO t1 VALUES(1, "c2あたりc2", 100, "c4あたりc4");
+INSERT INTO t1 VALUES(2, "c2あたりc2", 200, "c4はずれc4");
+INSERT INTO t1 VALUES(3, "c2はずれc2", 300, "c4あたりc4");
+INSERT INTO t1 VALUES(4, "c2はずれc2", 400, "c4はずれc4");
+
+SELECT *, MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+
+DELETE FROM t1 WHERE c1 = 2;
+SELECT * FROM t1;
+SELECT *, MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+
+INSERT INTO t1 VALUES(2, "c2あたりc2", 200, "c4はずれc4");
+ALTER TABLE t1 ADD c2a INT AFTER c2;
+UPDATE t1 SET c2a = 10;
+
+SELECT *, MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+
+DELETE FROM t1 WHERE c1 = 2;
+SELECT * FROM t1;
+SELECT *, MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE) AS score FROM t1
+WHERE MATCH(c2,c4) AGAINST("*W1:10,2:1 あたり" IN BOOLEAN MODE);
+
+SHOW SENNA STATUS;
+DELETE FROM t1;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+SHOW SENNA STATUS;
--- orig/mysql-test/suite/senna/t/senna_sjis.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_sjis.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,163 @@
+# sjis test
+
+SET NAMES utf8;
+
+# TESTS for Ngram
+SELECT "===== TESTS for Ngram started =====";
+
+SELECT "===== creating test data started =====";
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  c1 INT PRIMARY KEY AUTO_INCREMENT, 
+  c2 TEXT,
+  FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET sjis;
+
+SHOW CREATE TABLE t1;
+SHOW SENNA STATUS;
+
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+# warning 1366
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+# warning 1366
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+# warning 1366
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+
+SELECT * FROM t1;
+SELECT "===== creating test data finished =====";
+
+# tests for FULLTEXT search
+
+SELECT "===== tests for FULLTEXT search started =====";
+SELECT * FROM t1;
+
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+
+SELECT "===== tests for FULLTEXT search finished =====";
+
+# tests for INSERT
+
+SELECT "===== tests for INSERT started =====";
+SELECT * FROM t1;
+
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+
+SELECT * FROM t1;
+SELECT "===== tests for INSERT finished =====";
+
+# tests for DELETE
+
+SELECT "===== tests for DELETE started =====";
+SELECT * FROM t1;
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+
+SELECT * FROM t1;
+SELECT "===== tests for DELETE finished =====";
+
+# tests for errors
+
+SELECT "===== tests for errors started =====";
+
+--error 1191
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+
+SELECT "===== tests for error finished =====";
+
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
--- orig/mysql-test/suite/senna/t/senna_split.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_split.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,266 @@
+# testcase for SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL
+
+SET NAMES utf8;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# create index and show senna status
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_ALPHA (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_DIGIT (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+
+# search without split flags (utf8)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search with split flags (utf8)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search without split flags (cp932)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = cp932;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search with split flags (cp932)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = cp932;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search without split flags (eucjpms)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = eucjpms;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search with split flags (eucjpms)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = eucjpms;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+# testcase for SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL
+
+SET NAMES utf8;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# create index and show senna status
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_ALPHA (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_DIGIT (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft USING NGRAM, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+SHOW SENNA STATUS;
+DROP TABLE t1;
+
+
+# search without split flags (utf8)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search with split flags (utf8)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = utf8;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search without split flags (cp932)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = cp932;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search with split flags (cp932)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = cp932;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search without split flags (eucjpms)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM (c1))
+ENGINE = MyISAM DEFAULT CHARSET = eucjpms;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
+
+# search with split flags (eucjpms)
+
+CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX ft
+USING NGRAM, SPLIT_ALPHA, SPLIT_DIGIT, SPLIT_SYMBOL (c1))
+ENGINE = MyISAM DEFAULT CHARSET = eucjpms;
+
+INSERT INTO t1 VALUES("FedoraCore500の技");
+
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("50");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("00");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Fedo");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("Core");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("500");
+
+DROP TABLE t1;
--- orig/mysql-test/suite/senna/t/senna_ujis.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_ujis.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,162 @@
+# ujis test
+
+SET NAMES utf8;
+
+# TESTS for Ngram
+SELECT "===== TESTS for Ngram started =====";
+
+SELECT "===== creating test data started =====";
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  c1 INT PRIMARY KEY AUTO_INCREMENT, 
+  c2 TEXT,
+  FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET ujis;
+
+SHOW CREATE TABLE t1;
+SHOW SENNA STATUS;
+
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+# warning 1366
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+# warning 1366
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+
+SELECT * FROM t1;
+SELECT "===== creating test data finished =====";
+
+# tests for FULLTEXT search
+
+SELECT "===== tests for FULLTEXT search started =====";
+SELECT * FROM t1;
+
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+
+SELECT "===== tests for FULLTEXT search finished =====";
+
+# tests for INSERT
+
+SELECT "===== tests for INSERT started =====";
+SELECT * FROM t1;
+
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+
+SELECT * FROM t1;
+SELECT "===== tests for INSERT finished =====";
+
+# tests for DELETE
+
+SELECT "===== tests for DELETE started =====";
+SELECT * FROM t1;
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+
+SELECT * FROM t1;
+SELECT "===== tests for DELETE finished =====";
+
+# tests for errors
+
+SELECT "===== tests for errors started =====";
+
+--error 1191
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+
+SELECT "===== tests for error finished =====";
+
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
--- orig/mysql-test/suite/senna/t/senna_utf8.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_utf8.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,160 @@
+# utf8 test
+
+SET NAMES utf8;
+
+# TESTS for Ngram
+SELECT "===== TESTS for Ngram started =====";
+
+SELECT "===== creating test data started =====";
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  c1 INT PRIMARY KEY AUTO_INCREMENT, 
+  c2 TEXT,
+  FULLTEXT INDEX ft USING NGRAM(c2)
+) ENGINE = MyISAM DEFAULT CHARSET utf8;
+
+SHOW CREATE TABLE t1;
+SHOW SENNA STATUS;
+
+INSERT INTO t1 (c2) VALUES ("世界で最もポピュラーなオープンソースデータベースMySQL");
+INSERT INTO t1 (c2) VALUES ("住商情報システムはMySQLのオフィシャルトレーニングと商用ライセンスを提供しております。");
+INSERT INTO t1 (c2) VALUES ("他のオープンソースRDBMSと比較して「高速」で「安定」していることに定評があり、世界で600万のMySQLが稼動しています。");
+INSERT INTO t1 (c2) VALUES ("商用ライセンスは有料ですが、再配布なども自由に行えます。");
+INSERT INTO t1 (c2) VALUES ("信頼性と可用性は、MySQLの大きな特徴です。");
+INSERT INTO t1 (c2) VALUES ("企業のデータを適切に管理することは、DBAの最も大きな仕事です。");
+INSERT INTO t1 (c2) VALUES ("MySQLは優れたセキュリティ機能を提供しています。");
+INSERT INTO t1 (c2) VALUES ("ビジネスシステムで利用する場合には、サポートを購入して頂くことで安心してMySQLをご利用頂けます。");
+INSERT INTO t1 (c2) VALUES ("MySQLの特徴を活かした設計を、お客様のご要件に基づいて行います。");
+INSERT INTO t1 (c2) VALUES ("MySQL Clusterはメモリベースの高速ストレージエンジンです。");
+INSERT INTO t1 (c2) VALUES ("GPLライセンスに基づいてソフトウェアの再配布を行うことができます");
+INSERT INTO t1 (c2) VALUES ("高機能性と高速性の両立は大変ですが、MySQLは機能的にも優れ、かつ性能も非常に良いです。");
+INSERT INTO t1 (c2) VALUES ("GPLソフトウェアは無料ですが、サービスは有料です。");
+INSERT INTO t1 (c2) VALUES ("システム管理工学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("理工学部で物理学を担当している教授です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工です。");
+INSERT INTO t1 (c2) VALUES ("私の専攻は理工*です。");
+INSERT INTO t1 (c2) VALUES ("東の湖にて水泳大会を行います。");
+INSERT INTO t1 (c2) VALUES ("先生、その件について詳しく教えて下さい。");
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+INSERT INTO t1 (c2) VALUES ("御両親の印鑑を押してもらって明日持ってきてください、成績表");
+
+SELECT * FROM t1;
+SELECT "===== creating test data finished =====";
+
+# tests for FULLTEXT search
+
+SELECT "===== tests for FULLTEXT search started =====";
+SELECT * FROM t1;
+
+SELECT c1, MATCH(c2) AGAINST("再配布") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("再配布");
+SELECT c1, MATCH(c2) AGAINST("機能") as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("機能");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("最新");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 +有料" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -有料" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("OR 再配布 OR 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 ~ 商用" IN BOOLEAN MODE);
+SELECT c1, MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE) as score, c2 FROM t1 WHERE MATCH(c2) AGAINST("+再配布 < 商用 > 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("OR 商用 OR 教えて" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("+再配布 -(OR 商用 OR 教えて)" IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('"DBMS"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*D- +再配布 自由' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('+信頼性 -埼玉 -東京 -千葉 -神奈川 -山梨 -新潟 -静岡 -長野 -栃木 -群馬 -茨城 -福島 -青森 -岩手 -山形 -秋田 -富山 -加賀 -滋賀 -愛知 -岐阜 -京都 -大阪 -奈良 -和歌山 -愛媛 -高知 -徳島 -岡山 -広島 -鳥取 -特徴' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N100"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N8"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N7"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N6"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N5"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N4"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N3"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N2"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N1"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST('*N0"湖 水泳"' IN BOOLEAN MODE);
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("成績表");
+
+SELECT "===== tests for FULLTEXT search finished =====";
+
+# tests for INSERT
+
+SELECT "===== tests for INSERT started =====";
+SELECT * FROM t1;
+
+INSERT INTO t1 (c2) VALUES ("普段から緊急事態に備えておかなければならない。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+INSERT INTO t1 (c2) VALUES ("宛名書きは住商情報システム㈱でお願いいたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+INSERT INTO t1 (c2) VALUES ("ファイナルファンタジーⅶを1本下さい。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+INSERT INTO t1 (c2) VALUES ("NEC選定IBM拡張文字の淼について今日はお話いたします。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+INSERT INTO t1 (c2) VALUES ("日本語の文字の種類のひとつとして半角カタカナがある。");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+INSERT INTO t1 (c2) VALUES ("職員室に忘れて置いてきてしまった出席表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("出席表");
+
+SELECT * FROM t1;
+SELECT "===== tests for INSERT finished =====";
+
+# tests for DELETE
+
+SELECT "===== tests for DELETE started =====";
+SELECT * FROM t1;
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("緊急");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("㈱");
+
+DELETE FROM t1  WHERE MATCH(c2) AGAINST("ⅶ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("ⅶ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("淼");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("淼");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("カタカナ");
+
+DELETE FROM t1 WHERE MATCH(c2) AGAINST("表");
+SELECT * FROM t1 WHERE MATCH(c2) AGAINST("表");
+
+SELECT * FROM t1;
+SELECT "===== tests for DELETE finished =====";
+
+# tests for errors
+
+SELECT "===== tests for errors started =====";
+
+--error 1191
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー");
+SELECT * FROM t1 WHERE MATCH(c1) AGAINST("ダミー" IN BOOLEAN MODE);
+
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー");
+--error 1054
+SELECT * FROM t1 WHERE MATCH(c3) AGAINST("ダミー" IN BOOLEAN MODE);
+
+SELECT "===== tests for error finished =====";
+
+DROP TABLE t1;
+SELECT "===== TESTS for Ngram finished =====";
--- orig/mysql-test/suite/senna/t/senna_util.test	1970-01-01 09:00:00.000000000 +0900
+++ new/mysql-test/suite/senna/t/senna_util.test	2009-11-16 17:45:02.000000000 +0900
@@ -0,0 +1,88 @@
+
+# test for added senna variables
+
+SHOW VARIABLES LIKE 'senna_%';
+
+# test for senna_log_level
+
+--error 1229
+SET senna_log_level=INFO;
+
+SET GLOBAL senna_log_level=NONE;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=EMERG;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=ALERT;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=CRIT;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=ERROR;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=WARNING;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=NOTICE;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=INFO;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=DEBUG;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+SET GLOBAL senna_log_level=DUMP;
+SHOW GLOBAL VARIABLES LIKE 'senna_log_level';
+
+--error 1231
+SET GLOBAL senna_log_level=DUMMY;
+SHOW VARIABLES LIKE 'senna_log_level';
+
+# test for senna_2ind
+
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+
+SET senna_2ind=ON;
+
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+
+SET senna_2ind=OFF;
+
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+
+SET GLOBAL senna_2ind=ON;
+
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+
+SET GLOBAL senna_2ind=OFF;
+
+SHOW GLOBAL VARIABLES LIKE 'senna_2ind';
+SHOW SESSION VARIABLES LIKE 'senna_2ind';
+
+--error 1231
+SET senna_2ind=DUMMY;
+
+--error 1231
+SET GLOBAL senna_2ind=DUMMY;
+
+# test for senna_index_type
+
+SHOW VARIABLES LIKE 'senna_index_type';
+SET GLOBAL senna_index_type=mecab;
+SHOW VARIABLES LIKE 'senna_index_type';
+SET GLOBAL senna_index_type=ngram;
+SHOW VARIABLES LIKE 'senna_index_type';
+
+--error 1231
+SET GLOBAL senna_index_type=hoge;
+
+--error 1229
+SET SESSION senna_index_type=ngram;
--- orig/sql/Makefile.am	2009-10-16 06:20:32.000000000 +0900
+++ new/sql/Makefile.am	2009-11-16 17:45:02.000000000 +0900
@@ -22,7 +22,7 @@ INCLUDES =		@ZLIB_INCLUDES@ \
 			@bdb_includes@ @innodb_includes@ @ndbcluster_includes@ \
 			-I$(top_builddir)/include -I$(top_srcdir)/include \
 			-I$(top_srcdir)/regex -I$(srcdir) \
-                        $(openssl_includes)
+                        $(openssl_includes) @SENNA_INCLUDES@ @MECAB_INCLUDES@
 WRAPLIBS=		@WRAPLIBS@
 SUBDIRS =		share
 libexec_PROGRAMS =	mysqld
@@ -43,7 +43,7 @@ mysqld_LDADD =		@MYSQLD_EXTRA_LDFLAGS@ \
                         @innodb_system_libs@ \
 			@ndbcluster_libs@ @ndbcluster_system_libs@ \
 			$(LDADD)  $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
-			$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
+			$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@ @SENNA_LIBS@ @MECAB_LIBS@
 
 noinst_HEADERS =	item.h item_func.h item_sum.h item_cmpfunc.h \
 			item_strfunc.h item_timefunc.h item_uniq.h \
--- orig/sql/filesort.cc	2009-10-16 06:20:32.000000000 +0900
+++ new/sql/filesort.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1374,6 +1374,10 @@ sortlength(THD *thd, SORT_FIELD *sortord
       }
       if (sortorder->field->maybe_null())
 	length++;				// Place for NULL marker
+#ifdef ENABLE_SENNA
+      if (my_thread_var->sen_flags & SENNA_USE_2IND)
+	DEBUG_2IND(my_thread_var->sen_flags |= SENNA_FILESORT);
+#endif /* ENABLE_SENNA */
     }
     else
     {
--- orig/sql/ha_myisam.cc	2009-10-16 06:20:33.000000000 +0900
+++ new/sql/ha_myisam.cc	2009-11-16 17:45:02.000000000 +0900
@@ -128,6 +128,62 @@ static void mi_check_print_msg(MI_CHECK 
   return;
 }
 
+#ifdef ENABLE_SENNA
+typedef struct st_senna_enc_map {
+  char* enc_mysql;
+  sen_encoding enc_senna;
+} SENNA_ENC_MAP;
+
+SENNA_ENC_MAP senna_enc_mapping[] = {
+  {"utf8", sen_enc_utf8},
+  {"cp932", sen_enc_sjis},
+  {"sjis", sen_enc_sjis},
+  {"eucjpms", sen_enc_euc_jp},
+  {"ujis", sen_enc_euc_jp},
+  {"latin1", sen_enc_latin1},
+  {"koi8r", sen_enc_koi8r},
+  {0, sen_enc_default},
+  {0, sen_enc_none}};  /* this must be last */
+
+sen_encoding senna_enc_senna(const char *csname)
+{
+  if (!csname) return sen_enc_none;
+  int i;
+  for (i = 0; senna_enc_mapping[i].enc_mysql; i++) {
+    if (!(my_strcasecmp(system_charset_info, csname,
+                       senna_enc_mapping[i].enc_mysql)))
+      return senna_enc_mapping[i].enc_senna;
+  }
+  return sen_enc_none;
+}
+
+char *senna_enc_mysql(sen_encoding encoding)
+{
+  int i;
+  for (i = 0; (senna_enc_mapping[i].enc_senna != sen_enc_default); i++) {
+    if (senna_enc_mapping[i].enc_senna == encoding)
+      return senna_enc_mapping[i].enc_mysql;
+  }
+  return 0;
+}
+
+#ifdef USE_QUERY_ABORT
+static int senna_check_abort(void *)
+{
+  return current_thd->killed == THD::KILL_CONNECTION;
+}
+
+static void senna_set_abort_handler(MYISAM_SHARE *share)
+{
+  for (uint i = 0; i < (uint)share->state.header.keys; i++) {
+    if (share->keyinfo[i].senna != NULL) {
+      sen_index_set_abort_callback(share->keyinfo[i].senna, senna_check_abort,
+				   NULL);
+    }
+  }
+}
+#endif /* USE_QUERY_ABORT */
+#endif /* ENABLE_SENNA */
 
 /*
   Convert TABLE object to MyISAM key and column definition
@@ -174,6 +230,18 @@ int table2myisam(TABLE *table_arg, MI_KE
   for (i= 0; i < share->keys; i++, pos++)
   {
     keydef[i].flag= ((uint16) pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL));
+#ifdef ENABLE_SENNA
+    if ((keydef[i].flag & HA_FULLTEXT)) {
+      if (table_arg->key_info) {
+	keydef[i].senna_flags=pos->senna_flags;
+	keydef[i].senna_initial_n_segments=pos->senna_initial_n_segments;
+	keydef[i].senna_encoding=senna_enc_senna(pos->senna_encoding);
+      } else {
+	keydef[i].senna_flags=SEN_DISABLE_SENNA;
+	keydef[i].senna_initial_n_segments=0;
+      }
+    }
+#endif /* ENABLE_SENNA */
     keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ?
       (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) :
       pos->algorithm;
@@ -461,7 +529,6 @@ int check_definition(MI_KEYDEF *t1_keyin
   DBUG_RETURN(0);
 }
 
-
 extern "C" {
 
 volatile int *killed_ptr(MI_CHECK *param)
@@ -533,9 +600,12 @@ const char **ha_myisam::bas_ext() const
 
 const char *ha_myisam::index_type(uint key_number)
 {
-  return ((table->key_info[key_number].flags & HA_FULLTEXT) ? 
-	  "FULLTEXT" :
-	  (table->key_info[key_number].flags & HA_SPATIAL) ?
+  if (table->key_info[key_number].flags & HA_FULLTEXT)
+  {
+    return "FULLTEXT";
+  }
+  else
+  return ((table->key_info[key_number].flags & HA_SPATIAL) ?
 	  "SPATIAL" :
 	  (table->key_info[key_number].algorithm == HA_KEY_ALG_RTREE) ?
 	  "RTREE" :
@@ -642,6 +712,11 @@ int ha_myisam::open(const char *name, in
     int_table_flags|=HA_REC_NOT_IN_SEQ;
   if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
     int_table_flags|=HA_HAS_CHECKSUM;
+#ifdef ENABLE_SENNA
+#ifdef USE_QUERY_ABORT
+  senna_set_abort_handler(file->s);
+#endif
+#endif
   return (0);
 }
 
@@ -1664,6 +1739,30 @@ int ha_myisam::info(uint flag)
     delete_length=     misam_info.delete_length;
     check_time=        misam_info.check_time;
     mean_rec_length= misam_info.mean_reclength;
+#ifdef ENABLE_SENNA
+    if (flag & HA_STATUS_SENNA) {
+      int i;
+      for (i = 0; i < table->s->keys; i++) {
+	KEY *key = &table->key_info[i];
+	MI_KEYDEF *mi_keydef = &file->s->keyinfo[i];
+	sen_index *senna = mi_keydef->senna;
+	if (senna) {
+	  key->is_senna = true;
+	  key->senna_flags = mi_keydef->senna_flags;
+	  key->senna_initial_n_segments = mi_keydef->senna_initial_n_segments;
+	  key->senna_keys_size = mi_keydef->senna_keys_size;
+	  key->senna_keys_file_size = mi_keydef->senna_keys_file_size;
+	  key->senna_lexicon_size = mi_keydef->senna_lexicon_size;
+	  key->senna_lexicon_file_size = mi_keydef->senna_lexicon_file_size;
+	  key->senna_inv_seg_size = mi_keydef->senna_inv_seg_size;
+	  key->senna_inv_chunk_size = mi_keydef->senna_inv_chunk_size;
+
+	  key->senna_encoding = senna_enc_mysql(mi_keydef->senna_encoding);
+	} else
+	  key->senna_flags = false;
+      }
+    }
+#endif /* ENABLE_SENNA */
   }
   if (flag & HA_STATUS_CONST)
   {
@@ -1760,7 +1859,12 @@ THR_LOCK_DATA **ha_myisam::store_lock(TH
 
 void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
 {
+#ifdef ENABLE_SENNA
+  ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST |
+		  HA_STATUS_VARIABLE | HA_STATUS_SENNA);
+#else
   ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST);
+#endif
   if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
   {
     create_info->auto_increment_value=auto_increment_value;
@@ -1788,8 +1892,36 @@ int ha_myisam::create(const char *name, 
   TABLE_SHARE *share= table->s;
   uint options= share->db_options_in_use;
   DBUG_ENTER("ha_myisam::create");
+#ifdef ENABLE_SENNA
+  if ((ha_create_info->query_type == SENNA_CREATE_TABLE))
+  {
+    int i;
+    for (i=0; i < share->keys; i++)
+    {
+      if ((ha_create_info->key_info[i].flags & HA_FULLTEXT))
+      {
+	table_arg->key_info[i].senna_flags = ha_create_info->key_info[i].senna_flags;
+	table_arg->key_info[i].senna_initial_n_segments = ha_create_info->key_info[i].senna_initial_n_segments; 
+	table_arg->key_info[i].senna_encoding = ha_create_info->key_info[i].senna_encoding;
+      }
+    }
+  }
+  else if ((ha_create_info->query_type == SENNA_TRUNCATE_TABLE) && file) /* file check for restore table */
+  {
+    table_arg->file->open(name,0,0);
+    table_arg->file->info(HA_STATUS_VARIABLE | HA_STATUS_SENNA);
+  }
+  else if ((ha_create_info->query_type == SENNA_CREATE_TABLE_LIKE))
+  {
+    SEN_LOG(sen_log_warning, "ha_myisam::create: create table %s like ... may lost senna extention", name);
+  }
+#endif /* ENABLE_SENNA */
   if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
     DBUG_RETURN(error); /* purecov: inspected */
+#ifdef ENABLE_SENNA
+  if ((ha_create_info->query_type == SENNA_TRUNCATE_TABLE) && file)
+    table_arg->file->close();
+#endif
   bzero((char*) &create_info, sizeof(create_info));
   create_info.max_rows= share->max_rows;
   create_info.reloc_rows= share->min_rows;
--- orig/sql/handler.h	2009-10-16 06:20:33.000000000 +0900
+++ new/sql/handler.h	2009-11-16 17:45:02.000000000 +0900
@@ -479,6 +479,10 @@ typedef struct st_ha_create_information
   bool table_existed;			/* 1 in create if table existed */
   bool frm_only;                        /* 1 if no ha_create_table() */
   bool varchar;                         /* 1 if table has a VARCHAR */
+#ifdef ENABLE_SENNA
+  KEY *key_info;
+  int query_type;
+#endif /* ENABLE_SENNA */
 } HA_CREATE_INFO;
 
 
--- orig/sql/item.h	2009-10-16 06:20:33.000000000 +0900
+++ new/sql/item.h	2009-11-16 17:45:02.000000000 +0900
@@ -724,7 +724,9 @@ public:
     Any new item which can be NULL must implement this method.
   */
   virtual bool is_null() { return 0; }
-
+#ifdef ENABLE_SENNA
+  virtual bool needs_record() { return true; }
+#endif /* ENABLE_SENNA */
   /*
    Make sure the null_value member has a correct value.
   */
--- orig/sql/item_cmpfunc.cc	2009-10-16 06:20:33.000000000 +0900
+++ new/sql/item_cmpfunc.cc	2009-11-16 17:45:02.000000000 +0900
@@ -3375,6 +3375,22 @@ bool Item_func_in::nulls_in_row()
   return 0;
 }
 
+#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 */
 
 /*
   Perform context analysis of an IN item tree
--- orig/sql/item_cmpfunc.h	2009-10-16 06:20:33.000000000 +0900
+++ new/sql/item_cmpfunc.h	2009-11-16 17:45:02.000000000 +0900
@@ -1376,6 +1376,9 @@ public:
   void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
   bool fix_fields(THD *, 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;
--- orig/sql/item_func.cc	2009-10-16 06:20:33.000000000 +0900
+++ new/sql/item_func.cc	2009-11-16 18:01:29.000000000 +0900
@@ -5069,9 +5069,12 @@ bool Item_func_match::fix_index()
   for (keynr=0 ; keynr < table->s->keys ; keynr++)
   {
     if ((table->key_info[keynr].flags & HA_FULLTEXT) &&
-        (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) :
-                           table->s->keys_in_use.is_set(keynr)))
-
+        ((flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) :
+	  table->s->keys_in_use.is_set(keynr))
+#ifdef ENABLE_SENNA
+	 || my_thread_var->sen_flags
+#endif /* ENABLE_SENNA */
+	 ))
     {
       ft_to_key[fts]=keynr;
       ft_cnt[fts]=0;
--- orig/sql/item_func.h	2009-10-16 06:20:33.000000000 +0900
+++ new/sql/item_func.h	2009-11-16 17:45:02.000000000 +0900
@@ -1465,6 +1465,9 @@ public:
   table_map not_null_tables() const { return 0; }
   bool fix_fields(THD *thd, 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_real() != 0.0; }
   double val_real();
--- orig/sql/item_strfunc.cc	2009-10-16 06:20:34.000000000 +0900
+++ new/sql/item_strfunc.cc	2009-11-16 17:45:02.000000000 +0900
@@ -34,6 +34,9 @@
 C_MODE_START
 #include "../mysys/my_static.h"			// For soundex_map
 C_MODE_END
+#ifdef ENABLE_SENNA
+#include <senna.h>
+#endif /* ENABLE_SENNA */
 
 String my_empty_string("",default_charset_info);
 
@@ -3422,3 +3425,213 @@ String *Item_func_uuid::val_str(String *
   strmov(s+18, clock_seq_and_node_str);
   return str;
 }
+
+#ifdef ENABLE_SENNA
+static sen_encoding senna_enc_type(const char *csname)
+{
+  if (!my_strcasecmp(system_charset_info, csname, "latin1"))
+    return sen_enc_latin1;
+  else if (!my_strcasecmp(system_charset_info, csname, "utf8"))
+    return sen_enc_utf8;
+  else if (!my_strcasecmp(system_charset_info, csname, "cp932"))
+    return sen_enc_sjis;
+  else if (!my_strcasecmp(system_charset_info, csname, "sjis"))
+    return sen_enc_sjis;
+  else if (!my_strcasecmp(system_charset_info, csname, "eucjpms"))
+    return sen_enc_euc_jp;
+  else if (!my_strcasecmp(system_charset_info, csname, "ujis"))
+    return sen_enc_euc_jp;
+  else if (!my_strcasecmp(system_charset_info, csname, "koi8r"))
+    return sen_enc_koi8r;
+  else
+    return sen_enc_default;
+}
+
+
+String *Item_func_senna_kwic::val_str(String *str)
+{
+  String *target, target_tmp;
+  int max_snip_len;
+  int max_snips;
+  int html_encoding;
+  String *start, start_tmp;
+  String *end, end_tmp;
+  String *keyword, keyword_tmp;
+  String *open_tag, open_tmp;
+  String *close_tag, close_tmp;
+
+  sen_snip *snip;
+  sen_encoding encoding;
+  sen_rc rc;
+  uint nresults;
+  uint max_tagged_len;
+  sen_snip_mapping *mapping;
+
+  char *result;
+  uint result_len;
+  int i;
+
+  null_value=0;
+
+  if (arg_count < 9 || arg_count % 3 != 0) {
+    SEN_LOG(sen_log_warning, "Incorrect number of arguments for kwic: %d", arg_count);
+    return &my_empty_string;
+  }
+
+  for (i = 0; i < arg_count; i++) {
+    if (!(args[i]->val_str(str))) {
+      SEN_LOG(sen_log_warning, "kwic argument #%d is null", i+1);
+      goto err_null;
+    }
+  }
+
+  target        = args[0]->str_result(&target_tmp);
+  max_snip_len  = args[1]->val_int();
+  max_snips     = args[2]->val_int();
+  html_encoding = args[3]->val_int();
+  start         = args[4]->str_result(&start_tmp);
+  end           = args[5]->str_result(&end_tmp);
+
+  if (max_snip_len <= 0) {
+    SEN_LOG(sen_log_warning, "kwic argument #2 must be positive value, passed %d", max_snip_len);
+    return &my_empty_string;
+  }
+
+  if (max_snips <= 0) {
+    SEN_LOG(sen_log_warning, "kwic argument #3 must be positive value, passed %d", max_snips);
+    return &my_empty_string;
+  }
+
+  if (target == NULL) return &my_empty_string;
+  encoding = senna_enc_senna(target->charset()->csname);
+  if (html_encoding == 1) {
+    mapping = (sen_snip_mapping *) -1;
+  } else {
+    mapping = NULL;
+  }
+
+  SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_open: " \
+	  "%d, SEN_SNIP_NORMALIZE | SEN_SNIP_SKIP_LEADING_SPACES, %d, %d, \"\", 0, \"\", 0, %p",
+	  encoding, max_snip_len, max_snips, mapping);
+  if (!(snip = sen_snip_open(encoding, SEN_SNIP_NORMALIZE | SEN_SNIP_SKIP_LEADING_SPACES, 
+			     max_snip_len, max_snips, "", 0,
+			     "", 0, mapping))) {
+    SEN_LOG(sen_log_error, "sen_snip_open failed: snip = %p", snip);
+    return &my_empty_string;
+  }
+
+  for (i = 6; i < arg_count; i+=3) {
+    keyword       = args[i]->str_result(&keyword_tmp);
+    open_tag      = args[i+1]->str_result(&open_tmp);
+    close_tag     = args[i+2]->str_result(&close_tmp);
+
+    SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_add_cond: " \
+	    "%p, %p, %d, %p, %d, %p, %d", snip, keyword->ptr(), keyword->length(),
+	    open_tag->ptr(), open_tag->length(), close_tag->ptr(), close_tag->length());
+    if ((rc = sen_snip_add_cond(snip, keyword->ptr(), keyword->length(),
+				open_tag->ptr(), open_tag->length(),
+				close_tag->ptr(), close_tag->length()))) {
+      SEN_LOG(sen_log_error, "sen_snip_add_cond failed: sen_rc= %d", rc);
+      SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	      "snip = %p", snip);
+      if ((rc = sen_snip_close(snip))) {
+	SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+      }
+      return &my_empty_string;
+    }
+  }
+
+  SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_exec: " \
+	  "%p, %p, %d, %p, %p", snip, target->ptr(), target->length(),
+	  &nresults, &max_tagged_len);
+  if ((rc = sen_snip_exec(snip, target->ptr(), target->length(),
+			  &nresults, &max_tagged_len))) {
+    SEN_LOG(sen_log_error, "sen_snip_exec failed: sen_rc= %d", rc);
+    SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	    "snip = %p", snip);
+    if ((rc = sen_snip_close(snip))) {
+      SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+    }
+    return &my_empty_string;
+  }
+
+
+  if (!(result = sql_alloc(max_tagged_len))) {
+    SEN_LOG(sen_log_error, "sql_alloc failed", rc);
+    SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+            "snip = %p\n", snip);
+    if ((rc = sen_snip_close(snip))) {
+      SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d\n", rc);
+    }
+    return &my_empty_string;
+  }
+
+  str->copy("", 0, target->charset());
+
+  for (i = 0; i < nresults; i++) {
+    SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_get_result: " \
+	    "%p, 0, %p, %p", snip, result, &result_len);
+    if ((rc = sen_snip_get_result(snip, i, result, &result_len))) {
+      SEN_LOG(sen_log_error, "sen_snip_get_result failed: sen_rc= %d", rc);
+      SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	      "snip = %p", snip);
+      if ((rc = sen_snip_close(snip))) {
+	SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+      }
+      return &my_empty_string;
+    }
+    
+    if (result_len <= 0) {
+      SEN_LOG(sen_log_error, "result_len is not positive value: %d", result_len);
+      SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	      "snip = %p", snip);
+      if ((rc = sen_snip_close(snip))) {
+	SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+      }
+      return &my_empty_string;
+    }
+    
+    str->append(start->ptr(), start->length(), target->charset());
+    str->append(result, result_len, target->charset());
+    str->append(end->ptr(), end->length(), target->charset());
+  }
+
+  SEN_LOG(sen_log_debug, "Item_func_senna_kwic::val_str => sen_snip_close: " \
+	  "snip = %p", snip);
+  if ((rc = sen_snip_close(snip))) {
+    SEN_LOG(sen_log_error, "sen_snip_close failed: sen_rc = %d", rc);
+  }
+
+  return str;
+
+err_null:
+  null_value= 1;
+  return 0;
+}
+
+
+void Item_func_senna_kwic::fix_length_and_dec()
+{
+  ulonglong max_result_length= 0;
+
+  if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
+    return;
+
+  for (uint i=0 ; i < arg_count ; i++)
+  {
+    if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
+      max_result_length+= (args[i]->max_length /
+                           args[i]->collation.collation->mbmaxlen) *
+                           collation.collation->mbmaxlen;
+    else
+      max_result_length+= args[i]->max_length;
+  }
+
+  if (max_result_length >= MAX_BLOB_WIDTH)
+  {
+    max_result_length= MAX_BLOB_WIDTH;
+    maybe_null= 1;
+  }
+  max_length= (ulong) max_result_length;
+}
+#endif /* ENABLE_SENNA */
--- orig/sql/item_strfunc.h	2009-10-16 06:20:34.000000000 +0900
+++ new/sql/item_strfunc.h	2009-11-16 17:45:02.000000000 +0900
@@ -869,3 +869,14 @@ public:
   String *val_str(String *);
 };
 
+#ifdef ENABLE_SENNA
+class Item_func_senna_kwic :public Item_str_func
+{
+ public:
+  Item_func_senna_kwic(List<Item> &list) :Item_str_func(list) {}
+  Item_func_senna_kwic(Item *a,Item *b) :Item_str_func(a,b) {}
+  String *val_str(String *);
+  void fix_length_and_dec();
+  const char *func_name() const { return "kwic"; }
+};
+#endif /* ENABLE SENNA */
--- orig/sql/item_sum.cc	2009-10-16 06:20:34.000000000 +0900
+++ new/sql/item_sum.cc	2009-11-16 17:45:02.000000000 +0900
@@ -2552,6 +2552,10 @@ bool Item_sum_count_distinct::setup(THD 
     return TRUE;
 
   /* Create a table with an unique key over all parameters */
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND)
+    DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DISTINCT);
+#endif /* ENABLE_SENNA */
   for (uint i=0; i < arg_count ; i++)
   {
     Item *item=args[i];
--- orig/sql/lex.h	2009-10-16 06:20:34.000000000 +0900
+++ new/sql/lex.h	2009-11-16 17:45:02.000000000 +0900
@@ -157,6 +157,7 @@ static SYMBOL symbols[] = {
   { "DELAYED",		SYM(DELAYED_SYM)},
   { "DELAY_KEY_WRITE",	SYM(DELAY_KEY_WRITE_SYM)},
   { "DELETE",		SYM(DELETE_SYM)},
+  { "DELIMITED",	SYM(SENNA_DELIMITED_SYM)},
   { "DESC",		SYM(DESC)},
   { "DESCRIBE",		SYM(DESCRIBE)},
   { "DES_KEY_FILE",	SYM(DES_KEY_FILE)},
@@ -311,6 +312,7 @@ static SYMBOL symbols[] = {
   { "MAX_ROWS",		SYM(MAX_ROWS)},
   { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR)},
   { "MAX_USER_CONNECTIONS", SYM(MAX_USER_CONNECTIONS_SYM)},
+  { "MECAB",            SYM(SENNA_MECAB_SYM)},
   { "MEDIUM",		SYM(MEDIUM_SYM)},
   { "MEDIUMBLOB",	SYM(MEDIUMBLOB)},
   { "MEDIUMINT",	SYM(MEDIUMINT)},
@@ -342,8 +344,10 @@ static SYMBOL symbols[] = {
   { "NCHAR",		SYM(NCHAR_SYM)},
   { "NEW",              SYM(NEW_SYM)},
   { "NEXT",		SYM(NEXT_SYM)},
+  { "NGRAM",		SYM(SENNA_NGRAM_SYM)},
   { "NO",		SYM(NO_SYM)},
   { "NONE",		SYM(NONE_SYM)},
+  { "NORMALIZE",	SYM(SENNA_NORMALIZE_SYM)},
   { "NOT",		SYM(NOT_SYM)},
   { "NO_WRITE_TO_BINLOG",  SYM(NO_WRITE_TO_BINLOG)},
   { "NULL",		SYM(NULL_SYM)},
@@ -428,8 +432,10 @@ static SYMBOL symbols[] = {
   { "SCHEMAS",          SYM(DATABASES)},
   { "SECOND",		SYM(SECOND_SYM)},
   { "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM)},
+  { "SECTIONALIZE",     SYM(SENNA_SECTIONALIZE_SYM)},
   { "SECURITY",         SYM(SECURITY_SYM)},
   { "SELECT",		SYM(SELECT_SYM)},
+  { "SENNA",		SYM(SENNA_SYM)},
   { "SENSITIVE",        SYM(SENSITIVE_SYM)},
   { "SEPARATOR",	SYM(SEPARATOR_SYM)},
   { "SERIAL",		SYM(SERIAL_SYM)},
@@ -450,6 +456,9 @@ static SYMBOL symbols[] = {
   { "SOURCE",   SYM(SOURCE_SYM)},
   { "SPATIAL",		SYM(SPATIAL_SYM)},
   { "SPECIFIC",         SYM(SPECIFIC_SYM)},
+  { "SPLIT_ALPHA",      SYM(SENNA_SPLIT_ALPHA_SYM)},
+  { "SPLIT_DIGIT",      SYM(SENNA_SPLIT_DIGIT_SYM)},
+  { "SPLIT_SYMBOL",     SYM(SENNA_SPLIT_SYMBOL_SYM)},
   { "SQL",              SYM(SQL_SYM)},
   { "SQLEXCEPTION",     SYM(SQLEXCEPTION_SYM)},
   { "SQLSTATE",         SYM(SQLSTATE_SYM)},
@@ -656,6 +665,9 @@ static SYMBOL sql_functions[] = {
   { "ISNULL",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)},
   { "IS_FREE_LOCK",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)},
   { "IS_USED_LOCK",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_used_lock)},
+#ifdef ENABLE_SENNA
+  { "KWIC",             SYM(SENNA_KWIC_SYM)},
+#endif /* ENABLE_SENNA */
   { "LAST_INSERT_ID",	SYM(LAST_INSERT_ID)},
   { "ISSIMPLE",         F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_issimple)},
   { "LAST_DAY",         F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_last_day)},
--- orig/sql/mysql_priv.h	2009-10-16 06:20:34.000000000 +0900
+++ new/sql/mysql_priv.h	2009-11-16 17:45:02.000000000 +0900
@@ -995,6 +995,11 @@ void calc_sum_of_all_status(STATUS_VAR *
 void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
                     const LEX_STRING *definer_host);
 
+#ifdef ENABLE_SENNA
+bool senna_show_status(THD *thd, LEX *lex);
+char *senna_enc_mysql(sen_encoding encoding);
+sen_encoding senna_enc_senna(const char *csname);
+#endif 
 
 /* information schema */
 extern LEX_STRING INFORMATION_SCHEMA_NAME;
@@ -1494,6 +1499,13 @@ extern SHOW_COMP_OPTION have_compress;
 extern SHOW_COMP_OPTION have_community_features;
 extern SHOW_COMP_OPTION have_profiling;
 
+#ifdef ENABLE_SENNA
+extern my_bool opt_senna_log;
+extern uint senna_log_level_options;
+extern uint senna_index_type_options;
+extern int senna_default_flags;
+#endif
+
 #ifndef __WIN__
 extern pthread_t signal_thread;
 #endif
--- orig/sql/mysqld.cc	2009-10-16 06:20:34.000000000 +0900
+++ new/sql/mysqld.cc	2009-11-16 17:45:02.000000000 +0900
@@ -364,6 +364,12 @@ static pthread_cond_t COND_thread_cache,
 static my_bool opt_sync_bdb_logs;
 #endif
 
+#ifdef ENABLE_SENNA
+static char *opt_senna_logname;
+static char *opt_senna_log_level;
+static char *opt_senna_index_type;
+#endif
+
 /* Global variables */
 
 bool opt_update_log, opt_bin_log;
@@ -541,6 +547,14 @@ SHOW_COMP_OPTION have_crypt, have_compre
 SHOW_COMP_OPTION have_community_features;
 SHOW_COMP_OPTION have_profiling;
 
+#ifdef ENABLE_SENNA
+my_bool opt_senna_log;
+char* senna_logname;
+uint senna_log_level_options;
+uint senna_index_type_options;
+int senna_default_flags;
+#endif
+
 /* Thread specific variables */
 
 pthread_key(MEM_ROOT**,THR_MALLOC);
@@ -1025,9 +1039,16 @@ static void __cdecl kill_server(int sig_
   if (sig != 0) // 0 is not a valid signal number
     my_sigset(sig, SIG_IGN);                    /* purify inspected */
   if (sig == MYSQL_KILL_SIGNAL || sig == 0)
+	{
     sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
+#ifdef ENABLE_SENNA /* nkjm added below for SFID:10293 2007/04/26. */
+    SEN_LOG(sen_log_notice, "kill_server: mysqld is shutting down...");
+#endif /* nkjm added above. */
+	}
   else
+	{
     sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
+	}
 
 #if defined(HAVE_SMEM) && defined(__WIN__)
   /*
@@ -1215,7 +1236,13 @@ void clean_up(bool print_message)
 #endif
 
   if (print_message && errmesg)
+	{
     sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
+#ifdef ENABLE_SENNA /* nkjm added below for SFID:10293 2007/04/26.  */
+    SEN_LOG(sen_log_notice, "clean_up: mysqld shutdown complete.");
+#endif /* nkjm added above. */
+	}
+
 #if !defined(EMBEDDED_LIBRARY)
   if (!opt_bootstrap)
     (void) my_delete(pidfile_name,MYF(0));	// This may not always exist
@@ -1745,6 +1772,14 @@ void end_thread(THD *thd, bool put_in_ca
       thd->mysys_var->abort= 0;
       thd->thr_create_time= time(NULL);
       threads.append(thd);
+
+#if !defined(__WIN__) && !defined(OS2) && defined ENABLE_SENNA /* nkjm SFID:10294 */
+      struct st_my_thread_var *sen_tmp;
+      extern pthread_key_t THR_KEY_mysys;
+      sen_tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
+      sen_tmp->sen_connection_id= thd->thread_id;
+#endif /* nkjm SFID:10294 */
+
       pthread_mutex_unlock(&LOCK_thread_count);
       DBUG_VOID_RETURN;
     }
@@ -3748,6 +3783,27 @@ int main(int argc, char **argv)
 
   (void) thr_setconcurrency(concurrency);	// 10 by default
 
+#ifdef ENABLE_SENNA
+  sen_init();
+  if (opt_senna_log)
+  {
+    if (!opt_senna_logname) opt_senna_logname = "senna.log";
+    int senna_logname_len = strlen(mysql_data_home) + strlen(opt_senna_logname) + 1;
+    senna_logname = my_malloc(senna_logname_len, MYF(MY_WME));
+    my_snprintf(senna_logname, senna_logname_len, "%s%s", mysql_data_home, opt_senna_logname);
+    senna_logger.max_level = (sen_log_level) senna_log_level_options;
+    sen_logger_info_set(&senna_logger);
+  }
+#ifdef MECAB_STATIC
+  char *mecabrc_rpath = "etc/mecabrc";
+  int mecabrc_len = strlen(mysql_home) + strlen(mecabrc_rpath) + 3;
+  char *mecabrc_path = my_malloc(mecabrc_len, MYF(MY_WME));
+  my_snprintf(mecabrc_path, mecabrc_len, "-r%s%s", mysql_home, mecabrc_rpath);
+  char *sen_lex_default_mecab_argv[] = {"", "-Owakati", mecabrc_path};
+  sen_lex_set_mecab_args(3, sen_lex_default_mecab_argv);
+#endif /* MECAB_STATIC */
+#endif /* ENABLE_SENNA */
+  
   select_thread=pthread_self();
   select_thread_in_use=1;
 
@@ -3895,6 +3951,10 @@ we force server id to 2, but this MySQL 
   Service.SetRunning();
 #endif
 
+#ifdef ENABLE_SENNA /* nkjm added below for SFID:10293 2007/04/26 */
+  SEN_LOG(sen_log_notice, "main: mysqld started.");
+#endif /* nkjm added above. */
+
 #if defined(__NT__) || defined(HAVE_SMEM)
   handle_connections_methods();
 #else
@@ -5058,6 +5118,12 @@ enum options_mysqld
   OPT_PLUGIN_DIR,
   OPT_PORT_OPEN_TIMEOUT,
   OPT_MERGE,
+#ifdef ENABLE_SENNA
+  OPT_SENNA_LOG,
+  OPT_SENNA_LOG_LEVEL,
+  OPT_SENNA_2IND,
+  OPT_SENNA_INDEX_TYPE,
+#endif
   OPT_PROFILING,
   OPT_INNODB_ROLLBACK_ON_TIMEOUT,
   OPT_SECURE_FILE_PRIV,
@@ -5749,6 +5815,21 @@ Can't be set to 1 if --log-slave-updates
   {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.",
    (gptr*) &opt_secure_auth, (gptr*) &opt_secure_auth, 0, GET_BOOL, NO_ARG,
    my_bool(0), 0, 0, 0, 0, 0},
+#ifdef ENABLE_SENNA
+  {"senna-2ind", OPT_SENNA_2IND, "Enable Senna 2ind-patch.",
+   (gptr*) &global_system_variables.senna_2ind, 
+   (gptr*) &global_system_variables.senna_2ind, 
+   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"senna-index-type", OPT_SENNA_INDEX_TYPE, "Senna default index type. A value can be NGRAM or MECAB. Default value is NGRAM.",
+   (gptr*) &opt_senna_index_type, (gptr*) &opt_senna_index_type, 0, GET_STR, REQUIRED_ARG,
+   0, 0, 0, 0, 0, 0},
+  {"senna-log", OPT_SENNA_LOG, "Senna log file.",
+   (gptr*) &opt_senna_logname, (gptr*) &opt_senna_logname, 0, GET_STR, OPT_ARG,
+   0, 0, 0, 0, 0, 0},
+  {"senna-log-level", OPT_SENNA_LOG_LEVEL, "Senna log level.",
+   (gptr*) &opt_senna_log_level, (gptr*) &opt_senna_log_level, 0, GET_STR, REQUIRED_ARG,
+   0, 0, 0, 0, 0, 0},
+#endif
   {"secure-file-priv", OPT_SECURE_FILE_PRIV,
    "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory",
    (gptr*) &opt_secure_file_priv, (gptr*) &opt_secure_file_priv, 0,
@@ -6575,6 +6656,9 @@ struct show_var_st status_vars[]= {
   {"Com_show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
   {"Com_show_privileges",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
   {"Com_show_processlist",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
+#ifdef ENABLE_SENNA
+  {"Com_show_senna_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SENNA_STATUS]), SHOW_LONG_STATUS},
+#endif
   {"Com_show_slave_hosts",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
   {"Com_show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
   {"Com_show_status",	       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
@@ -6666,6 +6750,9 @@ struct show_var_st status_vars[]= {
   {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
   {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
   {"Select_scan",	       (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
+#ifdef ENABLE_SENNA
+  {"Senna_2ind_count",         (char*) offsetof(STATUS_VAR, senna_2ind_count), SHOW_LONG_STATUS},
+#endif
   {"Slave_open_temp_tables",   (char*) &slave_open_temp_tables, SHOW_LONG},
   {"Slave_retried_transactions",(char*) 0,                      SHOW_SLAVE_RETRIED_TRANS},
   {"Slave_running",            (char*) 0,                       SHOW_SLAVE_RUNNING},
@@ -7032,6 +7119,14 @@ static void mysql_init_variables(void)
   have_community_features = SHOW_OPTION_NO;
 #endif
 
+#ifdef ENABLE_SENNA
+  senna_index_type_options = 0;
+  senna_default_flags = (SEN_INDEX_NORMALIZE | SEN_INDEX_NGRAM);
+  opt_senna_log = 0;
+  senna_log_level_options = senna_logger.max_level;
+  global_system_variables.senna_2ind = 0;
+#endif
+
 #if defined(__WIN__) || defined(__NETWARE__)
   /* Allow Win32 and NetWare users to move MySQL anywhere */
   {
@@ -7641,6 +7736,44 @@ get_one_option(int optid, const struct m
     lower_case_table_names= argument ? atoi(argument) : 1;
     lower_case_table_names_used= 1;
     break;
+#ifdef ENABLE_SENNA
+  case OPT_SENNA_INDEX_TYPE:
+    int type;
+    if ((type=find_type(argument, &senna_index_type_typelib, 2)) <= 0)
+    {
+      fprintf(stderr, "Unkown senna_index_type type: %s\n",argument);
+      exit(1);
+    }
+    senna_index_type_options= (uint) type-1;
+    if (senna_index_type_options == 1) {
+      senna_default_flags = (SEN_INDEX_NORMALIZE);
+    } else {
+      senna_default_flags = (SEN_INDEX_NORMALIZE | SEN_INDEX_NGRAM);
+    }
+    break;
+  case OPT_SENNA_LOG:
+    opt_senna_log = 1;
+    break;
+  case OPT_SENNA_LOG_LEVEL:
+    if (argument == disabled_my_option)
+      senna_log_level_options= (uint) sen_log_none;
+    else if (! argument)
+      senna_log_level_options= (uint) sen_log_none;
+    else
+    {
+      int type;
+      if ((type=find_type(argument, &senna_log_level_typelib, 2)) <= 0)
+      {
+	fprintf(stderr,"Unknown senna_log_level type: %s\n",argument);
+	exit(1);
+      }
+      senna_log_level_options= (uint) type-1;
+    }
+    break;
+  case OPT_SENNA_2IND:
+    global_system_variables.senna_2ind = 1;
+    break;
+#endif
   }
   return 0;
 }
@@ -8110,3 +8243,45 @@ template class I_List<NAMED_LIST>;
 template class I_List<Statement>;
 template class I_List_iterator<Statement>;
 #endif
+
+#ifdef ENABLE_SENNA
+void senna_logger_func(int level, const char *time, const char *title,
+		       const char *msg, const char *location, void *func_arg)
+{
+  static FILE *fp = NULL;
+  const char slev[] = " EACewnid-";
+  if (!fp)
+  {
+    fp = fopen(senna_logname, "a");
+  }
+
+/* nkjm SFID:10294 */
+#if !defined(__WIN__) && !defined(OS2)
+  struct st_my_thread_var *sen_tmp;
+  extern pthread_key_t THR_KEY_mysys;
+  sen_tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
+  if (fp)
+  {
+    if (sen_tmp)
+    {
+      fprintf(fp, "%s|%c|%u|%s %s %s\n", time, *(slev + level), sen_tmp->sen_connection_id, title, msg, location);
+      fflush(fp);
+    } 
+  }
+#else
+  if (fp) 
+  {
+    fprintf(fp, "%s|%c|%u|%s %s %s\n", time, *(slev + level), (uint)pthread_self(), title, msg, location);
+    fflush(fp);
+  }
+#endif
+/* nkjm SFID:10294 */
+}
+
+sen_logger_info senna_logger = {
+  sen_log_notice,
+  SEN_LOG_TIME|SEN_LOG_MESSAGE,
+  senna_logger_func,
+  NULL
+};
+#endif /* ENABLE_SENNA */
--- orig/sql/records.cc	2009-10-16 06:20:35.000000000 +0900
+++ new/sql/records.cc	2009-11-16 17:45:02.000000000 +0900
@@ -193,6 +193,10 @@ void init_read_record(READ_RECORD *info,
                     table->sort.found_records*info->ref_length;
     info->read_record= (table->sort.addon_field ?
                         rr_unpack_from_buffer : rr_from_pointers);
+#ifdef ENABLE_SENNA
+    if (my_thread_var->sen_flags & SENNA_USE_2IND)
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+#endif /* ENABLE_SENNA */
   }
   else
   {
@@ -357,6 +361,16 @@ static int rr_from_tempfile(READ_RECORD 
   {
     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 & SENNA_USE_2IND) {
+      if ((my_thread_var->sen_flags & 
+	   (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	  == (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+	SEN_LOG(sen_log_debug, "rr_from_tempfile: 2ind return 0");
+	return 0;
+      }
+    }
+#endif /* ENABLE_SENNA */
     if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos)))
       break;
     /* The following is extremely unlikely to happen */
@@ -410,6 +424,16 @@ static int rr_from_pointers(READ_RECORD 
     cache_pos= info->cache_pos;
     info->cache_pos+= info->ref_length;
 
+#ifdef ENABLE_SENNA
+    if (my_thread_var->sen_flags & SENNA_USE_2IND) {
+      if ((my_thread_var->sen_flags &
+	   (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD)) 
+	  == (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+	SEN_LOG(sen_log_debug, "rr_from_pointers: 2ind return 0");
+	return 0;
+      }
+    }
+#endif /* ENABLE_SENNA */
     if (!(tmp=info->file->rnd_pos(info->record,cache_pos)))
       break;
 
--- orig/sql/set_var.cc	2009-10-16 06:20:35.000000000 +0900
+++ new/sql/set_var.cc	2009-11-16 17:45:02.000000000 +0900
@@ -82,6 +82,25 @@ TYPELIB delay_key_write_typelib=
   delay_key_write_type_names, NULL
 };
 
+#ifdef ENABLE_SENNA
+const char *senna_log_level_type_names[] = { "NONE", "EMERG", "ALERT",
+					     "CRIT", "ERROR", "WARNING",
+					     "NOTICE", "INFO", "DEBUG",
+					     "DUMP", NullS };
+TYPELIB senna_log_level_typelib=
+{
+  array_elements(senna_log_level_type_names)-1, "",
+  senna_log_level_type_names, NULL
+};
+
+const char *senna_index_type_type_names[] = { "NGRAM", "MECAB", NullS};
+TYPELIB senna_index_type_typelib=
+{
+  array_elements(senna_index_type_type_names)-1, "",
+  senna_index_type_type_names, NULL
+};
+#endif
+
 static int  sys_check_ftb_syntax(THD *thd,  set_var *var);
 static bool sys_update_ftb_syntax(THD *thd, set_var * var);
 static void sys_default_ftb_syntax(THD *thd, enum_var_type type);
@@ -478,6 +497,15 @@ sys_var_const_os_str_ptr sys_innodb_log_
                                                        &innobase_log_group_home_dir);
 #endif
 
+#ifdef ENABLE_SENNA
+sys_var_enum            sys_senna_index_type("senna_index_type",&senna_index_type_options,
+					     &senna_index_type_typelib, fix_senna_index_type);
+sys_var_bool_ptr        sys_senna_log("senna_log", &opt_senna_log);
+sys_var_enum            sys_senna_log_level("senna_log_level",&senna_log_level_options,
+					    &senna_log_level_typelib, fix_senna_log_level);
+sys_var_thd_bool        sys_senna_2ind("senna_2ind", &SV::senna_2ind, fix_senna_2ind);
+#endif
+
 /* Condition pushdown to storage engine */
 sys_var_thd_bool
 sys_engine_condition_pushdown("engine_condition_pushdown",
@@ -765,6 +793,11 @@ sys_var *sys_variables[]=
   &sys_secure_auth,
   &sys_secure_file_priv,
   &sys_select_limit,
+#ifdef ENABLE_SENNA
+  &sys_senna_2ind,
+  &sys_senna_index_type,
+  &sys_senna_log_level,
+#endif
   &sys_server_id,
 #ifdef HAVE_REPLICATION
   &sys_slave_compressed_protocol,
@@ -1092,6 +1125,12 @@ struct show_var_st init_vars[]= {
   {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank,       SHOW_SYS},
   {"secure_auth",             (char*) &sys_secure_auth,             SHOW_SYS},
   {"secure_file_priv",        (char*) &sys_secure_file_priv,        SHOW_SYS},
+#ifdef ENABLE_SENNA
+  {"senna_2ind",              (char*) &sys_senna_2ind,              SHOW_SYS},
+  {"senna_index_type",        (char*) &sys_senna_index_type,        SHOW_SYS},
+  {"senna_log",               (char*) &opt_senna_log,               SHOW_MY_BOOL},
+  {"senna_log_level",         (char*) &sys_senna_log_level,         SHOW_SYS},
+#endif
 #ifdef HAVE_SMEM
   {"shared_memory",           (char*) &opt_enable_shared_memory,    SHOW_MY_BOOL},
   {"shared_memory_base_name", (char*) &shared_memory_base_name,     SHOW_CHAR_PTR},
@@ -1414,6 +1453,33 @@ extern void fix_delay_key_write(THD *thd
   }
 }
 
+#ifdef ENABLE_SENNA
+extern void fix_senna_index_type(THD *thd, enum_var_type type)
+{
+  DBUG_ENTER("fix_senna_index_type");
+  if (senna_index_type_options == 0) {
+    senna_default_flags = (SEN_INDEX_NORMALIZE | SEN_INDEX_NGRAM);
+  } else {
+    senna_default_flags = (SEN_INDEX_NORMALIZE);
+  }
+  DBUG_VOID_RETURN;
+}
+
+extern void fix_senna_log_level(THD *thd, enum_var_type type)
+{
+  DBUG_ENTER("fix_senna_log_level");
+  senna_logger.max_level = (sen_log_level) senna_log_level_options;
+  DBUG_VOID_RETURN;
+}
+
+extern void fix_senna_2ind(THD *thd, enum_var_type type)
+{
+  DBUG_ENTER("fix_senna_2ind");
+  DEBUG_2IND(my_thread_var->sen_flags = (thd->variables.senna_2ind ? SENNA_USE_2IND : 0));
+  DBUG_VOID_RETURN;
+}
+#endif
+
 static void fix_max_binlog_size(THD *thd, enum_var_type type)
 {
   DBUG_ENTER("fix_max_binlog_size");
--- orig/sql/set_var.h	2009-10-16 06:20:35.000000000 +0900
+++ new/sql/set_var.h	2009-11-16 17:45:02.000000000 +0900
@@ -31,6 +31,12 @@ typedef struct my_locale_st MY_LOCALE;
 
 extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
 
+#ifdef ENABLE_SENNA
+extern TYPELIB senna_log_level_typelib;
+extern TYPELIB senna_index_type_typelib;
+extern int senna_default_flags;
+#endif
+
 typedef int (*sys_check_func)(THD *,  set_var *);
 typedef bool (*sys_update_func)(THD *, set_var *);
 typedef void (*sys_after_update_func)(THD *,enum_var_type);
@@ -1101,6 +1107,11 @@ extern sys_var_thd_bit sys_autocommit;
 CHARSET_INFO *get_old_charset_by_name(const char *old_name);
 gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
 		NAMED_LIST **found);
+#ifdef ENABLE_SENNA
+void fix_senna_log_level(THD *thd, enum_var_type type);
+void fix_senna_2ind(THD *thd, enum_var_type type);
+void fix_senna_index_type(THD *thd, enum_var_type type);
+#endif
 
 /* key_cache functions */
 KEY_CACHE *get_key_cache(LEX_STRING *cache_name);
--- orig/sql/sp_head.cc	2009-10-16 06:20:36.000000000 +0900
+++ new/sql/sp_head.cc	2009-11-16 17:45:02.000000000 +0900
@@ -193,6 +193,9 @@ sp_get_flags_for_command(LEX *lex)
   case SQLCOM_SHOW_OPEN_TABLES:
   case SQLCOM_SHOW_PRIVILEGES:
   case SQLCOM_SHOW_PROCESSLIST:
+#ifdef ENABLE_SENNA
+  case SQLCOM_SHOW_SENNA_STATUS:
+#endif
   case SQLCOM_SHOW_SLAVE_HOSTS:
   case SQLCOM_SHOW_SLAVE_STAT:
   case SQLCOM_SHOW_STATUS:
--- orig/sql/sql_class.h	2009-10-16 06:20:36.000000000 +0900
+++ new/sql/sql_class.h	2009-11-16 17:45:02.000000000 +0900
@@ -436,11 +436,22 @@ public:
   List<key_part_spec> columns;
   const char *name;
   bool generated;
+#ifdef ENABLE_SENNA
+  int senna_flags;
+  int senna_initial_n_segments;
+#endif /* ENABLE_SENNA */
 
+#ifdef ENABLE_SENNA
+  Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par,
+      bool generated_arg, List<key_part_spec> &cols, int sen_flags=1, int sen_nsegs=0)
+    :type(type_par), algorithm(alg_par), columns(cols), name(name_arg),
+    generated(generated_arg), senna_flags(sen_flags), senna_initial_n_segments(sen_nsegs)
+#else /* ENABLE_SENNA */
   Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par,
       bool generated_arg, List<key_part_spec> &cols)
     :type(type_par), algorithm(alg_par), columns(cols), name(name_arg),
     generated(generated_arg)
+#endif /* ENABLE_SENNA */
   {}
   ~Key() {}
   /* Equality comparison of keys (ignoring name) */
@@ -614,6 +625,10 @@ struct system_variables
   DATE_TIME_FORMAT *datetime_format;
   DATE_TIME_FORMAT *time_format;
   my_bool sysdate_is_now;
+
+#ifdef ENABLE_SENNA
+  my_bool senna_2ind;
+#endif
 };
 
 
@@ -685,6 +700,9 @@ typedef struct system_status_var
     sense to add to the /global/ status variable counter.
   */
   double last_query_cost;
+#ifdef ENABLE_SENNA
+  ulong senna_2ind_count;
+#endif
 } STATUS_VAR;
 
 /*
--- orig/sql/sql_db.cc	2009-10-16 06:20:36.000000000 +0900
+++ new/sql/sql_db.cc	2009-11-16 17:45:02.000000000 +0900
@@ -874,6 +874,11 @@ static long mysql_rm_known_files(THD *th
        (file->name[1] == '.' &&  !file->name[2])))
       continue;
 
+#ifdef ENABLE_SENNA
+    /* senna files is skip */
+    /* ".SEN",".SEN.i",".SEN.i.c",".SEN.l", ".SEN.i.c.001",.. and so on */
+    if (strstr(file->name, ".SEN")) { continue; }
+#endif /* ENABLE_SENNA */
     /* Check if file is a raid directory */
     if ((my_isdigit(system_charset_info, file->name[0]) ||
 	 (file->name[0] >= 'a' && file->name[0] <= 'f')) &&
--- orig/sql/sql_delete.cc	2009-10-16 06:20:36.000000000 +0900
+++ new/sql/sql_delete.cc	2009-11-16 17:45:02.000000000 +0900
@@ -939,6 +939,9 @@ bool mysql_truncate(THD *thd, TABLE_LIST
     if (thd->slave_thread)
       --slave_open_temp_tables;
     *fn_ext(path)=0;				// Remove the .frm extension
+#ifdef ENABLE_SENNA
+    create_info.key_info=table->key_info;
+#endif /* ENABLE_SENNA */
     ha_create_table(path, &create_info,1);
     // We don't need to call invalidate() because this table is not in cache
     if ((error= (int) !(open_temporary_table(thd, path, table_list->db,
@@ -971,6 +974,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST
       DBUG_RETURN(TRUE);
   }
 
+#ifdef ENABLE_SENNA
+  create_info.query_type = SENNA_TRUNCATE_TABLE;
+#endif
+
   *fn_ext(path)=0;				// Remove the .frm extension
   error= ha_create_table(path,&create_info,1);
   query_cache_invalidate3(thd, table_list, 0);
--- orig/sql/sql_insert.cc	2009-10-16 06:20:36.000000000 +0900
+++ new/sql/sql_insert.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1867,6 +1867,9 @@ bool delayed_get_table(THD *thd, TABLE_L
       di->table_list.alias= di->table_list.table_name= di->thd.query;
       di->table_list.db= di->thd.db;
       di->lock();
+#ifdef ENABLE_SENNA
+      di->thd.thread_id= thd->thread_id;
+#endif
       pthread_mutex_lock(&di->mutex);
       if ((error= pthread_create(&di->thd.real_id, &connection_attrib,
                                  handle_delayed_insert, (void*) di)))
@@ -2204,6 +2207,9 @@ pthread_handler_t handle_delayed_insert(
 {
   Delayed_insert *di=(Delayed_insert*) arg;
   THD *thd= &di->thd;
+#ifdef ENABLE_SENNA
+  uint sen_thread_id = thd->thread_id;
+#endif
 
   pthread_detach_this_thread();
   /* Add thread to THD list so that's it's visible in 'show processlist' */
@@ -2229,6 +2235,12 @@ pthread_handler_t handle_delayed_insert(
     strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
     goto end;
   }
+#ifdef ENABLE_SENNA /* nkjm SFID:10294 */
+  struct st_my_thread_var *sen_tmp;
+  extern pthread_key_t THR_KEY_mysys;
+  sen_tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
+  sen_tmp->sen_connection_id= sen_thread_id;
+#endif /* nkjm SFID:10294 */
 #endif
 
   DBUG_ENTER("handle_delayed_insert");
--- orig/sql/sql_lex.h	2009-10-16 06:20:37.000000000 +0900
+++ new/sql/sql_lex.h	2009-11-16 17:45:02.000000000 +0900
@@ -44,6 +44,10 @@ class sp_pcontext;
 #endif
 #endif
 
+#ifdef ENABLE_SENNA
+#include "senna.h"
+#endif
+
 /*
   When a command is added here, be sure it's also added in mysqld.cc
   in "struct show_var_st status_vars[]= {" ...
@@ -95,6 +99,9 @@ enum enum_sql_command {
   SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
   SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
   SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
+#ifdef ENABLE_SENNA
+  SQLCOM_SHOW_SENNA_STATUS,
+#endif
 
   /*
     When a command is added here, be sure it's also added in mysqld.cc
@@ -1200,6 +1207,15 @@ typedef struct st_lex : public Query_tab
   */
   bool protect_against_global_read_lock;
 
+#ifdef ENABLE_SENNA
+  int senna_flags;
+  int senna_initial_n_segments;
+  inline void senna_clear() {
+    senna_flags= senna_default_flags;
+    senna_initial_n_segments=0;
+  }
+#endif /* ENABLE_SENNA */
+
   st_lex();
 
   virtual ~st_lex()
--- orig/sql/sql_parse.cc	2009-10-16 06:20:37.000000000 +0900
+++ new/sql/sql_parse.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1142,6 +1142,12 @@ pthread_handler_t handle_one_connection(
     end_thread(thd,0);
     return 0;
   }
+#ifdef ENABLE_SENNA /* nkjm SFID:10294 */
+  struct st_my_thread_var *sen_tmp;
+  extern pthread_key_t THR_KEY_mysys;
+  sen_tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
+  sen_tmp->sen_connection_id= thd->thread_id;
+#endif /* nkjm SFID:10294 */
 #endif
 
   /*
@@ -1221,6 +1227,9 @@ pthread_handler_t handle_one_connection(
       thd_proc_info(thd, 0);
       thd->init_for_queries();
     }
+#ifdef ENABLE_SENNA
+    DEBUG_2IND(my_thread_var->sen_flags = (thd->variables.senna_2ind ? SENNA_USE_2IND : 0));
+#endif
 
     /* Connect completed, set read/write timeouts back to tdefault */
     my_net_set_read_timeout(net, thd->variables.net_read_timeout);
@@ -3144,6 +3153,13 @@ mysql_execute_command(THD *thd)
       break;
     }
 #endif
+#ifdef ENABLE_SENNA
+  case SQLCOM_SHOW_SENNA_STATUS:
+  {
+    res = senna_show_status(thd, lex);
+    break;
+  }
+#endif
 #ifdef HAVE_REPLICATION
   case SQLCOM_LOAD_MASTER_TABLE:
   {
--- orig/sql/sql_select.cc	2009-10-16 06:20:37.000000000 +0900
+++ new/sql/sql_select.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1479,6 +1479,11 @@ JOIN::optimize()
       DBUG_RETURN(-1);                         /* purecov: inspected */
   }
 
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND)
+    DEBUG_2IND(my_thread_var->sen_flags |= SENNA_FIRST_CALL);
+#endif /* ENABLE_SENNA */
+
   error= 0;
   DBUG_RETURN(0);
 }
@@ -2101,6 +2106,11 @@ JOIN::exec()
   curr_join->fields= curr_fields_list;
   curr_join->procedure= procedure;
 
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND)
+    DEBUG_2IND(my_thread_var->sen_flags &= ~SENNA_FIRST_CALL);
+#endif /* ENABLE_SENNA */
+
   if (is_top_level_join() && thd->cursor && tables != const_tables)
   {
     /*
@@ -2301,7 +2311,16 @@ mysql_select(THD *thd, Item ***rref_poin
       goto err;
     }
   }
-
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND) {
+    if (select_lex->ftfunc_list->elements) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_MATCH);
+    }
+    if (join->select_distinct) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DISTINCT);
+    }
+  }
+#endif /* ENABLE_SENNA */
   if ((err= join->optimize()))
   {
     goto err;					// 1
@@ -2335,6 +2354,9 @@ mysql_select(THD *thd, Item ***rref_poin
   }
 
 err:
+#ifdef ENABLE_SENNA
+  DEBUG_2IND(my_thread_var->sen_flags &= SENNA_USE_2IND);
+#endif
   if (free_join)
   {
     thd_proc_info(thd, "end");
@@ -3730,7 +3752,11 @@ update_ref_and_keys(THD *thd, DYNAMIC_AR
       return TRUE;
   }
 
-  if (select_lex->ftfunc_list->elements)
+  if (select_lex->ftfunc_list->elements
+#ifdef ENABLE_SENNA
+      && !join_tab->table->force_index
+#endif /* ENABLE_SENNA */
+      )
   {
     if (add_ft_keys(keyuse,join_tab,cond,normal_tables))
       return TRUE;
@@ -6254,6 +6280,10 @@ make_join_readinfo(JOIN *join, ulonglong
       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
+      if (my_thread_var->sen_flags & SENNA_USE_2IND) 
+	DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+#endif /* ENABLE_SENNA */
       break;
     case JT_ALL:
       /*
@@ -10589,6 +10619,21 @@ do_select(JOIN *join,List<Item> *fields,
   DBUG_RETURN(join->thd->net.report_error ? -1 : rc);
 }
 
+#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 & (SENNA_DISTINCT | SENNA_FIRST_CALL)) ||
+      (((*join->sum_funcs && (*join->sum_funcs)->sum_func() != Item_sum::COUNT_FUNC) ||
+	join_tab->next_select != end_send_group)
+       && !join->unit->offset_limit_cnt &&
+       join->send_records < join->unit->select_limit_cnt)) {
+    DEBUG_2IND(my_thread_var->sen_flags |= SENNA_IF_READ_RECORD);
+  } else {
+    DEBUG_2IND(my_thread_var->sen_flags &= ~SENNA_IF_READ_RECORD);
+  }
+}
+#endif /* ENABLE_SENNA */
 
 enum_nested_loop_state
 sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
@@ -10734,6 +10779,11 @@ sub_select_cache(JOIN *join,JOIN_TAB *jo
 enum_nested_loop_state
 sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
 {
+#ifdef ENABLE_SENNA
+  if ((my_thread_var->sen_flags & SENNA_USE_2IND) && (join_tab->next_select == end_update)) {
+    DEBUG_2IND(my_thread_var->sen_flags &= ~SENNA_DO_READ_RECORD);
+  }
+#endif /* ENABLE_SENNA */
   join_tab->table->null_row=0;
   if (end_of_records)
     return (*join_tab->next_select)(join,join_tab+1,end_of_records);
@@ -10742,6 +10792,10 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
   enum_nested_loop_state rc;
   my_bool *report_error= &(join->thd->net.report_error);
   READ_RECORD *info= &join_tab->read_record;
+#ifdef ENABLE_SENNA
+  COND *select_cond = join_tab->select_cond;
+  bool needs_record = select_cond ? select_cond->needs_record() : false;
+#endif /* ENABLE_SENNA */
 
   if (join->resume_nested_loop)
   {
@@ -10771,12 +10825,20 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
     }
     join->thd->row_count= 0;
 
+#ifdef ENABLE_SENNA
+    if (my_thread_var->sen_flags & SENNA_USE_2IND)
+      decide_read_or_skip(join, join_tab, needs_record);
+#endif /* ENABLE_SENNA */
     error= (*join_tab->read_first_record)(join_tab);
     rc= evaluate_join_record(join, join_tab, error, report_error);
   }
 
   while (rc == NESTED_LOOP_OK)
   {
+#ifdef ENABLE_SENNA
+    if (my_thread_var->sen_flags & SENNA_USE_2IND)
+      decide_read_or_skip(join, join_tab, needs_record);
+#endif /* ENABLE_SENNA */
     error= info->read_record(info);
     rc= evaluate_join_record(join, join_tab, error, report_error);
   }
@@ -11458,7 +11520,22 @@ join_read_first(JOIN_TAB *tab)
   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 & SENNA_USE_2IND) {
+    if (my_thread_var->sen_flags & SENNA_MATCH) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+    }
+    if ((my_thread_var->sen_flags & 
+	 (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	== (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+      //error=tab->table->file->index_first(NULL);
+      //statistic_increment(tab->table->in_use->status_var.senna_2ind_count, &LOCK_status);
+      return 0;
+    }
+  }
+#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);
@@ -11472,7 +11549,19 @@ static int
 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 & SENNA_USE_2IND) {
+    if ((my_thread_var->sen_flags & 
+	 (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	== (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+      //error=info->file->index_next(NULL);
+      //statistic_increment(info->thd->status_var.senna_2ind_count, &LOCK_status);
+      return 0;
+    }
+  }
+#endif /* ENABLE_SENNA */
+    error=info->file->index_next(info->record);
+  if (error)
     return report_error(info->table, error);
   return 0;
 }
@@ -11497,7 +11586,22 @@ join_read_last(JOIN_TAB *tab)
   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 & SENNA_USE_2IND) {
+    if (my_thread_var->sen_flags & SENNA_MATCH) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+    }
+    if ((my_thread_var->sen_flags & 
+	 (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	== (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+      //error=tab->table->file->index_last(NULL);
+      //statistic_increment(tab->table->in_use->status_var.senna_2ind_count, &LOCK_status);
+      return 0;
+    }
+  }
+#endif /* ENABLE_SENNA */
+    error=tab->table->file->index_last(tab->table->record[0]);
+  if (error)
     return report_error(table, error);
   return 0;
 }
@@ -11507,7 +11611,19 @@ static int
 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 & SENNA_USE_2IND) {
+    if ((my_thread_var->sen_flags & 
+	 (SENNA_MATCH | SENNA_DO_READ_RECORD | SENNA_IF_READ_RECORD))
+	== (SENNA_MATCH | SENNA_DO_READ_RECORD)) {
+      //error=info->file->index_prev(NULL);
+      //statistic_increment(info->thd->status_var.senna_2ind_count, &LOCK_status);
+      return 0;
+    }
+  } 
+#endif /* ENABLE_SENNA */
+    error=info->file->index_prev(info->record);
+  if (error)
     return report_error(info->table, error);
   return 0;
 }
@@ -11521,6 +11637,12 @@ join_ft_read_first(JOIN_TAB *tab)
 
   if (!table->file->inited)
     table->file->ha_index_init(tab->ref.key);
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND)
+    if (my_thread_var->sen_flags & SENNA_MATCH) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_DO_READ_RECORD);
+    }
+#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()
@@ -12833,6 +12955,14 @@ create_sort_index(THD *thd, JOIN *join, 
   table=  tab->table;
   select= tab->select;
 
+#ifdef ENABLE_SENNA
+  if (my_thread_var->sen_flags & SENNA_USE_2IND) {
+    if (tab->select_cond && tab->select_cond->needs_record()) {
+      DEBUG_2IND(my_thread_var->sen_flags |= SENNA_IF_READ_RECORD);
+    }
+  }
+#endif /* ENABLE_SENNA */
+
   /*
     When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
     and thus force sorting on disk unless a group min-max optimization
--- orig/sql/sql_show.cc	2009-10-16 06:20:37.000000000 +0900
+++ new/sql/sql_show.cc	2009-11-16 17:45:02.000000000 +0900
@@ -28,6 +28,13 @@
 #include "ha_berkeley.h"			// For berkeley_show_logs
 #endif
 
+#ifdef ENABLE_SENNA
+#define SECTIONALIZE  0x00080000
+#ifdef HAVE_ISAM
+#include "ha_myisam.h"                 // For isam
+#endif
+#endif /* ENABLE_SENNA */
+
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
 static const char *grant_names[]={
   "select","insert","update","delete","create","drop","reload","shutdown",
@@ -1021,6 +1028,45 @@ store_create_info(THD *thd, TABLE_LIST *
 	  !(key_info->flags & HA_SPATIAL))
         packet->append(STRING_WITH_LEN(" USING RTREE"));
 
+#ifdef ENABLE_SENNA
+      {
+	char ins[32];
+	char *insp;
+	int inslen;
+	if (key_info->is_senna)
+	{
+	  if (key_info->senna_flags & SEN_INDEX_NGRAM)
+	    packet->append(STRING_WITH_LEN(" USING NGRAM"));
+	  else if (key_info->senna_flags & SEN_INDEX_DELIMITED)
+	    packet->append(STRING_WITH_LEN(" USING DELIMITED"));
+	  else
+	    packet->append(STRING_WITH_LEN(" USING MECAB"));
+
+	  if (key_info->senna_flags & SEN_INDEX_NORMALIZE)
+	    packet->append(STRING_WITH_LEN(", NORMALIZE"));
+	  else
+	    packet->append(STRING_WITH_LEN(", NO NORMALIZE"));
+
+	  if (key_info->senna_flags & SECTIONALIZE)
+	    packet->append(STRING_WITH_LEN(", SECTIONALIZE"));
+
+	  if (key_info->senna_flags & SEN_INDEX_SPLIT_ALPHA)
+	    packet->append(STRING_WITH_LEN(", SPLIT_ALPHA"));
+	  if (key_info->senna_flags & SEN_INDEX_SPLIT_DIGIT)
+	    packet->append(STRING_WITH_LEN(", SPLIT_DIGIT"));
+	  if (key_info->senna_flags & SEN_INDEX_SPLIT_SYMBOL)
+	    packet->append(STRING_WITH_LEN(", SPLIT_SYMBOL"));
+
+	/* TODO: initial_n_segments support */
+	  my_snprintf(ins, sizeof(ins), ", %d",key_info->senna_initial_n_segments);
+	  inslen = strlen(ins);
+	  insp = sql_alloc(inslen);
+	  memcpy(insp, ins, inslen);
+	  packet->append(insp, inslen);
+        }
+      }
+#endif
+
       // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY
     }
     packet->append(STRING_WITH_LEN(" ("));
@@ -1930,6 +1976,9 @@ void get_index_field_values(LEX *lex, IN
   case SQLCOM_SHOW_TABLES:
   case SQLCOM_SHOW_TABLE_STATUS:
   case SQLCOM_SHOW_TRIGGERS:
+#ifdef ENABLE_SENNA
+  case SQLCOM_SHOW_SENNA_STATUS: 
+#endif
     index_field_values->db_value= lex->select_lex.db;
     index_field_values->table_value= wild;
     break;
@@ -4505,3 +4554,120 @@ ST_SCHEMA_TABLE schema_tables[]=
 template class List_iterator_fast<char>;
 template class List<char>;
 #endif
+
+#ifdef ENABLE_SENNA
+bool senna_show_status(THD *thd, LEX *lex)
+{
+  List<char> files;
+  List<Item> field_list;  
+  char path[FN_LEN];
+  char *file_name;
+  DBUG_ENTER("senna_show_status");
+  Protocol* protocol = thd->protocol;
+  char *db = lex->select_lex.db ? lex->select_lex.db : thd->db;
+  if (!db) {
+    my_error(ER_NO_DB_ERROR, MYF(0));
+    DBUG_RETURN(TRUE);
+  }
+
+  const char *wild = lex->wild ? lex->wild->ptr() : "%";
+  
+  (void) my_snprintf(path, FN_LEN, "%s/%s", mysql_data_home, db);
+  (void) unpack_dirname(path, path);
+  
+  field_list.push_back(new Item_empty_string("Table", 20));
+  field_list.push_back(new Item_empty_string("Key_name", 20));
+  field_list.push_back(new Item_empty_string("Column_name", 20));
+  field_list.push_back(new Item_empty_string("Encoding", 20));
+  field_list.push_back(new Item_empty_string("Index_type", 20));
+  field_list.push_back(new Item_empty_string("Sectionalize", 20));
+  field_list.push_back(new Item_empty_string("Normalize", 20));
+  field_list.push_back(new Item_empty_string("Split_alpha", 20));
+  field_list.push_back(new Item_empty_string("Split_digit", 20));
+  field_list.push_back(new Item_empty_string("Split_symbol", 20));
+  field_list.push_back(new Item_int("Initial_n_segments", 20));
+  field_list.push_back(new Item_int("Senna_keys_size", 20));
+  field_list.push_back(new Item_int("Senna_keys_file_size", 20));
+  field_list.push_back(new Item_int("Senna_lexicon_size", 20));
+  field_list.push_back(new Item_int("Senna_lexicon_file_size", 20));
+  field_list.push_back(new Item_int("Senna_inv_seg_size", 20));
+  field_list.push_back(new Item_int("Senna_inv_chunk_size", 20));
+  if (protocol->send_fields(&field_list,
+			    Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+    DBUG_RETURN(TRUE);
+  
+  if (find_files(thd, &files, db, path, wild, 0))
+    DBUG_RETURN(-1);
+  List_iterator_fast<char> it(files);
+  while (file_name = it++)
+  {
+    TABLE tmp_table;
+    TABLE_LIST table_list;
+
+    /* to skip views */
+    (void) my_snprintf(path, FN_LEN, "%s/%s", db, file_name);
+    openfrm(thd, path, "", 0, SENNA_CHECK_VIEW, 0, &tmp_table);
+    if(!(tmp_table.file)) continue;
+    closefrm(&tmp_table);
+
+    bzero((char*) &table_list, sizeof(table_list));
+    table_list.db = db;
+    table_list.table_name = file_name;
+    table_list.alias = file_name;
+    TABLE *table = open_ltable(thd, &table_list, TL_READ);
+    if (!strcmp(table->file->table_type(), "MyISAM"))
+    {
+      uint nkeys = table->s->keys;
+      int i = 0;
+      table->file->info(HA_STATUS_VARIABLE | HA_STATUS_SENNA);
+      for (; i < nkeys; i++)
+      {
+	const char* tkey;
+	KEY *key = &table->key_info[i];
+	
+        if (key->algorithm == HA_KEY_ALG_FULLTEXT
+	    &&!(key->senna_flags & SEN_DISABLE_SENNA))
+	{
+	  uint nkey_parts = key->key_parts;
+	  int j = 0;
+	  for (; j < nkey_parts; j++)
+	  {
+	    KEY_PART_INFO *key_part = &key->key_part[j];
+	    uint16 fieldnr = key_part->fieldnr;
+	    Field *field = table->field[fieldnr-1];
+	    const char *field_name = field->field_name;
+	    
+	    protocol->prepare_for_resend();
+	    protocol->store(key->table->s->table_name, system_charset_info);
+	    protocol->store(key->name, system_charset_info);
+	    protocol->store(field_name, system_charset_info);
+	    protocol->store(key->senna_encoding, system_charset_info);
+	    if (key->senna_flags & SEN_INDEX_NGRAM)
+	      protocol->store("NGRAM", system_charset_info); 
+	    else if (key->senna_flags & SEN_INDEX_DELIMITED)
+	      protocol->store("DELIMITED", system_charset_info);
+	    else
+	      protocol->store("MECAB", system_charset_info);
+	    protocol->store(key->senna_flags & SECTIONALIZE ? "ON" : "OFF", system_charset_info);
+	    protocol->store(key->senna_flags & SEN_INDEX_NORMALIZE ? "ON" : "OFF", system_charset_info);
+	    protocol->store(key->senna_flags & SEN_INDEX_SPLIT_ALPHA ? "ON" : "OFF", system_charset_info);
+	    protocol->store(key->senna_flags & SEN_INDEX_SPLIT_DIGIT ? "ON" : "OFF", system_charset_info);
+	    protocol->store(key->senna_flags & SEN_INDEX_SPLIT_SYMBOL ? "ON" : "OFF", system_charset_info);
+	    protocol->store((longlong) key->senna_initial_n_segments);
+	    protocol->store((longlong) key->senna_keys_size);
+	    protocol->store((longlong) key->senna_keys_file_size);
+	    protocol->store((longlong) key->senna_lexicon_size);
+	    protocol->store((longlong) key->senna_lexicon_file_size);
+	    protocol->store((longlong) key->senna_inv_seg_size);
+	    protocol->store((longlong) key->senna_inv_chunk_size);
+	    if (protocol->write()) DBUG_RETURN(TRUE);
+	  }
+	}
+      }
+    }
+    close_thread_tables(thd, 0);
+  }
+  send_eof(thd);
+  DBUG_RETURN(TRUE);
+}
+#endif
--- orig/sql/sql_table.cc	2009-10-16 06:20:37.000000000 +0900
+++ new/sql/sql_table.cc	2009-11-16 17:45:02.000000000 +0900
@@ -1129,6 +1129,9 @@ static int mysql_prepare_table(THD *thd,
   if (!*key_info_buffer || ! key_part_info)
     DBUG_RETURN(-1);				// Out of memory
 
+#ifdef ENABLE_SENNA
+  create_info->key_info=*key_info_buffer;
+#endif /* ENABLE_SENNA */
   key_iterator.rewind();
   key_number=0;
   for (; (key=key_iterator++) ; key_number++)
@@ -1172,6 +1175,10 @@ static int mysql_prepare_table(THD *thd,
     if (key->generated)
       key_info->flags|= HA_GENERATED_KEY;
 
+#ifdef ENABLE_SENNA
+    key_info->senna_flags=key->senna_flags;
+    key_info->senna_initial_n_segments=key->senna_initial_n_segments;
+#endif /* ENABLE_SENNA */
     key_info->key_parts=(uint8) key->columns.elements;
     key_info->key_part=key_part_info;
     key_info->usable_key_parts= key_number;
@@ -1271,6 +1278,9 @@ static int mysql_prepare_table(THD *thd,
 	    DBUG_RETURN(-1);
 	}
 	ft_key_charset=sql_field->charset;
+#ifdef ENABLE_SENNA
+	key_info->senna_encoding=ft_key_charset->csname;
+#endif
 	/*
 	  for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
 	  code anyway, and 0 (set to column width later) for char's. it has
@@ -2834,6 +2844,10 @@ bool mysql_create_like_table(THD* thd, T
 
   DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
 
+#ifdef ENABLE_SENNA
+  create_info->query_type = SENNA_CREATE_TABLE_LIKE;
+#endif
+
   /*
     Validate the destination table
 
@@ -3199,6 +3213,10 @@ view_err:
   if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
     DBUG_RETURN(TRUE);
 
+#ifdef ENABLE_SENNA
+  table->file->info(HA_STATUS_VARIABLE | HA_STATUS_SENNA);
+#endif
+
   /* Check that we are not trying to rename to an existing table */
   if (new_name)
   {
@@ -3646,10 +3664,19 @@ view_err:
       else
         key_type= Key::MULTIPLE;
 
+#ifdef ENABLE_SENNA
+      key= new Key(key_type, key_name,
+		   key_info->algorithm,
+		   test(key_info->flags & HA_GENERATED_KEY),
+		   key_parts,
+		   key_info->senna_flags,
+		   key_info->senna_initial_n_segments);
+#else /* ENABLE_SENNA */
       key= new Key(key_type, key_name,
                    key_info->algorithm,
                    test(key_info->flags & HA_GENERATED_KEY),
                    key_parts);
+#endif /* ENABLE_SENNA */
       new_info.key_list.push_back(key);
     }
   }
--- orig/sql/sql_yacc.yy	2009-10-16 06:20:38.000000000 +0900
+++ new/sql/sql_yacc.yy	2009-11-16 19:08:12.000000000 +0900
@@ -465,10 +465,10 @@ bool my_yyoverflow(short **a, YYSTYPE **
 
 %pure_parser					/* We have threads */
 /*
-  Currently there are 240 shift/reduce conflicts.
+  Currently there are 241 shift/reduce conflicts.
   We should not introduce new conflicts any more.
 */
-%expect 240
+%expect 241
 
 %token  END_OF_INPUT
 
@@ -899,6 +899,16 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  SECOND_SYM
 %token  SECURITY_SYM
 %token  SELECT_SYM
+%token  SENNA_DELIMITED_SYM
+%token  SENNA_KWIC_SYM
+%token  SENNA_MECAB_SYM
+%token  SENNA_NGRAM_SYM
+%token  SENNA_NORMALIZE_SYM
+%token  SENNA_SECTIONALIZE_SYM
+%token  SENNA_SPLIT_ALPHA_SYM
+%token  SENNA_SPLIT_DIGIT_SYM
+%token  SENNA_SPLIT_SYMBOL_SYM
+%token  SENNA_SYM
 %token  SENSITIVE_SYM
 %token  SEPARATOR_SYM
 %token  SERIALIZABLE_SYM
@@ -1205,7 +1215,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 	view_suid view_tail view_list_opt view_list view_select
 	view_check_option trigger_tail sp_tail sf_tail udf_tail
         case_stmt_specification simple_case_stmt searched_case_stmt
-        definer_opt no_definer definer
+        definer_opt no_definer definer opt_senna_list opt_senna_item
 END_OF_INPUT
 
 %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -1534,6 +1544,9 @@ create:
 						 TL_WRITE))
 	    MYSQL_YYABORT;
           lex->alter_info.reset();
+#ifdef ENABLE_SENNA
+	  lex->senna_clear();
+#endif
 	  lex->col_list.empty();
 	  lex->change=NullS;
 	  bzero((char*) &lex->create_info,sizeof(lex->create_info));
@@ -1558,11 +1571,21 @@ create:
 	   '(' key_list ')'
 	  {
 	    LEX *lex=Lex;
+#ifdef ENABLE_SENNA
+            Key *key= new Key($2,$4.str, $5, 0, lex->col_list,
+                              lex->senna_flags, lex->senna_initial_n_segments);
+            if (key == NULL)
+              MYSQL_YYABORT;
+
+            lex->alter_info.key_list.push_back(key);
+            lex->senna_clear();
+#else /* ENABLE_SENNA */
             Key *key= new Key($2, $4.str, $5, 0, lex->col_list);
             if (key == NULL)
               MYSQL_YYABORT;
 
             lex->alter_info.key_list.push_back(key);
+#endif /* ENABLE_SENNA */
 	    lex->col_list.empty();
 	  }
 	| CREATE DATABASE opt_if_not_exists ident
@@ -3126,6 +3149,9 @@ column_def:
 	  field_spec opt_check_constraint
 	| field_spec references
 	  {
+#ifdef ENABLE_SENNA
+            Lex->senna_clear();
+#endif /* ENABLE_SENNA */
 	    Lex->col_list.empty();		/* Alloced by sql_alloc */
 	  }
 	;
@@ -3134,10 +3160,19 @@ key_def:
 	key_type opt_ident key_alg '(' key_list ')' key_alg
 	  {
 	    LEX *lex=Lex;
+#ifdef ENABLE_SENNA
+            Key *key= new Key($1, $2, $7 ? $7 : $3, 0, lex->col_list,
+                              lex->senna_flags, lex->senna_initial_n_segments);
+            if (key == NULL)
+              MYSQL_YYABORT;
+            lex->alter_info.key_list.push_back(key);
+            lex->senna_clear();
+#else /* ENABLE_SENNA */
             Key *key= new Key($1, $2, $7 ? $7 : $3, 0, lex->col_list);
             if (key == NULL)
               MYSQL_YYABORT;
             lex->alter_info.key_list.push_back(key);
+#endif /* ENABLE_SENNA */
 
 	    lex->col_list.empty();		/* Alloced by sql_alloc */
 	  }
@@ -3170,14 +3205,23 @@ key_def:
             if (key == NULL)
               MYSQL_YYABORT;
             lex->alter_info.key_list.push_back(key);
+#ifdef ENABLE_SENNA
+            lex->senna_clear();
+#endif /* ENABLE_SENNA */
 	    lex->col_list.empty();		/* Alloced by sql_alloc */
 	  }
 	| constraint opt_check_constraint
 	  {
+#ifdef ENABLE_SENNA
+            Lex->senna_clear();
+#endif /* ENABLE_SENNA */
 	    Lex->col_list.empty();		/* Alloced by sql_alloc */
 	  }
 	| opt_constraint check_constraint
 	  {
+#ifdef ENABLE_SENNA
+            Lex->senna_clear();
+#endif /* ENABLE_SENNA */
 	    Lex->col_list.empty();		/* Alloced by sql_alloc */
 	  }
 	;
@@ -3687,7 +3731,80 @@ opt_btree_or_rtree:
 	  {
 	    $$= HA_KEY_ALG_RTREE;
 	  }
-	| HASH_SYM	{ $$= HA_KEY_ALG_HASH; };
+        | HASH_SYM      { $$= HA_KEY_ALG_HASH; }
+        | opt_senna_list { $$= HA_KEY_ALG_UNDEF; };
+
+opt_senna_list:
+        opt_senna_item
+        | opt_senna_item ',' opt_senna_list ;
+
+opt_senna_item:
+        SENNA_SYM {
+#ifdef ENABLE_SENNA
+          Lex->senna_flags &= ~SEN_DISABLE_SENNA;
+#endif /* ENABLE_SENNA */
+        }
+        | NO_SYM SENNA_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags |= SEN_DISABLE_SENNA;
+#endif /* ENABLE_SENNA */
+          }
+        | SENNA_NORMALIZE_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags |= SEN_INDEX_NORMALIZE;
+#endif /* ENABLE_SENNA */
+          }
+        | NO_SYM SENNA_NORMALIZE_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags &= ~SEN_INDEX_NORMALIZE;
+#endif /* ENABLE_SENNA */
+          }
+        | SENNA_SPLIT_ALPHA_SYM {
+#ifdef ENABLE_SENNA
+	    Lex->senna_flags |= SEN_INDEX_SPLIT_ALPHA;
+#endif /* ENABLE_SENNA */
+          }
+        | SENNA_SPLIT_DIGIT_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags |= SEN_INDEX_SPLIT_DIGIT;
+#endif /* ENABLE_SENNA */
+          }
+        | SENNA_SPLIT_SYMBOL_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags |= SEN_INDEX_SPLIT_SYMBOL;
+#endif /* ENABLE_SENNA */
+          }
+        | SENNA_DELIMITED_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags &= ~SEN_INDEX_NGRAM;
+            Lex->senna_flags |= SEN_INDEX_DELIMITED;
+#endif /* ENABLE_SENNA */
+          }
+        | SENNA_MECAB_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags &= ~SEN_INDEX_DELIMITED;
+            Lex->senna_flags &= ~SEN_INDEX_NGRAM;
+#endif /* ENABLE_SENNA */
+          }
+        | SENNA_NGRAM_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags |= SEN_INDEX_NGRAM;
+#endif /* ENABLE_SENNA */
+          }
+        | SENNA_SECTIONALIZE_SYM {
+#ifdef ENABLE_SENNA
+            Lex->senna_flags |= 0x00080000;
+#endif /* ENABLE_SENNA */
+          }
+        | ulong_num {
+#ifdef ENABLE_SENNA
+            if ($1 < 65536) {
+              Lex->senna_initial_n_segments=$1;
+            } else {
+              Lex->senna_flags |= $1;
+            }
+#endif /* ENABLE_SENNA */
+          };
 
 key_list:
 	key_list ',' key_part order_dir { Lex->col_list.push_back($3); }
@@ -3740,6 +3857,9 @@ alter:
 	  if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
 						 TL_OPTION_UPDATING))
 	    MYSQL_YYABORT;
+#ifdef ENABLE_SENNA
+          lex->senna_clear();
+#endif /* ENABLE_SENNA */
 	  lex->col_list.empty();
           lex->select_lex.init_order();
 	  lex->select_lex.db=
@@ -5515,6 +5635,12 @@ simple_expr:
             if ($$ == NULL)
               MYSQL_YYABORT;
 	    Lex->safe_to_cache_query= 0;
+#ifdef ENABLE_SENNA
+	  }
+        | SENNA_KWIC_SYM '(' expr_list ')'
+          {
+            $$= new Item_func_senna_kwic(* $3);
+#endif
 	  }
 	| LAST_INSERT_ID '(' expr ')'
 	  {
@@ -8306,6 +8432,13 @@ show_param:
             Lex->sql_command= SQLCOM_SHOW_FUNC_CODE;
 	    Lex->spname= $3;
 #endif
+#ifdef ENABLE_SENNA
+          }
+        | SENNA_SYM STATUS_SYM opt_db wild_and_where
+          {
+            Lex->sql_command= SQLCOM_SHOW_SENNA_STATUS;
+            Lex->select_lex.db = $3;
+#endif
           }
         ;
 
@@ -9603,6 +9736,16 @@ keyword_sp:
 	| ROW_SYM		{}
 	| RTREE_SYM		{}
 	| SECOND_SYM		{}
+        | SENNA_DELIMITED_SYM   {}
+        | SENNA_KWIC_SYM        {}
+        | SENNA_MECAB_SYM       {}
+        | SENNA_NGRAM_SYM       {}
+        | SENNA_NORMALIZE_SYM   {}
+        | SENNA_SECTIONALIZE_SYM {}
+        | SENNA_SPLIT_ALPHA_SYM {}
+        | SENNA_SPLIT_DIGIT_SYM {}
+        | SENNA_SPLIT_SYMBOL_SYM {}
+        | SENNA_SYM             {}
 	| SERIAL_SYM		{}
 	| SERIALIZABLE_SYM	{}
 	| SESSION_SYM		{}
--- orig/sql/structs.h	2009-10-16 06:20:38.000000000 +0900
+++ new/sql/structs.h	2009-11-16 17:45:02.000000000 +0900
@@ -104,6 +104,18 @@ typedef struct st_key {
     int  bdb_return_if_eq;
   } handler;
   struct st_table *table;
+#ifdef ENABLE_SENNA
+  bool is_senna;                        /* this is set to true by ha_myisam::info */
+  int senna_flags;
+  int senna_initial_n_segments;
+  uint senna_keys_size;
+  uint senna_keys_file_size;
+  uint senna_lexicon_size;
+  uint senna_lexicon_file_size;
+  uint senna_inv_seg_size;
+  uint senna_inv_chunk_size;
+  const char *senna_encoding;
+#endif /* ENABLE_SENNA */
 } KEY;
 
 
--- orig/sql/table.cc	2009-10-16 06:20:38.000000000 +0900
+++ new/sql/table.cc	2009-11-16 17:45:02.000000000 +0900
@@ -109,6 +109,18 @@ int openfrm(THD *thd, const char *name, 
   if (my_read(file,(byte*) head,64,MYF(MY_NABP)))
     goto err;
 
+#ifdef ENABLE_SENNA
+  if (prgflag & SENNA_CHECK_VIEW)
+  {
+    if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW")) == 0)
+    {
+      error_reported = TRUE;
+      error = 0;
+      goto err;
+    }
+  }
+#endif
+
   if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0)
   {
     // new .frm
--- orig/sql/unireg.h	2009-10-16 06:20:38.000000000 +0900
+++ new/sql/unireg.h	2009-11-16 17:45:02.000000000 +0900
@@ -155,6 +155,10 @@
 #define NO_ERR_ON_NEW_FRM	8192	/* stop error sending on new format */
 #define OPEN_VIEW_NO_PARSE     16384    /* Open frm only if it's a view,
                                            but do not parse view itself */
+#ifdef ENABLE_SENNA
+#define SENNA_CHECK_VIEW       32768
+#endif
+
 #define SC_INFO_LENGTH 4		/* Form format constant */
 #define TE_INFO_LENGTH 3
 #define MTYP_NOEMPTY_BIT 128