--- groonga-storage-engine-1.0.1/ha_mroonga.cc	2011-10-28 07:19:15.506715507 +0200
+++ groonga-storage-engine-1.0.1/ha_mroonga.cc	2011-11-02 11:37:03.095096227 +0100
@@ -77,6 +77,9 @@
 extern "C" {
 #endif
 
+/* groonga's internal functions */
+const char *grn_obj_get_value_(grn_ctx *ctx, grn_obj *obj, grn_id id, uint32 *size);
+
 /* global variables */
 pthread_mutex_t mrn_db_mutex;
 pthread_mutex_t mrn_log_mutex;
@@ -109,7 +112,6 @@
 static bool mrn_logfile_opened = false;
 grn_log_level mrn_log_level_default = GRN_LOG_DEFAULT_LEVEL;
 ulong mrn_log_level = (ulong) mrn_log_level_default;
-char mrn_default_parser_name[MRN_MAX_KEY_SIZE];
 char *mrn_default_parser;
 
 static void mrn_logger_func(int level, const char *time, const char *title,
@@ -228,13 +230,12 @@
           "default parser changed from '%s' to '%s'",
           old_value, new_value);
   grn_ctx_fin(&ctx);
-  strcpy(mrn_default_parser_name, new_value);
-  mrn_default_parser = mrn_default_parser_name;
+  strncpy(mrn_default_parser, new_value, MRN_MAX_KEY_SIZE - 1);
   DBUG_VOID_RETURN;
 }
 
 static MYSQL_SYSVAR_STR(default_parser, mrn_default_parser,
-                        PLUGIN_VAR_RQCMDARG,
+                        PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
                         "default fulltext parser",
                         NULL,
                         mrn_default_parser_update,
@@ -908,6 +909,15 @@
                    field->charset());
       break;
     }
+  case MYSQL_TYPE_BLOB:
+    {
+      GRN_VOID_INIT(&buf);
+      uint32 len;
+      const char *val = grn_obj_get_value_(ctx, col, id, &len);
+      Field_blob *blob = (Field_blob *)field;
+      blob->set_ptr((uchar *)&len, (uchar *)val);
+      break;
+    }
   default: //strings etc..
     {
       GRN_TEXT_INIT(&buf,0);
@@ -1010,6 +1020,9 @@
     goto error_allocated_open_tables_hash_init;
   }
 
+  mrn_default_parser = (char *)my_malloc(MRN_MAX_KEY_SIZE, MYF(MY_WME));
+  strncpy(mrn_default_parser, MRN_PARSER_DEFAULT, MRN_MAX_KEY_SIZE - 1);
+
   return 0;
 
 error_allocated_open_tables_hash_init:
@@ -4422,7 +4435,7 @@
   DBUG_RETURN(error);
 }
 
-int ha_mroonga::wrapper_index_read_map(uchar * buf, const uchar * key,
+int ha_mroonga::wrapper_index_read_map(uchar *buf, const uchar *key,
                                        key_part_map keypart_map,
                                        enum ha_rkey_function find_flag)
 {
@@ -4442,7 +4455,11 @@
     MRN_SET_WRAP_TABLE_KEY(this, table);
     if (fulltext_searching)
       set_pk_bitmap();
+#ifdef MRN_HANDLER_HAVE_HA_INDEX_READ_MAP
+    error = wrap_handler->ha_index_read_map(buf, key, keypart_map, find_flag);
+#else
     error = wrap_handler->index_read_map(buf, key, keypart_map, find_flag);
+#endif
     MRN_SET_BASE_SHARE_KEY(share, table->s);
     MRN_SET_BASE_TABLE_KEY(this, table);
   }
@@ -4557,7 +4574,7 @@
   DBUG_RETURN(error);
 }
 
-int ha_mroonga::index_read_map(uchar * buf, const uchar * key,
+int ha_mroonga::index_read_map(uchar *buf, const uchar *key,
                                key_part_map keypart_map,
                                enum ha_rkey_function find_flag)
 {
@@ -4572,6 +4589,7 @@
   DBUG_RETURN(error);
 }
 
+#ifdef MRN_HANDLER_HAVE_INDEX_READ_LAST_MAP
 int ha_mroonga::wrapper_index_read_last_map(uchar *buf, const uchar *key,
                                             key_part_map keypart_map)
 {
@@ -4658,6 +4676,7 @@
   }
   DBUG_RETURN(error);
 }
+#endif
 
 int ha_mroonga::wrapper_index_next(uchar *buf)
 {
@@ -6226,7 +6245,11 @@
 }
 
 ha_rows ha_mroonga::wrapper_multi_range_read_info(uint keyno, uint n_ranges,
-                                                  uint keys, uint *bufsz,
+                                                  uint keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                                  uint key_parts,
+#endif
+                                                  uint *bufsz,
                                                   uint *flags, COST_VECT *cost)
 {
   MRN_DBUG_ENTER_METHOD();
@@ -6236,6 +6259,9 @@
   if (fulltext_searching)
     set_pk_bitmap();
   rows = wrap_handler->multi_range_read_info(keyno, n_ranges, keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                             key_parts,
+#endif
                                              bufsz, flags, cost);
   MRN_SET_BASE_SHARE_KEY(share, table->s);
   MRN_SET_BASE_TABLE_KEY(this, table);
@@ -6243,16 +6269,26 @@
 }
 
 ha_rows ha_mroonga::storage_multi_range_read_info(uint keyno, uint n_ranges,
-                                                  uint keys, uint *bufsz,
+                                                  uint keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                                  uint key_parts,
+#endif
+                                                  uint *bufsz,
                                                   uint *flags, COST_VECT *cost)
 {
   MRN_DBUG_ENTER_METHOD();
   ha_rows rows = handler::multi_range_read_info(keyno, n_ranges, keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                                key_parts,
+#endif
                                                 bufsz, flags, cost);
   DBUG_RETURN(rows);
 }
 
 ha_rows ha_mroonga::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                          uint key_parts,
+#endif
                                           uint *bufsz, uint *flags,
                                           COST_VECT *cost)
 {
@@ -6261,9 +6297,15 @@
   if (share->wrapper_mode)
   {
     rows = wrapper_multi_range_read_info(keyno, n_ranges, keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                         key_parts,
+#endif
                                          bufsz, flags, cost);
   } else {
     rows = storage_multi_range_read_info(keyno, n_ranges, keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                         key_parts,
+#endif
                                          bufsz, flags, cost);
   }
   DBUG_RETURN(rows);
@@ -6315,7 +6357,7 @@
   DBUG_RETURN(error);
 }
 
-int ha_mroonga::wrapper_multi_range_read_next(char **range_info)
+int ha_mroonga::wrapper_multi_range_read_next(range_id_t *range_info)
 {
   MRN_DBUG_ENTER_METHOD();
   int error = 0;
@@ -6329,14 +6371,14 @@
   DBUG_RETURN(error);
 }
 
-int ha_mroonga::storage_multi_range_read_next(char **range_info)
+int ha_mroonga::storage_multi_range_read_next(range_id_t *range_info)
 {
   MRN_DBUG_ENTER_METHOD();
   int error = handler::multi_range_read_next(range_info);
   DBUG_RETURN(error);
 }
 
-int ha_mroonga::multi_range_read_next(char **range_info)
+int ha_mroonga::multi_range_read_next(range_id_t *range_info)
 {
   MRN_DBUG_ENTER_METHOD();
   int error = 0;
--- groonga-storage-engine-1.0.1/ha_mroonga.h	2011-10-27 12:31:36.859277054 +0200
+++ groonga-storage-engine-1.0.1/ha_mroonga.h	2011-11-02 11:37:03.095096227 +0100
@@ -47,18 +47,22 @@
 #  define MRN_HANDLER_HAVE_ADD_INDEX 1
 #endif
 
-#if (MYSQL_VERSION_ID >= 50600) || \
-    (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50302)
-#  define MRN_HANDLER_HAVE_HA_CLOSE 1
+#if (MYSQL_VERSION_ID >= 50603) || \
+    (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50209)
 #  define MRN_HANDLER_HAVE_HA_RND_NEXT 1
 #  define MRN_HANDLER_HAVE_HA_RND_POS 1
+#  define MRN_HANDLER_HAVE_HA_INDEX_READ_MAP 1
 #  define MRN_HANDLER_HAVE_HA_INDEX_READ_IDX_MAP 1
 #  define MRN_HANDLER_HAVE_HA_INDEX_NEXT 1
 #  define MRN_HANDLER_HAVE_HA_INDEX_PREV 1
 #  define MRN_HANDLER_HAVE_HA_INDEX_FIRST 1
 #  define MRN_HANDLER_HAVE_HA_INDEX_LAST 1
 #  define MRN_HANDLER_HAVE_HA_INDEX_NEXT_SAME 1
+#endif
 
+#if (MYSQL_VERSION_ID >= 50603) || \
+    (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50302)
+#  define MRN_HANDLER_HAVE_HA_CLOSE 1
 #  define MRN_HANDLER_HAVE_MULTI_RANGE_READ 1
 #endif
 
@@ -66,6 +70,14 @@
 #  define MRN_HANDLER_HAVE_HA_INPLACE_INDEX_CHANGE
 #endif
 
+#ifndef MRN_MARIADB_P
+#  define MRN_HANDLER_HAVE_INDEX_READ_LAST_MAP
+#endif
+
+#if (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50302)
+#  define MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+#endif
+
 #if MYSQL_VERSION_ID < 50600
   typedef Item COND;
 #endif
@@ -74,6 +86,10 @@
   typedef MYSQL_ERROR Sql_condition;
 #endif
 
+#ifndef MRN_MARIADB_P
+  typedef char *range_id_t;
+#endif
+
 class ha_mroonga;
 
 /* structs */
@@ -213,11 +229,15 @@
   ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
   int index_init(uint idx, bool sorted);
   int index_end();
+#ifndef MRN_HANDLER_HAVE_HA_INDEX_READ_MAP
   int index_read_map(uchar * buf, const uchar * key,
                      key_part_map keypart_map,
                      enum ha_rkey_function find_flag);
+#endif
+#ifdef MRN_HANDLER_HAVE_INDEX_READ_LAST_MAP
   int index_read_last_map(uchar *buf, const uchar *key,
                           key_part_map keypart_map);
+#endif
 #ifndef MRN_HANDLER_HAVE_HA_INDEX_NEXT
   int index_next(uchar *buf);
 #endif
@@ -261,11 +281,14 @@
                                       uint n_ranges, uint *bufsz,
                                       uint *flags, COST_VECT *cost);
   ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                uint key_parts,
+#endif
                                 uint *bufsz, uint *flags, COST_VECT *cost);
   int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
                             uint n_ranges, uint mode,
                             HANDLER_BUFFER *buf);
-  int multi_range_read_next(char **range_info);
+  int multi_range_read_next(range_id_t *range_info);
 #else // MRN_HANDLER_HAVE_MULTI_RANGE_READ
   int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
                              KEY_MULTI_RANGE *ranges,
@@ -321,6 +344,11 @@
 #ifdef MRN_HANDLER_HAVE_HA_RND_POS
   int rnd_pos(uchar *buf, uchar *pos);
 #endif
+#ifdef MRN_HANDLER_HAVE_HA_INDEX_READ_MAP
+  int index_read_map(uchar *buf, const uchar *key,
+                     key_part_map keypart_map,
+                     enum ha_rkey_function find_flag);
+#endif
 #ifdef MRN_HANDLER_HAVE_HA_INDEX_NEXT
   int index_next(uchar *buf);
 #endif
@@ -469,10 +497,12 @@
   int storage_index_read_map(uchar *buf, const uchar *key,
                              key_part_map keypart_map,
                              enum ha_rkey_function find_flag);
+#ifdef MRN_HANDLER_HAVE_INDEX_READ_LAST_MAP
   int wrapper_index_read_last_map(uchar *buf, const uchar *key,
                                   key_part_map keypart_map);
   int storage_index_read_last_map(uchar *buf, const uchar *key,
                                   key_part_map keypart_map);
+#endif
   int wrapper_index_next(uchar *buf);
   int storage_index_next(uchar *buf);
   int wrapper_index_prev(uchar *buf);
@@ -533,9 +563,15 @@
                                               uint *flags,
                                               COST_VECT *cost);
   ha_rows wrapper_multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                        uint key_parts,
+#endif
                                         uint *bufsz, uint *flags,
                                         COST_VECT *cost);
   ha_rows storage_multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
+                                        uint key_parts,
+#endif
                                         uint *bufsz, uint *flags,
                                         COST_VECT *cost);
   int wrapper_multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
@@ -544,8 +580,8 @@
   int storage_multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
                                     uint n_ranges, uint mode,
                                     HANDLER_BUFFER *buf);
-  int wrapper_multi_range_read_next(char **range_info);
-  int storage_multi_range_read_next(char **range_info);
+  int wrapper_multi_range_read_next(range_id_t *range_info);
+  int storage_multi_range_read_next(range_id_t *range_info);
 #else // MRN_HANDLER_HAVE_MULTI_RANGE_READ
   int wrapper_read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
                                      KEY_MULTI_RANGE *ranges,
--- groonga-storage-engine-1.0.1/test/run-sql-test.sh	2011-09-27 10:43:29.093290682 +0200
+++ groonga-storage-engine-1.0.1/test/run-sql-test.sh	2011-11-02 11:37:03.099096256 +0100
@@ -24,12 +24,20 @@
 source_test_suites_dir="${source_mysql_test_dir}/suite"
 build_test_suites_dir="${build_mysql_test_dir}/suite"
 case "${MYSQL_VERSION}" in
-    5.1)
+    5.1.*)
 	plugins_dir="${MYSQL_BUILD}/lib/mysql/plugin"
 	if ! test -d "${build_test_suites_dir}"; then
 	    mkdir -p "${build_test_suites_dir}"
 	fi
 	;;
+    *-MariaDB*)
+	if ! test -d "${build_test_suites_dir}"; then
+	    ln -s "${source_test_suites_dir}" "${build_test_suites_dir}"
+	fi
+	if ! test -d "${MYSQL_BUILD}/plugin/mroonga"; then
+	    ln -s "${top_dir}" "${MYSQL_BUILD}/plugin/mroonga"
+	fi
+	;;
     *)
 	if ! test -d "${build_test_suites_dir}"; then
 	    ln -s "${source_test_suites_dir}" "${build_test_suites_dir}"
@@ -47,10 +55,14 @@
     fi
 done
 
-make -C ${top_dir} \
-    install-pluginLTLIBRARIES \
-    plugindir=${plugins_dir} > /dev/null || \
-    exit 1
+if test -n "${plugins_dir}"; then
+    make -C ${top_dir} \
+	install-pluginLTLIBRARIES \
+	plugindir=${plugins_dir} > /dev/null || \
+	exit 1
+else
+    make -C ${top_dir} > /dev/null || exit 1
+fi
 
 (cd "$build_mysql_test_dir" && \
     ./mysql-test-run.pl \