diff options
author | Kentoku SHIBA <kentokushiba@gmail.com> | 2015-07-02 04:12:21 +0900 |
---|---|---|
committer | Kentoku SHIBA <kentokushiba@gmail.com> | 2015-07-02 04:12:21 +0900 |
commit | 06913d016268c4d0d7e19d19cbe6ca96a7f20e18 (patch) | |
tree | 08bb0719182c6eec97104f053f278c79983a3786 /storage/mroonga | |
parent | 031930489360b24032fd151c71292026b3747f32 (diff) | |
download | mariadb-git-06913d016268c4d0d7e19d19cbe6ca96a7f20e18.tar.gz |
Update Mroonga to the latest version on 2015-07-02T04:12:21+0900
Diffstat (limited to 'storage/mroonga')
329 files changed, 11200 insertions, 2136 deletions
diff --git a/storage/mroonga/CMakeLists.txt b/storage/mroonga/CMakeLists.txt index e5d0abe5dcd..3b88d942165 100644 --- a/storage/mroonga/CMakeLists.txt +++ b/storage/mroonga/CMakeLists.txt @@ -39,11 +39,6 @@ if(BIG_ENDIAN) endif() endif() -if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") - message(STATUS "Mroonga is not supported on Solaris") - return() -endif() - if(MSVC) if(MSVC_VERSION LESS 1800) set(MRN_OLD_MSVC_MESSAGE "Mroonga supports only MSVC 2013 or later") @@ -115,6 +110,8 @@ if(MRN_GROONGA_BUNDLED) add_subdirectory("${MRN_BUNDLED_GROONGA_RELATIVE_DIR}") else() + set(MRN_GROONGA_EMBED OFF) + file(READ ${MRN_SOURCE_DIR}/required_groonga_version REQUIRED_GROONGA_VERSION) string(STRIP "${REQUIRED_GROONGA_VERSION}" REQUIRED_GROONGA_VERSION) @@ -323,8 +320,7 @@ set(MRN_ALL_SOURCES if(MRN_BUNDLED) mysql_add_plugin(mroonga ${MRN_ALL_SOURCES} - STORAGE_ENGINE MODULE_ONLY DISABLED # see MDEV-7246 - RECOMPILE_FOR_EMBEDDED + STORAGE_ENGINE MODULE_ONLY LINK_LIBRARIES ${MRN_LIBRARIES}) else() add_library(mroonga MODULE ${MRN_ALL_SOURCES}) @@ -334,28 +330,33 @@ else() option(WITH_DEBUG "Enable debug options" OFF) if(WITH_DEBUG) - add_definitions("-DSAFE_MUTEX") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "SAFE_MUTEX") if(CMAKE_COMPILER_IS_GNUCXX) set(MRN_C_COMPILE_FLAGS "${MRN_C_COMPILE_FLAGS} -g3 -O0") set(MRN_CXX_COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS} -g3 -O0") endif() else() - add_definitions("-DDBUG_OFF") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "DBUG_OFF") endif() option(WITH_DEBUG_FULL "Enable full debug options" OFF) if(WITH_DEBUG_FULL) - add_definitions("-DSAFE_MUTEX" "SAFEMALLOC") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "SAFE_MUTEX" "SAFEMALLOC") endif() option(DISABLE_FAST_MUTEXES "Force disabling fast mutex" OFF) if(DISABLE_FAST_MUTEXES) - add_definitions("-DFORCE_FAST_MUTEX_DISABLED=1") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "FORCE_FAST_MUTEX_DISABLED=1") endif() option(WITH_FAST_MUTEXES "Enable fast mutex" OFF) if(WITH_FAST_MUTEXES) - add_definitions("-DMY_PTHREAD_FASTMUTEX") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "MY_PTHREAD_FASTMUTEX") endif() if(CMAKE_COMPILER_IS_GNUCXX) @@ -381,7 +382,8 @@ else() COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS}") set_source_files_properties(${LIBMRN_NO_MYSQL_SOURCES} PROPERTIES COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS}") - add_definitions("-DMYSQL_DYNAMIC_PLUGIN") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "MYSQL_DYNAMIC_PLUGIN") set_target_properties(mroonga PROPERTIES PREFIX "" OUTPUT_NAME "ha_mroonga") @@ -390,16 +392,33 @@ else() endif() if(GROONGA_NORMALIZER_MYSQL_FOUND) - add_definitions("-DWITH_GROONGA_NORMALIZER_MYSQL=1") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "WITH_GROONGA_NORMALIZER_MYSQL=1") if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED) - add_definitions("-DMRN_GROONGA_NORMALIZER_MYSQL_EMBED") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "MRN_GROONGA_NORMALIZER_MYSQL_EMBEDDED") else() - add_definitions("-DGROONGA_NORMALIZER_MYSQL_PLUGIN_NAME=\"normalizers/mysql\"") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "GROONGA_NORMALIZER_MYSQL_PLUGIN_NAME=\"normalizers/mysql\"") endif() endif() -set(MRN_DEFAULT_PARSER "TokenBigram" CACHE STRING "The default fulltext parser") -add_definitions("-DMRN_PARSER_DEFAULT=\"${MRN_DEFAULT_PARSER}\"") +if(MRN_GROONGA_EMBED) + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "MRN_GROONGA_EMBEDDED") +endif() + +set(MRN_DEFAULT_PARSER "" CACHE STRING + "The default fulltext parser (Deprecated. Use MRN_DEFAULT_TOKENIZER instead.)") +set(MRN_DEFAULT_TOKENIZER "" CACHE STRING + "The default tokenizer for fulltext index") +if(NOT ${MRN_DEFAULT_TOKENIZER} STREQUAL "") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "MRN_DEFAULT_TOKENIZER=\"${MRN_DEFAULT_TOKENIZER}\"") +elseif(NOT ${MRN_DEFAULT_PARSER} STREQUAL "") + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "MRN_DEFAULT_TOKENIZER=\"${MRN_DEFAULT_PARSER}\"") +endif() configure_file( "${PROJECT_SOURCE_DIR}/mrn_version.h.in" diff --git a/storage/mroonga/appveyor.yml b/storage/mroonga/appveyor.yml index de368b85660..038d590054e 100644 --- a/storage/mroonga/appveyor.yml +++ b/storage/mroonga/appveyor.yml @@ -3,16 +3,16 @@ clone_depth: 10 install: - cd .. - choco install -y curl 7zip.commandline - - curl -O http://mirror.jmu.edu/pub/mariadb/mariadb-10.0.17/source/mariadb-10.0.17.tar.gz - - 7z x mariadb-10.0.17.tar.gz - - 7z x mariadb-10.0.17.tar > nul - - cd mariadb-10.0.17 + - curl -O http://mirror.jmu.edu/pub/mariadb/mariadb-10.0.20/source/mariadb-10.0.20.tar.gz + - 7z x mariadb-10.0.20.tar.gz + - 7z x mariadb-10.0.20.tar > nul + - cd mariadb-10.0.20 - rmdir /S /Q storage\mroonga\ - move ..\mroonga storage\mroonga - git clone --quiet --depth 1 https://github.com/groonga/groonga.git ..\groonga - cd ..\groonga - git submodule update --init - - cd ..\mariadb-10.0.17 + - cd ..\mariadb-10.0.20 - rmdir /S /Q ..\groonga\test\ - mkdir storage\mroonga\vendor - move ..\groonga storage\mroonga\vendor\groonga diff --git a/storage/mroonga/build/makefiles/gettext.am b/storage/mroonga/build/makefiles/gettext.am index 9706b485dd1..9cea8ce63c1 100644 --- a/storage/mroonga/build/makefiles/gettext.am +++ b/storage/mroonga/build/makefiles/gettext.am @@ -1,6 +1,8 @@ include $(top_srcdir)/doc/files.am include $(top_srcdir)/build/makefiles/sphinx-build.am +CLEANFILES = + EXTRA_DIST += \ $(po_files) @@ -11,9 +13,11 @@ endif if DOCUMENT_BUILDABLE BUILT_SOURCES += \ + mo-build-stamp +CLEANFILES += \ pot-build-stamp \ edit-po-build-stamp \ - $(mo_files) + mo-build-stamp endif SUFFIXES += .pot .po .mo .edit @@ -47,8 +51,8 @@ SUFFIXES += .pot .po .mo .edit msgfmt -o $@ $< if DOCUMENT_BUILDABLE -update: pot-build-stamp edit-po-build-stamp -build: update $(mo_files) +update: edit-po-build-stamp +build: mo-build-stamp else update: build: @@ -68,6 +72,15 @@ pot-build-stamp: $(absolute_source_files) $(MAKE) gettext @touch $@ -edit-po-build-stamp: $(absolute_source_files) +edit-po-build-stamp: pot-build-stamp $(MAKE) $(edit_po_files) @touch $@ + +mo_build_stamp_dependencies = edit-po-build-stamp +if DOCUMENT_BUILDABLE +mo_build_stamp_dependencies += $(edit_po_files) +endif + +mo-build-stamp: $(mo_build_stamp_dependencies) + $(MAKE) $(mo_files) + @touch $@ diff --git a/storage/mroonga/build/makefiles/sphinx.am b/storage/mroonga/build/makefiles/sphinx.am index f84fb23b739..c68f62e26ec 100644 --- a/storage/mroonga/build/makefiles/sphinx.am +++ b/storage/mroonga/build/makefiles/sphinx.am @@ -106,7 +106,7 @@ help: @echo " doctest to run all doctests embedded in the documentation (if enabled)" man: man-build-stamp -html: html-build-stamp +html: html-recursive html-build-stamp dirhtml: dirhtml-build-stamp pickle: pickle-build-stamp json: json-build-stamp diff --git a/storage/mroonga/configure.ac b/storage/mroonga/configure.ac index dc127c17838..f60b481e0ea 100644 --- a/storage/mroonga/configure.ac +++ b/storage/mroonga/configure.ac @@ -309,20 +309,30 @@ CONFIG_OPTION_GROONGA_NORMALIZER_MYSQL AC_ARG_WITH(default_parser, [AS_HELP_STRING([--with-default-parser=PARSER], - [specify the default fulltext parser like + [Deprecated. Use --with-default-tokenizer=TOKENIZER instead. + specify the default fulltext parser like --with-default-parser=TokenMecab. (default: TokenBigram)])], [default_parser=$withval], [default_parser=no]) if test x"$default_parser" != x"no"; then - AC_DEFINE_UNQUOTED(MRN_PARSER_DEFAULT, + AC_DEFINE_UNQUOTED(MRN_TOKENIZER_DEFAULT, "$default_parser", - "specified default fulltext parser") - MRN_DEFAULT_PARSER=$default_parser -else - MRN_DEFAULT_PARSER=TokenBigram + "specified the default tokenizer for fulltext index") +fi + +AC_ARG_WITH(default_tokenizer, + [AS_HELP_STRING([--with-default-tokenizer=TOKENIZER], + [specify the default tokenizer for fulltext index like + --with-default-tokenizer=TokenMecab. + (default: TokenBigram)])], + [default_tokenizer=$withval], + [default_tokenizer=no]) +if test x"$default_tokenizer" != x"no"; then + AC_DEFINE_UNQUOTED(MRN_DEFAULT_TOKENIZER, + "$default_tokenizer", + "specified the default tokenizer for fulltext index") fi -AC_SUBST(MRN_DEFAULT_PARSER) AC_ARG_ENABLE(fast_mutexes, [AS_HELP_STRING([--disable-fast-mutexes], diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 83f03fcb272..a94278e19c2 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -27,14 +27,11 @@ #pragma implementation #endif -#if MYSQL_VERSION_ID >= 50500 -# include <sql_plugin.h> -# include <sql_show.h> -# include <key.h> -# include <tztime.h> -# include <sql_base.h> -#endif - +#include <sql_plugin.h> +#include <sql_show.h> +#include <key.h> +#include <tztime.h> +#include <sql_base.h> #include <sql_select.h> #include <item_sum.h> @@ -102,6 +99,10 @@ # include <sql_table.h> #endif +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS +# include <create_options.h> +#endif + // for debug #define MRN_CLASS_NAME "ha_mroonga" @@ -110,7 +111,11 @@ #define MRN_LONG_TEXT_SIZE (1 << 31) // 2Gbytes #ifdef MRN_HAVE_TDC_LOCK_TABLE_SHARE -# define mrn_open_mutex(share) &((share)->tdc.LOCK_table_share) +# ifdef MRN_TABLE_SHARE_TDC_IS_POINTER +# define mrn_open_mutex(share) &((share)->tdc->LOCK_table_share) +# else +# define mrn_open_mutex(share) &((share)->tdc.LOCK_table_share) +# endif # define mrn_open_mutex_lock(share) do { \ TABLE_SHARE *share_ = share; \ if (share_ && share_->tmp_table == NO_TMP_TABLE) { \ @@ -156,24 +161,10 @@ static mysql_mutex_t *mrn_LOCK_open; # define mrn_declare_plugin(NAME) maria_declare_plugin(NAME) # define mrn_declare_plugin_end maria_declare_plugin_end # define MRN_PLUGIN_LAST_VALUES MRN_VERSION, MariaDB_PLUGIN_MATURITY_STABLE -# if MYSQL_VERSION_ID >= 100000 -# define MRN_ABORT_ON_WARNING(thd) thd_kill_level(thd) -# else -# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning -# endif #else # define mrn_declare_plugin(NAME) mysql_declare_plugin(NAME) # define mrn_declare_plugin_end mysql_declare_plugin_end -# ifdef MRN_PLUGIN_HAVE_FLAGS -# define MRN_PLUGIN_LAST_VALUES NULL, 0 -# else -# define MRN_PLUGIN_LAST_VALUES NULL -# endif -# if MYSQL_VERSION_ID >= 50706 -# define MRN_ABORT_ON_WARNING(thd) false -# else -# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning -# endif +# define MRN_PLUGIN_LAST_VALUES NULL, 0 #endif #if MYSQL_VERSION_ID >= 100007 && defined(MRN_MARIADB_P) @@ -267,9 +258,7 @@ uint grn_atoui(const char *nptr, const char *end, const char **rest); # ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE PSI_mutex_key *mrn_table_share_lock_share; # endif -# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA PSI_mutex_key *mrn_table_share_lock_ha_data; -# endif # endif static PSI_mutex_key mrn_open_tables_mutex_key; static PSI_mutex_key mrn_long_term_share_mutex_key; @@ -357,11 +346,6 @@ static const char *mrn_inspect_thr_lock_type(enum thr_lock_type lock_type) case TL_WRITE_ALLOW_WRITE: inspected = "TL_WRITE_ALLOW_WRITE"; break; -#ifdef MRN_HAVE_TL_WRITE_ALLOW_READ - case TL_WRITE_ALLOW_READ: - inspected = "TL_WRITE_ALLOW_READ"; - break; -#endif #ifdef MRN_HAVE_TL_WRITE_CONCURRENT_DEFAULT case TL_WRITE_CONCURRENT_DEFAULT: inspected = "TL_WRITE_CONCURRENT_DEFAULT"; @@ -524,19 +508,15 @@ static const char *mrn_inspect_extra_function(enum ha_extra_function operation) case HA_EXTRA_PREPARE_FOR_RENAME: inspected = "HA_EXTRA_PREPARE_FOR_RENAME"; break; -#ifdef MRN_HAVE_HA_EXTRA_ADD_CHILDREN_LIST case HA_EXTRA_ADD_CHILDREN_LIST: inspected = "HA_EXTRA_ADD_CHILDREN_LIST"; break; -#endif case HA_EXTRA_ATTACH_CHILDREN: inspected = "HA_EXTRA_ATTACH_CHILDREN"; break; -#ifdef MRN_HAVE_HA_EXTRA_IS_ATTACHED_CHILDREN case HA_EXTRA_IS_ATTACHED_CHILDREN: inspected = "HA_EXTRA_IS_ATTACHED_CHILDREN"; break; -#endif case HA_EXTRA_DETACH_CHILDREN: inspected = "HA_EXTRA_DETACH_CHILDREN"; break; @@ -597,7 +577,7 @@ static bool mrn_log_file_opened = false; static grn_log_level mrn_log_level_default = GRN_LOG_DEFAULT_LEVEL; static ulong mrn_log_level = mrn_log_level_default; -char *mrn_default_parser = NULL; +char *mrn_default_tokenizer = NULL; char *mrn_default_wrapper_engine = NULL; static int mrn_lock_timeout = grn_get_lock_timeout(); static char *mrn_libgroonga_version = const_cast<char *>(grn_get_version()); @@ -630,6 +610,11 @@ static TYPELIB mrn_boolean_mode_syntax_flags_typelib = { NULL }; #endif +#ifdef MRN_GROONGA_EMBEDDED +static my_bool mrn_libgroonga_embedded = TRUE; +#else +static my_bool mrn_libgroonga_embedded = FALSE; +#endif typedef enum { MRN_ACTION_ON_ERROR_ERROR, @@ -836,8 +821,8 @@ static MYSQL_SYSVAR_STR(log_file, mrn_log_file_path, mrn_log_file_update, MRN_LOG_FILE_PATH); -static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var, - void *var_ptr, const void *save) +static void mrn_default_tokenizer_update(THD *thd, struct st_mysql_sys_var *var, + void *var_ptr, const void *save) { MRN_DBUG_ENTER_FUNCTION(); const char *new_value = *((const char **)save); @@ -848,12 +833,12 @@ static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var, mrn_change_encoding(&ctx, system_charset_info); if (strcmp(*old_value_ptr, new_value) == 0) { GRN_LOG(&ctx, GRN_LOG_NOTICE, - "default parser isn't changed " - "because the requested default parser isn't different: <%s>", + "default tokenizer for fulltext index isn't changed " + "because the requested default tokenizer isn't different: <%s>", new_value); } else { GRN_LOG(&ctx, GRN_LOG_NOTICE, - "default fulltext parser is changed: <%s> -> <%s>", + "default tokenizer for fulltext index is changed: <%s> -> <%s>", *old_value_ptr, new_value); } @@ -869,12 +854,20 @@ static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var, DBUG_VOID_RETURN; } -static MYSQL_SYSVAR_STR(default_parser, mrn_default_parser, +static MYSQL_SYSVAR_STR(default_parser, mrn_default_tokenizer, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, - "default fulltext parser", + "default fulltext parser " + "(Deprecated. Use mroonga_default_tokenizer instead.)", NULL, - mrn_default_parser_update, - MRN_PARSER_DEFAULT); + mrn_default_tokenizer_update, + MRN_DEFAULT_TOKENIZER); + +static MYSQL_SYSVAR_STR(default_tokenizer, mrn_default_tokenizer, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, + "default tokenizer for fulltext index", + NULL, + mrn_default_tokenizer_update, + MRN_DEFAULT_TOKENIZER); static MYSQL_THDVAR_BOOL( dry_write, /* name */ @@ -1084,11 +1077,19 @@ static MYSQL_THDVAR_INT(max_n_records_for_estimate, INT_MAX, 0); +static MYSQL_SYSVAR_BOOL(libgroonga_embedded, mrn_libgroonga_embedded, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "Whether libgroonga is embedded or not", + NULL, + NULL, + mrn_libgroonga_embedded); + static struct st_mysql_sys_var *mrn_system_variables[] = { MYSQL_SYSVAR(log_level), MYSQL_SYSVAR(log_file), MYSQL_SYSVAR(default_parser), + MYSQL_SYSVAR(default_tokenizer), MYSQL_SYSVAR(dry_write), MYSQL_SYSVAR(enable_optimization), MYSQL_SYSVAR(match_escalation_threshold), @@ -1105,6 +1106,7 @@ static struct st_mysql_sys_var *mrn_system_variables[] = MYSQL_SYSVAR(boolean_mode_syntax_flags), #endif MYSQL_SYSVAR(max_n_records_for_estimate), + MYSQL_SYSVAR(libgroonga_embedded), NULL }; @@ -1213,7 +1215,7 @@ static int mrn_close_connection(handlerton *hton, THD *thd) MRN_DBUG_ENTER_FUNCTION(); void *p = *thd_ha_data(thd, mrn_hton_ptr); if (p) { - mrn_clear_alter_share(thd); + mrn_clear_slot_data(thd); free(p); *thd_ha_data(thd, mrn_hton_ptr) = (void *) NULL; { @@ -1409,13 +1411,14 @@ static grn_builtin_type mrn_grn_type_from_field(grn_ctx *ctx, Field *field, return type; } -grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd, - grn_ctx *ctx, - const char *flag_names, - uint flag_names_length) +static bool mrn_parse_grn_column_create_flags(THD *thd, + grn_ctx *ctx, + const char *flag_names, + uint flag_names_length, + grn_obj_flags *column_flags) { - grn_obj_flags flags = 0; const char *flag_names_end = flag_names + flag_names_length; + bool found = false; while (flag_names < flag_names_end) { uint rest_length = flag_names_end - flag_names; @@ -1425,14 +1428,17 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd, continue; } if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_SCALAR", 13)) { - flags |= GRN_OBJ_COLUMN_SCALAR; + *column_flags |= GRN_OBJ_COLUMN_SCALAR; flag_names += 13; + found = true; } else if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_VECTOR", 13)) { - flags |= GRN_OBJ_COLUMN_VECTOR; + *column_flags |= GRN_OBJ_COLUMN_VECTOR; flag_names += 13; + found = true; } else if (rest_length >= 13 && !memcmp(flag_names, "COMPRESS_ZLIB", 13)) { if (mrn_libgroonga_support_zlib) { - flags |= GRN_OBJ_COMPRESS_ZLIB; + *column_flags |= GRN_OBJ_COMPRESS_ZLIB; + found = true; } else { push_warning_printf(thd, MRN_SEVERITY_WARNING, ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM, @@ -1442,7 +1448,8 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd, flag_names += 13; } else if (rest_length >= 12 && !memcmp(flag_names, "COMPRESS_LZ4", 12)) { if (mrn_libgroonga_support_lz4) { - flags |= GRN_OBJ_COMPRESS_LZ4; + *column_flags |= GRN_OBJ_COMPRESS_LZ4; + found = true; } else { push_warning_printf(thd, MRN_SEVERITY_WARNING, ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM, @@ -1459,20 +1466,18 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd, push_warning_printf(thd, MRN_SEVERITY_WARNING, ER_MRN_INVALID_COLUMN_FLAG_NUM, ER_MRN_INVALID_COLUMN_FLAG_STR, - invalid_flag_name, - "COLUMN_SCALAR"); - flags |= GRN_OBJ_COLUMN_SCALAR; + invalid_flag_name); break; } } - return flags; + return found; } -bool mrn_parse_grn_index_column_flags(THD *thd, - grn_ctx *ctx, - const char *flag_names, - uint flag_names_length, - grn_obj_flags *index_column_flags) +static bool mrn_parse_grn_index_column_flags(THD *thd, + grn_ctx *ctx, + const char *flag_names, + uint flag_names_length, + grn_obj_flags *index_column_flags) { const char *flag_names_end = flag_names + flag_names_length; bool found = false; @@ -1588,6 +1593,24 @@ static uint mrn_alter_table_flags(uint flags) } #endif +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS +static ha_create_table_option mrn_field_options[] = +{ + HA_FOPTION_STRING("GROONGA_TYPE", groonga_type), + HA_FOPTION_STRING("FLAGS", flags), + HA_FOPTION_END +}; + +static ha_create_table_option mrn_index_options[] = +{ + HA_IOPTION_STRING("TOKENIZER", tokenizer), + HA_IOPTION_STRING("NORMALIZER", normalizer), + HA_IOPTION_STRING("TOKEN_FILTERS", token_filters), + HA_IOPTION_STRING("FLAGS", flags), + HA_IOPTION_END +}; +#endif + static int mrn_init(void *p) { // init handlerton @@ -1606,6 +1629,10 @@ static int mrn_init(void *p) #ifdef MRN_HAVE_HTON_ALTER_TABLE_FLAGS hton->alter_table_flags = mrn_alter_table_flags; #endif +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + hton->field_options = mrn_field_options; + hton->index_options = mrn_index_options; +#endif mrn_hton_ptr = hton; #ifdef _WIN32 @@ -1629,11 +1656,9 @@ static int mrn_init(void *p) (PSI_mutex_key *)GetProcAddress(current_module, MRN_TABLE_SHARE_LOCK_SHARE_PROC); # endif -# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA - mrn_table_share_lock_ha_data = - (PSI_mutex_key *)GetProcAddress(current_module, - MRN_TABLE_SHARE_LOCK_HA_DATA_PROC); -# endif + mrn_table_share_lock_ha_data = + (PSI_mutex_key *)GetProcAddress(current_module, + MRN_TABLE_SHARE_LOCK_HA_DATA_PROC); # endif #else mrn_binlog_filter = binlog_filter; @@ -1790,7 +1815,7 @@ static int mrn_deinit(void *p) mrn::Lock lock(&mrn_allocated_thds_mutex); while ((tmp_thd = (THD *) my_hash_element(&mrn_allocated_thds, 0))) { - mrn_clear_alter_share(tmp_thd); + mrn_clear_slot_data(tmp_thd); void *slot_ptr = mrn_get_slot_data(tmp_thd, false); if (slot_ptr) free(slot_ptr); *thd_ha_data(tmp_thd, mrn_hton_ptr) = (void *) NULL; @@ -2367,10 +2392,10 @@ const char *ha_mroonga::table_type() const const char *ha_mroonga::index_type(uint key_nr) { MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->s->key_info[key_nr]; - if (key_info.algorithm == HA_KEY_ALG_FULLTEXT) { + KEY *key_info = &(table->s->key_info[key_nr]); + if (key_info->algorithm == HA_KEY_ALG_FULLTEXT) { DBUG_RETURN("FULLTEXT"); - } else if (key_info.algorithm == HA_KEY_ALG_HASH) { + } else if (key_info->algorithm == HA_KEY_ALG_HASH) { DBUG_RETURN("HASH"); } else { DBUG_RETURN("BTREE"); @@ -2655,9 +2680,10 @@ ulonglong ha_mroonga::table_flags() const ulong ha_mroonga::wrapper_index_flags(uint idx, uint part, bool all_parts) const { ulong index_flags; - KEY key = table_share->key_info[idx]; + KEY *key = &(table_share->key_info[idx]); MRN_DBUG_ENTER_METHOD(); - if (key.algorithm == HA_KEY_ALG_BTREE || key.algorithm == HA_KEY_ALG_UNDEF) { + if (key->algorithm == HA_KEY_ALG_BTREE || + key->algorithm == HA_KEY_ALG_UNDEF) { MRN_SET_WRAP_SHARE_KEY(share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); index_flags = wrap_handler->index_flags(idx, part, all_parts); @@ -2673,18 +2699,27 @@ ulong ha_mroonga::storage_index_flags(uint idx, uint part, bool all_parts) const { MRN_DBUG_ENTER_METHOD(); ulong flags; - KEY key = table_share->key_info[idx]; - if (key.algorithm == HA_KEY_ALG_BTREE || key.algorithm == HA_KEY_ALG_UNDEF) { + KEY *key = &(table_share->key_info[idx]); + if (key->algorithm == HA_KEY_ALG_BTREE || + key->algorithm == HA_KEY_ALG_UNDEF) { flags = HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE; bool need_normalize_p = false; - Field *field = &key.key_part[part].field[0]; + // TODO: MariaDB 10.1 passes key->user_defined_key_parts as part + // for ORDER BY DESC. We just it fallback to part = 0. We may use + // it for optimization in the future. + // + // See also: test_if_order_by_key() in sql/sql_select.cc. + if (KEY_N_KEY_PARTS(key) == part) { + part = 0; + } + Field *field = &(key->key_part[part].field[0]); if (field && should_normalize(field)) { need_normalize_p = true; } if (!need_normalize_p) { flags |= HA_KEYREAD_ONLY; } - if (KEY_N_KEY_PARTS(&key) > 1 || !need_normalize_p) { + if (KEY_N_KEY_PARTS(key) > 1 || !need_normalize_p) { flags |= HA_READ_ORDER; } } else { @@ -2697,11 +2732,11 @@ ulong ha_mroonga::index_flags(uint idx, uint part, bool all_parts) const { MRN_DBUG_ENTER_METHOD(); - KEY key = table_share->key_info[idx]; - if (key.algorithm == HA_KEY_ALG_FULLTEXT) { + KEY *key = &(table_share->key_info[idx]); + if (key->algorithm == HA_KEY_ALG_FULLTEXT) { DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR); } - if (mrn_is_geo_key(&key)) { + if (mrn_is_geo_key(key)) { DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR); } @@ -2833,9 +2868,23 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table, share = tmp_share; MRN_SET_WRAP_SHARE_KEY(tmp_share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); - if (!(hnd = - tmp_share->hton->create(tmp_share->hton, table->s, - current_thd->mem_root))) +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + if (parse_engine_table_options(ha_thd(), tmp_share->hton, table->s)) { + MRN_SET_BASE_SHARE_KEY(tmp_share, table->s); + MRN_SET_BASE_TABLE_KEY(this, table); + share = NULL; + if (wrap_key_info) + { + my_free(wrap_key_info); + wrap_key_info = NULL; + } + base_key_info = NULL; + error = MRN_GET_ERROR_NUMBER; + DBUG_RETURN(error); + } +#endif + hnd = get_new_handler(table->s, current_thd->mem_root, tmp_share->hton); + if (!hnd) { MRN_SET_BASE_SHARE_KEY(tmp_share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); @@ -2848,7 +2897,6 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table, base_key_info = NULL; DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - hnd->init(); error = hnd->ha_create(name, table, info); MRN_SET_BASE_SHARE_KEY(tmp_share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); @@ -2856,7 +2904,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table, delete hnd; if (error) { - wrapper_delete_index(name, tmp_share, mapper.table_name()); + generic_delete_table(name, mapper.table_name()); } if (wrap_key_info) @@ -2949,8 +2997,7 @@ int ha_mroonga::wrapper_create_index_fulltext(const char *grn_table_name, mrn_change_encoding(ctx, system_charset_info); index_tables[i] = index_table; - grn_obj *tokenizer = find_tokenizer(tmp_share->key_parser[i], - tmp_share->key_parser_length[i]); + grn_obj *tokenizer = find_tokenizer(key_info, tmp_share, i); if (tokenizer) { grn_info_type info_type = GRN_INFO_DEFAULT_TOKENIZER; grn_obj_set_info(ctx, index_table, info_type, tokenizer); @@ -3097,14 +3144,14 @@ int ha_mroonga::wrapper_create_index(const char *name, TABLE *table, for (i = 0; i < n_keys; i++) { index_tables[i] = NULL; - KEY key_info = table->s->key_info[i]; - if (key_info.algorithm == HA_KEY_ALG_FULLTEXT) { + KEY *key_info = &(table->s->key_info[i]); + if (key_info->algorithm == HA_KEY_ALG_FULLTEXT) { error = wrapper_create_index_fulltext(grn_table_name, - i, &key_info, + i, key_info, index_tables, NULL, tmp_share); - } else if (mrn_is_geo_key(&key_info)) { + } else if (mrn_is_geo_key(key_info)) { error = wrapper_create_index_geo(grn_table_name, - i, &key_info, + i, key_info, index_tables, NULL, tmp_share); } } @@ -3160,12 +3207,12 @@ int ha_mroonga::storage_create(const char *name, TABLE *table, grn_obj *pkey_type; uint pkey_nr = table->s->primary_key; if (pkey_nr != MAX_INDEXES) { - KEY key_info = table->s->key_info[pkey_nr]; + KEY *key_info = &(table->s->key_info[pkey_nr]); bool is_id; - int key_parts = KEY_N_KEY_PARTS(&key_info); + int key_parts = KEY_N_KEY_PARTS(key_info); if (key_parts == 1) { - Field *pkey_field = key_info.key_part[0].field; + Field *pkey_field = key_info->key_part[0].field; const char *column_name = pkey_field->field_name; is_id = (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0); @@ -3177,7 +3224,7 @@ int ha_mroonga::storage_create(const char *name, TABLE *table, } // default algorithm is BTREE ==> PAT - if (!is_id && key_info.algorithm == HA_KEY_ALG_HASH) { + if (!is_id && key_info->algorithm == HA_KEY_ALG_HASH) { table_flags |= GRN_OBJ_TABLE_HASH_KEY; } else if (!is_id) { table_flags |= GRN_OBJ_TABLE_PAT_KEY; @@ -3212,8 +3259,8 @@ int ha_mroonga::storage_create(const char *name, TABLE *table, if (table_flags == (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_PAT_KEY) || table_flags == (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_HASH_KEY)) { - KEY key_info = table->s->key_info[pkey_nr]; - int key_parts = KEY_N_KEY_PARTS(&key_info); + KEY *key_info = &(table->s->key_info[pkey_nr]); + int key_parts = KEY_N_KEY_PARTS(key_info); if (key_parts == 1) { grn_obj *normalizer = NULL; if (tmp_share->normalizer) { @@ -3221,9 +3268,9 @@ int ha_mroonga::storage_create(const char *name, TABLE *table, tmp_share->normalizer, tmp_share->normalizer_length); } else { - Field *field = &(key_info.key_part->field[0]); + Field *field = &(key_info->key_part->field[0]); if (should_normalize(field)) { - normalizer = find_normalizer(&key_info); + normalizer = find_normalizer(key_info); } } if (normalizer) { @@ -3259,7 +3306,6 @@ int ha_mroonga::storage_create(const char *name, TABLE *table, /* create columns */ uint n_columns = table->s->fields; for (uint i = 0; i < n_columns; i++) { - grn_obj *col_type; Field *field = table->s->field[i]; const char *column_name = field->field_name; int column_name_size = strlen(column_name); @@ -3280,19 +3326,18 @@ int ha_mroonga::storage_create(const char *name, TABLE *table, #endif grn_obj_flags col_flags = GRN_OBJ_PERSISTENT; - if (tmp_share->col_flags[i]) { - col_flags |= mrn_parse_grn_column_create_flags(ha_thd(), - ctx, - tmp_share->col_flags[i], - tmp_share->col_flags_length[i]); - } else { + if (!find_column_flags(field, tmp_share, i, &col_flags)) { col_flags |= GRN_OBJ_COLUMN_SCALAR; } - grn_builtin_type gtype = mrn_grn_type_from_field(ctx, field, false); - if (tmp_share->col_type[i]) { - col_type = grn_ctx_get(ctx, tmp_share->col_type[i], -1); - } else { - col_type = grn_ctx_at(ctx, gtype); + + grn_obj *col_type; + { + int column_type_error_code = ER_CANT_CREATE_TABLE; + col_type = find_column_type(field, tmp_share, i, column_type_error_code); + if (!col_type) { + grn_obj_remove(ctx, table_obj); + DBUG_RETURN(column_type_error_code); + } } char *col_path = NULL; // we don't specify path @@ -3445,17 +3490,11 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table, DBUG_RETURN(false); } -#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()), mapper.mysql_table_name(), strlen(mapper.mysql_table_name()), mapper.mysql_table_name(), TL_WRITE); -#else - table_list.init_one_table(mapper.db_name(), - mapper.mysql_table_name(), - TL_WRITE); -#endif mrn_open_mutex_lock(table->s); tmp_ref_table_share = mrn_create_tmp_table_share(&table_list, ref_path, &error); @@ -3572,16 +3611,16 @@ int ha_mroonga::storage_create_validate_index(TABLE *table) /* checking if index is used for virtual columns */ uint n_keys = table->s->keys; for (i = 0; i < n_keys; i++) { - KEY key_info = table->s->key_info[i]; + KEY *key_info = &(table->s->key_info[i]); // must be single column key - int key_parts = KEY_N_KEY_PARTS(&key_info); + int key_parts = KEY_N_KEY_PARTS(key_info); if (key_parts != 1) { continue; } - Field *field = key_info.key_part[0].field; + Field *field = key_info->key_part[0].field; const char *column_name = field->field_name; if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) { - if (key_info.algorithm == HA_KEY_ALG_HASH) { + if (key_info->algorithm == HA_KEY_ALG_HASH) { continue; // hash index is ok } GRN_LOG(ctx, GRN_LOG_ERROR, "only hash index can be defined for _id"); @@ -3660,8 +3699,7 @@ int ha_mroonga::storage_create_index_table(TABLE *table, } if (key_info->flags & HA_FULLTEXT) { - grn_obj *tokenizer = find_tokenizer(tmp_share->key_parser[i], - tmp_share->key_parser_length[i]); + grn_obj *tokenizer = find_tokenizer(key_info, tmp_share, i); if (tokenizer) { grn_info_type info_type = GRN_INFO_DEFAULT_TOKENIZER; grn_obj_set_info(ctx, index_table, info_type, tokenizer); @@ -3909,6 +3947,8 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info) if (error) { mrn_free_long_term_share(tmp_share->long_term_share); tmp_share->long_term_share = NULL; + } else { + error = add_wrap_hton(tmp_share->table_name, tmp_share->hton); } mrn_free_share(tmp_share); DBUG_RETURN(error); @@ -3956,8 +3996,8 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked) MRN_SET_WRAP_TABLE_KEY(this, table); if (!is_clone) { - if (!(wrap_handler = - share->hton->create(share->hton, table->s, &mem_root))) + wrap_handler = get_new_handler(table->s, &mem_root, share->hton); + if (!wrap_handler) { MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); @@ -3969,19 +4009,13 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked) base_key_info = NULL; DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - wrap_handler->init(); #ifdef MRN_HANDLER_HAVE_SET_HA_SHARE_REF wrap_handler->set_ha_share_ref(&table->s->ha_share); #endif error = wrap_handler->ha_open(table, name, mode, test_if_locked); } else { -#ifdef MRN_HANDLER_CLONE_NEED_NAME if (!(wrap_handler = parent_for_clone->wrap_handler->clone(name, mem_root_for_clone))) -#else - if (!(wrap_handler = parent_for_clone->wrap_handler->clone( - mem_root_for_clone))) -#endif { MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); @@ -4047,12 +4081,12 @@ int ha_mroonga::wrapper_open_indexes(const char *name) mrn::PathMapper mapper(name); uint i = 0; for (i = 0; i < n_keys; i++) { - KEY key_info = table->s->key_info[i]; + KEY *key_info = &(table->s->key_info[i]); grn_index_tables[i] = NULL; grn_index_columns[i] = NULL; - if (!(wrapper_is_target_index(&key_info))) { + if (!(wrapper_is_target_index(key_info))) { continue; } @@ -4060,7 +4094,7 @@ int ha_mroonga::wrapper_open_indexes(const char *name) continue; } - mrn::IndexTableName index_table_name(mapper.table_name(), key_info.name); + mrn::IndexTableName index_table_name(mapper.table_name(), key_info->name); grn_index_tables[i] = grn_ctx_get(ctx, index_table_name.c_str(), index_table_name.length()); @@ -4077,7 +4111,7 @@ int ha_mroonga::wrapper_open_indexes(const char *name) strlen(INDEX_COLUMN_NAME)); if (!grn_index_columns[i]) { /* just for backward compatibility before 1.0. */ - Field *field = key_info.key_part[0].field; + Field *field = key_info->key_part[0].field; grn_index_columns[i] = grn_obj_column(ctx, grn_index_tables[i], field->field_name, strlen(field->field_name)); @@ -4337,10 +4371,10 @@ int ha_mroonga::storage_open_indexes(const char *name) continue; } - KEY key_info = table->s->key_info[i]; - if (KEY_N_KEY_PARTS(&key_info) > 1) { - KEY_PART_INFO *key_part = key_info.key_part; - for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { + KEY *key_info = &(table->s->key_info[i]); + if (KEY_N_KEY_PARTS(key_info) > 1) { + KEY_PART_INFO *key_part = key_info->key_part; + for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { bitmap_set_bit(&multiple_column_key_bitmap, key_part[j].field->field_index); } @@ -4355,11 +4389,11 @@ int ha_mroonga::storage_open_indexes(const char *name) if (ctx->rc == GRN_SUCCESS) { grn_index_columns[i] = grn_obj_column(ctx, grn_index_tables[i], - key_info.name, - strlen(key_info.name)); + key_info->name, + strlen(key_info->name)); } } else { - mrn::IndexTableName index_table_name(mapper.table_name(), key_info.name); + mrn::IndexTableName index_table_name(mapper.table_name(), key_info->name); grn_index_tables[i] = grn_ctx_get(ctx, index_table_name.c_str(), index_table_name.length()); @@ -4370,7 +4404,7 @@ int ha_mroonga::storage_open_indexes(const char *name) strlen(INDEX_COLUMN_NAME)); if (!grn_index_columns[i] && ctx->rc == GRN_SUCCESS) { /* just for backward compatibility before 1.0. */ - Field *field = key_info.key_part[0].field; + Field *field = key_info->key_part[0].field; grn_index_columns[i] = grn_obj_column(ctx, grn_index_tables[i], field->field_name, strlen(field->field_name)); @@ -4504,40 +4538,20 @@ int ha_mroonga::close() error = storage_close(); } - if (is_temporary_table_name(share->table_name)) { - TABLE_LIST table_list; - TABLE_SHARE *tmp_table_share; - int tmp_error; - /* no need to decode */ - mrn::PathMapper mapper(share->table_name); -#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS - table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()), - mapper.mysql_table_name(), - strlen(mapper.mysql_table_name()), - mapper.mysql_table_name(), - TL_WRITE); -#else - table_list.init_one_table(mapper.db_name(), mapper.mysql_table_name(), - TL_WRITE); -#endif - mrn_open_mutex_lock(NULL); - tmp_table_share = - mrn_create_tmp_table_share(&table_list, share->table_name, &tmp_error); - mrn_open_mutex_unlock(NULL); - if (!tmp_table_share) { - error = tmp_error; - } else if ((tmp_error = alter_share_add(share->table_name, - tmp_table_share))) { - error = tmp_error; - mrn_open_mutex_lock(NULL); - mrn_free_tmp_table_share(tmp_table_share); - mrn_open_mutex_unlock(NULL); - } + if (error != 0) + { + DBUG_RETURN(error); } + + error = add_wrap_hton(share->table_name, share->hton); bitmap_free(&multiple_column_key_bitmap); + if (share->use_count == 1) { + mrn_free_long_term_share(share->long_term_share); + } mrn_free_share(share); share = NULL; is_clone = false; + if ( thd && thd_sql_command(thd) == SQLCOM_FLUSH @@ -4554,76 +4568,28 @@ int ha_mroonga::close() DBUG_RETURN(error); } -int ha_mroonga::wrapper_delete_table(const char *name, MRN_SHARE *tmp_share, +int ha_mroonga::wrapper_delete_table(const char *name, + handlerton *wrap_handlerton, const char *table_name) { int error = 0; - handler *hnd; MRN_DBUG_ENTER_METHOD(); - MRN_SET_WRAP_SHARE_KEY(tmp_share, tmp_share->table_share); - if (!(hnd = - tmp_share->hton->create(tmp_share->hton, tmp_share->table_share, - current_thd->mem_root))) - { - MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share); - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - hnd->init(); - MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share); - if ((error = hnd->ha_delete_table(name))) + handler *hnd = get_new_handler(NULL, current_thd->mem_root, wrap_handlerton); + if (!hnd) { - delete hnd; - DBUG_RETURN(error); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - error = wrapper_delete_index(name, tmp_share, table_name); - + error = hnd->ha_delete_table(name); delete hnd; - DBUG_RETURN(error); -} - -int ha_mroonga::wrapper_delete_index(const char *name, MRN_SHARE *tmp_share, - const char *table_name) -{ - int error = 0; - MRN_DBUG_ENTER_METHOD(); - - error = ensure_database_open(name); - if (error) - DBUG_RETURN(error); - - error = mrn_change_encoding(ctx, system_charset_info); - if (error) - DBUG_RETURN(error); - TABLE_SHARE *tmp_table_share = tmp_share->table_share; - - uint i; - for (i = 0; i < tmp_table_share->keys; i++) { - error = drop_index(tmp_share, i); - if (error) { - DBUG_RETURN(error); - } - } - - grn_obj *table = grn_ctx_get(ctx, table_name, strlen(table_name)); - if (!ctx->rc) { - grn_obj_remove(ctx, table); - } - if (ctx->rc) { - error = ER_CANT_OPEN_FILE; - my_message(error, ctx->errbuf, MYF(0)); - DBUG_RETURN(error); - } DBUG_RETURN(error); } -int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share, - const char *table_name) +int ha_mroonga::generic_delete_table(const char *name, const char *table_name) { int error = 0; - TABLE_SHARE *tmp_table_share = tmp_share->table_share; MRN_DBUG_ENTER_METHOD(); error = ensure_database_open(name); @@ -4634,14 +4600,7 @@ int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share, if (error) DBUG_RETURN(error); - uint i; - for (i = 0; i < tmp_table_share->keys; i++) { - error = drop_index(tmp_share, i); - if (error) { - DBUG_RETURN(error); - } - } - + error = drop_indexes(table_name); grn_obj *table_obj = grn_ctx_get(ctx, table_name, strlen(table_name)); if (!ctx->rc) { grn_obj_remove(ctx, table_obj); @@ -4656,86 +4615,50 @@ int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share, int ha_mroonga::delete_table(const char *name) { + MRN_DBUG_ENTER_METHOD(); + int error = 0; THD *thd = ha_thd(); - TABLE_LIST table_list; - TABLE_SHARE *tmp_table_share = NULL; - TABLE tmp_table; - MRN_SHARE *tmp_share; - st_mrn_alter_share *alter_share, *tmp_alter_share; - MRN_DBUG_ENTER_METHOD(); + handlerton *wrap_handlerton = NULL; mrn::PathMapper mapper(name); st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, false); - if (slot_data && slot_data->first_alter_share) + if (slot_data && slot_data->first_wrap_hton) { - tmp_alter_share = NULL; - alter_share = slot_data->first_alter_share; - while (alter_share) + st_mrn_wrap_hton *wrap_hton, *tmp_wrap_hton; + tmp_wrap_hton = NULL; + wrap_hton = slot_data->first_wrap_hton; + while (wrap_hton) { - if (!strcmp(alter_share->path, name)) + if (!strcmp(wrap_hton->path, name)) { /* found */ - tmp_table_share = alter_share->alter_share; - if (tmp_alter_share) - tmp_alter_share->next = alter_share->next; + wrap_handlerton = wrap_hton->hton; + if (tmp_wrap_hton) + tmp_wrap_hton->next = wrap_hton->next; else - slot_data->first_alter_share = alter_share->next; - free(alter_share); + slot_data->first_wrap_hton = wrap_hton->next; + free(wrap_hton); break; } - tmp_alter_share = alter_share; - alter_share = alter_share->next; + tmp_wrap_hton = wrap_hton; + wrap_hton = wrap_hton->next; } } - if (!tmp_table_share) - { -#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS - table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()), - mapper.mysql_table_name(), - strlen(mapper.mysql_table_name()), - mapper.mysql_table_name(), - TL_WRITE); -#else - table_list.init_one_table(mapper.db_name(), mapper.mysql_table_name(), - TL_WRITE); -#endif - mrn_open_mutex_lock(NULL); - tmp_table_share = mrn_create_tmp_table_share(&table_list, name, &error); - mrn_open_mutex_unlock(NULL); - if (!tmp_table_share) { - DBUG_RETURN(error); - } - } - tmp_table.s = tmp_table_share; -#ifdef WITH_PARTITION_STORAGE_ENGINE - tmp_table.part_info = NULL; -#endif - if (!(tmp_share = mrn_get_share(name, &tmp_table, &error))) + + if (wrap_handlerton) { - mrn_open_mutex_lock(NULL); - mrn_free_tmp_table_share(tmp_table_share); - mrn_open_mutex_unlock(NULL); - DBUG_RETURN(error); + error = wrapper_delete_table(name, wrap_handlerton, mapper.table_name()); } - if (tmp_share->wrapper_mode) + if (!error) { - error = wrapper_delete_table(name, tmp_share, mapper.table_name()); - } else { - error = storage_delete_table(name, tmp_share, mapper.table_name()); + error = generic_delete_table(name, mapper.table_name()); } - if (!error) { - mrn_free_long_term_share(tmp_share->long_term_share); - tmp_share->long_term_share = NULL; - } - mrn_free_share(tmp_share); - mrn_open_mutex_lock(NULL); - mrn_free_tmp_table_share(tmp_table_share); - mrn_open_mutex_unlock(NULL); - if (is_temporary_table_name(name)) { + if (!error && is_temporary_table_name(name)) { mrn_db_manager->drop(name); } + DBUG_RETURN(error); } @@ -5331,9 +5254,9 @@ bool ha_mroonga::wrapper_have_target_index() uint i; uint n_keys = table->s->keys; for (i = 0; i < n_keys; i++) { - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (wrapper_is_target_index(&key_info)) { + if (wrapper_is_target_index(key_info)) { have_target_index = true; break; } @@ -5406,9 +5329,9 @@ int ha_mroonga::wrapper_write_row_index(uchar *buf) uint i; uint n_keys = table->s->keys; for (i = 0; i < n_keys; i++) { - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (!(wrapper_is_target_index(&key_info))) { + if (!(wrapper_is_target_index(key_info))) { continue; } @@ -5418,8 +5341,8 @@ int ha_mroonga::wrapper_write_row_index(uchar *buf) } uint j; - for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { - Field *field = key_info.key_part[j].field; + for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { + Field *field = key_info->key_part[j].field; if (field->is_null()) continue; @@ -5481,7 +5404,8 @@ int ha_mroonga::storage_write_row(uchar *buf) if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) { push_warning_printf(thd, MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED), + WARN_DATA_TRUNCATED, + MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED), MRN_COLUMN_NAME_ID, MRN_GET_CURRENT_ROW_FOR_WARNING(thd)); if (MRN_ABORT_ON_WARNING(thd)) { @@ -5490,66 +5414,79 @@ int ha_mroonga::storage_write_row(uchar *buf) } } - char *pkey; - int pkey_size; - uint pkey_nr; - pkey_nr = table->s->primary_key; - GRN_BULK_REWIND(&key_buffer); - if (pkey_nr == MAX_INDEXES) { - pkey = NULL; - pkey_size = 0; - } else { - KEY key_info = table->key_info[pkey_nr]; - if (KEY_N_KEY_PARTS(&key_info) == 1) { - Field *pkey_field = key_info.key_part[0].field; - error = mrn_change_encoding(ctx, pkey_field->charset()); - if (error) { - DBUG_RETURN(error); - } - generic_store_bulk(pkey_field, &key_buffer); - pkey = GRN_TEXT_VALUE(&key_buffer); - pkey_size = GRN_TEXT_LEN(&key_buffer); - } else { - mrn_change_encoding(ctx, NULL); - uchar key[MRN_MAX_KEY_SIZE]; - key_copy(key, buf, &key_info, key_info.key_length); - grn_bulk_space(ctx, &key_buffer, key_info.key_length); - pkey = GRN_TEXT_VALUE(&key_buffer); - storage_encode_multiple_column_key(&key_info, - key, key_info.key_length, - (uchar *)pkey, (uint *)&pkey_size); + uint pkey_nr = table->s->primary_key; + + int added = 0; + { + mrn::Lock lock(&(share->record_mutex), have_unique_index()); + if ((error = storage_write_row_unique_indexes(buf))) + { + DBUG_RETURN(error); } - } + unique_indexes_are_processed = true; - if (grn_table->header.type != GRN_TABLE_NO_KEY && pkey_size == 0) { - my_message(ER_ERROR_ON_WRITE, "primary key is empty", MYF(0)); - DBUG_RETURN(ER_ERROR_ON_WRITE); - } + char *pkey; + int pkey_size; + GRN_BULK_REWIND(&key_buffer); + if (pkey_nr == MAX_INDEXES) { + pkey = NULL; + pkey_size = 0; + } else { + KEY *key_info = &(table->key_info[pkey_nr]); + if (KEY_N_KEY_PARTS(key_info) == 1) { + Field *pkey_field = key_info->key_part[0].field; + error = mrn_change_encoding(ctx, pkey_field->charset()); + if (error) { + DBUG_RETURN(error); + } + generic_store_bulk(pkey_field, &key_buffer); + pkey = GRN_TEXT_VALUE(&key_buffer); + pkey_size = GRN_TEXT_LEN(&key_buffer); + } else { + mrn_change_encoding(ctx, NULL); + uchar key[MRN_MAX_KEY_SIZE]; + key_copy(key, buf, key_info, key_info->key_length); + grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE); + pkey = GRN_TEXT_VALUE(&key_buffer); + storage_encode_multiple_column_key(key_info, + key, key_info->key_length, + (uchar *)pkey, (uint *)&pkey_size); + } + } - int added; - record_id = grn_table_add(ctx, grn_table, pkey, pkey_size, &added); - if (ctx->rc) { - my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0)); - DBUG_RETURN(ER_ERROR_ON_WRITE); - } - if (!added) { - // duplicated error - error = HA_ERR_FOUND_DUPP_KEY; - memcpy(dup_ref, &record_id, sizeof(grn_id)); - dup_key = pkey_nr; - if (!ignoring_duplicated_key) { - GRN_LOG(ctx, GRN_LOG_ERROR, - "duplicated id on insert: update primary key: <%.*s>", - pkey_size, pkey); + if (grn_table->header.type != GRN_TABLE_NO_KEY && pkey_size == 0) { + my_message(ER_ERROR_ON_WRITE, "primary key is empty", MYF(0)); + DBUG_RETURN(ER_ERROR_ON_WRITE); } - DBUG_RETURN(error); - } - if ((error = storage_write_row_unique_indexes(buf))) - { - goto err; + record_id = grn_table_add(ctx, grn_table, pkey, pkey_size, &added); + if (ctx->rc) { + my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0)); + DBUG_RETURN(ER_ERROR_ON_WRITE); + } + if (!added) { + // duplicated error + error = HA_ERR_FOUND_DUPP_KEY; + memcpy(dup_ref, &record_id, sizeof(grn_id)); + dup_key = pkey_nr; + if (!ignoring_duplicated_key) { + GRN_LOG(ctx, GRN_LOG_ERROR, + "duplicated id on insert: update primary key: <%.*s>", + pkey_size, pkey); + } + uint j; + for (j = 0; j < table->s->keys; j++) { + if (j == pkey_nr) { + continue; + } + KEY *key_info = &table->key_info[j]; + if (key_info->flags & HA_NOSAME) { + grn_table_delete_by_id(ctx, grn_index_tables[j], key_id[j]); + } + } + DBUG_RETURN(error); + } } - unique_indexes_are_processed = true; grn_obj colbuf; GRN_VOID_INIT(&colbuf); @@ -5673,16 +5610,16 @@ int ha_mroonga::storage_write_row_multiple_column_index(uchar *buf, key_info, key_info->key_length); GRN_BULK_REWIND(&encoded_key_buffer); - grn_bulk_space(ctx, &encoded_key_buffer, key_info->key_length); + grn_bulk_reserve(ctx, &encoded_key_buffer, MRN_MAX_KEY_SIZE); uint encoded_key_length; storage_encode_multiple_column_key(key_info, (uchar *)(GRN_TEXT_VALUE(&key_buffer)), key_info->key_length, (uchar *)(GRN_TEXT_VALUE(&encoded_key_buffer)), &encoded_key_length); + grn_bulk_space(ctx, &encoded_key_buffer, encoded_key_length); DBUG_PRINT("info", ("mroonga: key_length=%u", key_info->key_length)); DBUG_PRINT("info", ("mroonga: encoded_key_length=%u", encoded_key_length)); - DBUG_ASSERT(key_info->key_length >= encoded_key_length); grn_rc rc; rc = grn_column_index_update(ctx, index_column, record_id, 1, NULL, @@ -5709,9 +5646,9 @@ int ha_mroonga::storage_write_row_multiple_column_indexes(uchar *buf, continue; } - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) { + if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) { continue; } @@ -5722,7 +5659,7 @@ int ha_mroonga::storage_write_row_multiple_column_indexes(uchar *buf, if ((error = storage_write_row_multiple_column_index(buf, record_id, - &key_info, + key_info, index_column))) { goto err; @@ -5757,7 +5694,7 @@ int ha_mroonga::storage_write_row_unique_index(uchar *buf, mrn_change_encoding(ctx, NULL); uchar key[MRN_MAX_KEY_SIZE]; key_copy(key, buf, key_info, key_info->key_length); - grn_bulk_space(ctx, &key_buffer, key_info->key_length); + grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE); ukey = GRN_TEXT_VALUE(&key_buffer); storage_encode_multiple_column_key(key_info, key, key_info->key_length, @@ -5949,11 +5886,11 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data) } mrn_change_encoding(ctx, NULL); - KEY key_info = table->key_info[table_share->primary_key]; + KEY *key_info = &(table->key_info[table_share->primary_key]); GRN_BULK_REWIND(&key_buffer); key_copy((uchar *)(GRN_TEXT_VALUE(&key_buffer)), new_data, - &key_info, key_info.key_length); + key_info, key_info->key_length); int added; grn_id new_record_id; new_record_id = grn_table_add(ctx, grn_table, @@ -5972,15 +5909,15 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data) grn_id old_record_id; my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(old_data, table->record[0]); - for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { - Field *field = key_info.key_part[j].field; + for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { + Field *field = key_info->key_part[j].field; field->move_field_offset(ptr_diff); } error = wrapper_get_record_id((uchar *)old_data, &old_record_id, "failed to get old record ID " "for updating from groonga"); - for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { - Field *field = key_info.key_part[j].field; + for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { + Field *field = key_info->key_part[j].field; field->move_field_offset(-ptr_diff); } if (error) { @@ -5991,9 +5928,9 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data) uint i; uint n_keys = table->s->keys; for (i = 0; i < n_keys; i++) { - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (!(wrapper_is_target_index(&key_info))) { + if (!(wrapper_is_target_index(key_info))) { continue; } @@ -6004,8 +5941,8 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data) } uint j; - for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { - Field *field = key_info.key_part[j].field; + for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { + Field *field = key_info->key_part[j].field; generic_store_bulk(field, &new_value_buffer); @@ -6086,6 +6023,7 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data) KEY *pkey_info = NULL; storage_store_fields_for_prep_update(old_data, new_data, record_id); { + mrn::Lock lock(&(share->record_mutex), have_unique_index()); mrn::DebugColumnAccess debug_column_access(table, table->read_set); if ((error = storage_prepare_delete_row_unique_indexes(old_data, record_id))) { @@ -6233,9 +6171,9 @@ int ha_mroonga::storage_update_row_index(const uchar *old_data, uchar *new_data) continue; } - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) { + if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) { continue; } @@ -6246,42 +6184,44 @@ int ha_mroonga::storage_update_row_index(const uchar *old_data, uchar *new_data) } GRN_BULK_REWIND(&old_key); - grn_bulk_space(ctx, &old_key, key_info.key_length); - for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { - Field *field = key_info.key_part[j].field; + grn_bulk_space(ctx, &old_key, key_info->key_length); + for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { + Field *field = key_info->key_part[j].field; field->move_field_offset(ptr_diff); } key_copy((uchar *)(GRN_TEXT_VALUE(&old_key)), (uchar *)old_data, - &key_info, - key_info.key_length); - for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { - Field *field = key_info.key_part[j].field; + key_info, + key_info->key_length); + for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { + Field *field = key_info->key_part[j].field; field->move_field_offset(-ptr_diff); } GRN_BULK_REWIND(&old_encoded_key); - grn_bulk_space(ctx, &old_encoded_key, key_info.key_length); + grn_bulk_reserve(ctx, &old_encoded_key, MRN_MAX_KEY_SIZE); uint old_encoded_key_length; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, (uchar *)(GRN_TEXT_VALUE(&old_key)), - key_info.key_length, + key_info->key_length, (uchar *)(GRN_TEXT_VALUE(&old_encoded_key)), &old_encoded_key_length); + grn_bulk_space(ctx, &old_encoded_key, old_encoded_key_length); GRN_BULK_REWIND(&new_key); - grn_bulk_space(ctx, &new_key, key_info.key_length); + grn_bulk_space(ctx, &new_key, key_info->key_length); key_copy((uchar *)(GRN_TEXT_VALUE(&new_key)), (uchar *)new_data, - &key_info, - key_info.key_length); + key_info, + key_info->key_length); GRN_BULK_REWIND(&new_encoded_key); - grn_bulk_space(ctx, &new_encoded_key, key_info.key_length); + grn_bulk_reserve(ctx, &new_encoded_key, MRN_MAX_KEY_SIZE); uint new_encoded_key_length; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, (uchar *)(GRN_TEXT_VALUE(&new_key)), - key_info.key_length, + key_info->key_length, (uchar *)(GRN_TEXT_VALUE(&new_encoded_key)), &new_encoded_key_length); + grn_bulk_space(ctx, &new_encoded_key, new_encoded_key_length); grn_rc rc; rc = grn_column_index_update(ctx, index_column, record_id, 1, @@ -6436,9 +6376,9 @@ int ha_mroonga::wrapper_delete_row_index(const uchar *buf) uint i; uint n_keys = table->s->keys; for (i = 0; i < n_keys; i++) { - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (!(wrapper_is_target_index(&key_info))) { + if (!(wrapper_is_target_index(key_info))) { continue; } @@ -6449,8 +6389,8 @@ int ha_mroonga::wrapper_delete_row_index(const uchar *buf) } uint j; - for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { - Field *field = key_info.key_part[j].field; + for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { + Field *field = key_info->key_part[j].field; if (field->is_null()) continue; @@ -6487,20 +6427,23 @@ int ha_mroonga::storage_delete_row(const uchar *buf) } storage_store_fields_for_prep_update(buf, NULL, record_id); - if ((error = storage_prepare_delete_row_unique_indexes(buf, record_id))) { - DBUG_RETURN(error); - } - mrn_change_encoding(ctx, NULL); - grn_table_delete_by_id(ctx, grn_table, record_id); - if (ctx->rc) { - my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0)); - DBUG_RETURN(ER_ERROR_ON_WRITE); - } - if ( - (error = storage_delete_row_index(buf)) || - (error = storage_delete_row_unique_indexes()) - ) { - DBUG_RETURN(error); + { + mrn::Lock lock(&(share->record_mutex), have_unique_index()); + if ((error = storage_prepare_delete_row_unique_indexes(buf, record_id))) { + DBUG_RETURN(error); + } + mrn_change_encoding(ctx, NULL); + grn_table_delete_by_id(ctx, grn_table, record_id); + if (ctx->rc) { + my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0)); + DBUG_RETURN(ER_ERROR_ON_WRITE); + } + if ( + (error = storage_delete_row_index(buf)) || + (error = storage_delete_row_unique_indexes()) + ) { + DBUG_RETURN(error); + } } grn_db_touch(ctx, grn_ctx_db(ctx)); @@ -6526,9 +6469,9 @@ int ha_mroonga::storage_delete_row_index(const uchar *buf) continue; } - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) { + if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) { continue; } @@ -6539,19 +6482,20 @@ int ha_mroonga::storage_delete_row_index(const uchar *buf) } GRN_BULK_REWIND(&key); - grn_bulk_space(ctx, &key, key_info.key_length); + grn_bulk_space(ctx, &key, key_info->key_length); key_copy((uchar *)(GRN_TEXT_VALUE(&key)), (uchar *)buf, - &key_info, - key_info.key_length); + key_info, + key_info->key_length); GRN_BULK_REWIND(&encoded_key); - grn_bulk_space(ctx, &encoded_key, key_info.key_length); + grn_bulk_reserve(ctx, &encoded_key, MRN_MAX_KEY_SIZE); uint encoded_key_length; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, (uchar *)(GRN_TEXT_VALUE(&key)), - key_info.key_length, + key_info->key_length, (uchar *)(GRN_TEXT_VALUE(&encoded_key)), &encoded_key_length); + grn_bulk_space(ctx, &encoded_key, encoded_key_length); grn_rc rc; rc = grn_column_index_update(ctx, index_column, record_id, 1, @@ -6627,7 +6571,7 @@ int ha_mroonga::storage_prepare_delete_row_unique_index(const uchar *buf, mrn_change_encoding(ctx, NULL); uchar key[MRN_MAX_KEY_SIZE]; key_copy(key, (uchar *) buf, key_info, key_info->key_length); - grn_bulk_space(ctx, &key_buffer, key_info->key_length); + grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE); ukey = GRN_TEXT_VALUE(&key_buffer); storage_encode_multiple_column_key(key_info, key, key_info->key_length, @@ -6737,8 +6681,8 @@ ha_rows ha_mroonga::wrapper_records_in_range(uint key_nr, key_range *range_min, { ha_rows row_count; MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->s->key_info[key_nr]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->s->key_info[key_nr]); + if (mrn_is_geo_key(key_info)) { row_count = generic_records_in_range_geo(key_nr, range_min, range_max); } else { MRN_SET_WRAP_SHARE_KEY(share, table->s); @@ -6760,8 +6704,8 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min, uchar *key_min = NULL, *key_max = NULL; uchar key_min_entity[MRN_MAX_KEY_SIZE]; uchar key_max_entity[MRN_MAX_KEY_SIZE]; - KEY key_info = table->s->key_info[key_nr]; - bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1; + KEY *key_info = &(table->s->key_info[key_nr]); + bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1; if (is_multiple_column_index) { mrn_change_encoding(ctx, NULL); @@ -6770,24 +6714,23 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min, memcmp(range_min->key, range_max->key, range_min->length) == 0) { flags |= GRN_CURSOR_PREFIX; key_min = key_min_entity; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, range_min->key, range_min->length, key_min, &size_min); } else { key_min = key_min_entity; key_max = key_max_entity; - storage_encode_multiple_column_key_range(&key_info, + storage_encode_multiple_column_key_range(key_info, range_min, range_max, key_min, &size_min, key_max, &size_max); } - } else if (mrn_is_geo_key(&key_info)) { - mrn_change_encoding(ctx, key_info.key_part->field->charset()); + } else if (mrn_is_geo_key(key_info)) { + mrn_change_encoding(ctx, key_info->key_part->field->charset()); row_count = generic_records_in_range_geo(key_nr, range_min, range_max); DBUG_RETURN(row_count); } else { - KEY_PART_INFO key_part = key_info.key_part[0]; - Field *field = key_part.field; + Field *field = key_info->key_part[0].field; const char *column_name = field->field_name; mrn_change_encoding(ctx, field->charset()); @@ -6909,12 +6852,12 @@ ha_rows ha_mroonga::records_in_range(uint key_nr, key_range *range_min, key_rang int ha_mroonga::wrapper_index_init(uint idx, bool sorted) { - int error = 0; - KEY key_info = table->s->key_info[idx]; MRN_DBUG_ENTER_METHOD(); + int error = 0; + KEY *key_info = &(table->s->key_info[idx]); MRN_SET_WRAP_SHARE_KEY(share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); - if (!mrn_is_geo_key(&key_info) && key_info.algorithm != HA_KEY_ALG_FULLTEXT) + if (!mrn_is_geo_key(key_info) && key_info->algorithm != HA_KEY_ALG_FULLTEXT) { error = wrap_handler->ha_index_init(share->wrap_key_nr[idx], sorted); } else { @@ -6985,8 +6928,8 @@ int ha_mroonga::wrapper_index_read_map(uchar *buf, const uchar *key, { int error = 0; MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { clear_cursor_geo(); error = generic_geo_open_cursor(key, find_flag); if (!error) { @@ -7019,7 +6962,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key, int error = 0; uint key_nr = active_index; - KEY key_info = table->key_info[key_nr]; + KEY *key_info = &(table->key_info[key_nr]); int flags = 0; uint size_min = 0, size_max = 0; uchar *key_min = NULL, *key_max = NULL; @@ -7030,7 +6973,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key, clear_cursor_geo(); clear_empty_value_records(); - bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1; + bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1; if (is_multiple_column_index) { mrn_change_encoding(ctx, NULL); uint key_length = @@ -7039,17 +6982,17 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key, ("mroonga: multiple column index: " "search key length=<%u>, " "multiple column index key length=<%u>", - key_length, key_info.key_length)); - if (key_length == key_info.key_length) { + key_length, key_info->key_length)); + if (key_length == key_info->key_length) { if (find_flag == HA_READ_BEFORE_KEY || find_flag == HA_READ_PREFIX_LAST_OR_PREV) { key_max = key_max_entity; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, key, key_length, key_max, &size_max); } else { key_min = key_min_entity; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, key, key_length, key_min, &size_min); if (find_flag == HA_READ_KEY_EXACT) { @@ -7060,12 +7003,12 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key, } else { flags |= GRN_CURSOR_PREFIX; key_min = key_min_entity; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, key, key_length, key_min, &size_min); } - } else if (mrn_is_geo_key(&key_info)) { - error = mrn_change_encoding(ctx, key_info.key_part->field->charset()); + } else if (mrn_is_geo_key(key_info)) { + error = mrn_change_encoding(ctx, key_info->key_part->field->charset()); if (error) DBUG_RETURN(error); error = generic_geo_open_cursor(key, find_flag); @@ -7074,8 +7017,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key, } DBUG_RETURN(error); } else { - KEY_PART_INFO key_part = key_info.key_part[0]; - Field *field = key_part.field; + Field *field = key_info->key_part[0].field; error = mrn_change_encoding(ctx, field->charset()); if (error) DBUG_RETURN(error); @@ -7150,7 +7092,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key, GRN_EXPR_CREATE_FOR_QUERY(ctx, grn_table, expression, expression_variable); grn_obj *target_column = - grn_columns[key_info.key_part->field->field_index]; + grn_columns[key_info->key_part->field->field_index]; grn_expr_append_const(ctx, expression, target_column, GRN_OP_GET_VALUE, 1); grn_obj empty_value; GRN_TEXT_INIT(&empty_value, 0); @@ -7229,7 +7171,7 @@ int ha_mroonga::storage_index_read_last_map(uchar *buf, const uchar *key, { MRN_DBUG_ENTER_METHOD(); uint key_nr = active_index; - KEY key_info = table->key_info[key_nr]; + KEY *key_info = &(table->key_info[key_nr]); int flags = GRN_CURSOR_DESCENDING, error; uint size_min = 0, size_max = 0; @@ -7238,19 +7180,18 @@ int ha_mroonga::storage_index_read_last_map(uchar *buf, const uchar *key, clear_cursor(); - bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1; + bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1; if (is_multiple_column_index) { mrn_change_encoding(ctx, NULL); flags |= GRN_CURSOR_PREFIX; uint key_length = mrn_calculate_key_len(table, active_index, key, keypart_map); key_min = key_min_entity; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, key, key_length, key_min, &size_min); } else { - KEY_PART_INFO key_part = key_info.key_part[0]; - Field *field = key_part.field; + Field *field = key_info->key_part[0].field; error = mrn_change_encoding(ctx, field->charset()); if (error) DBUG_RETURN(error); @@ -7308,8 +7249,8 @@ int ha_mroonga::wrapper_index_next(uchar *buf) { int error = 0; MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { error = wrapper_get_next_geo_record(buf); } else { MRN_SET_WRAP_SHARE_KEY(share, table->s); @@ -7351,8 +7292,8 @@ int ha_mroonga::wrapper_index_prev(uchar *buf) { int error = 0; MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { error = wrapper_get_next_geo_record(buf); } else { MRN_SET_WRAP_SHARE_KEY(share, table->s); @@ -7525,8 +7466,8 @@ int ha_mroonga::wrapper_index_next_same(uchar *buf, const uchar *key, { MRN_DBUG_ENTER_METHOD(); int error = 0; - KEY key_info = table->s->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->s->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { error = wrapper_get_next_geo_record(buf); } else { MRN_SET_WRAP_SHARE_KEY(share, table->s); @@ -7571,8 +7512,8 @@ int ha_mroonga::wrapper_read_range_first(const key_range *start_key, { int error = 0; MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { clear_cursor_geo(); error = generic_geo_open_cursor(start_key->key, start_key->flag); if (!error) { @@ -7603,11 +7544,11 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key, uchar *key_min = NULL, *key_max = NULL; uchar key_min_entity[MRN_MAX_KEY_SIZE]; uchar key_max_entity[MRN_MAX_KEY_SIZE]; - KEY key_info = table->s->key_info[active_index]; + KEY *key_info = &(table->s->key_info[active_index]); clear_cursor(); - bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1; + bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1; if (is_multiple_column_index) { mrn_change_encoding(ctx, NULL); if (start_key && end_key && @@ -7615,13 +7556,13 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key, memcmp(start_key->key, end_key->key, start_key->length) == 0) { flags |= GRN_CURSOR_PREFIX; key_min = key_min_entity; - storage_encode_multiple_column_key(&key_info, + storage_encode_multiple_column_key(key_info, start_key->key, start_key->length, key_min, &size_min); } else { key_min = key_min_entity; key_max = key_max_entity; - storage_encode_multiple_column_key_range(&key_info, + storage_encode_multiple_column_key_range(key_info, start_key, end_key, key_min, &size_min, key_max, &size_max); @@ -7633,8 +7574,7 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key, } } } else { - KEY_PART_INFO key_part = key_info.key_part[0]; - Field *field = key_part.field; + Field *field = key_info->key_part[0].field; const char *column_name = field->field_name; error = mrn_change_encoding(ctx, field->charset()); if (error) @@ -7742,8 +7682,8 @@ int ha_mroonga::wrapper_read_range_next() { int error = 0; MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { error = wrapper_get_next_geo_record(table->record[0]); DBUG_RETURN(error); } @@ -8082,7 +8022,7 @@ grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_boolean_mode( bool parsed = false; bool done = false; keyword++; - keyword_length++; + keyword_length--; while (!done) { uint consumed_keyword_length = 0; switch (keyword[0]) { @@ -8283,12 +8223,11 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key) check_count_skip(0, 0, true); mrn_change_encoding(ctx, system_charset_info); - grn_operator operation = GRN_OP_AND; + grn_operator operation = GRN_OP_OR; if (!matched_record_keys) { matched_record_keys = grn_table_create(ctx, NULL, 0, NULL, GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC, grn_table, 0); - operation = GRN_OP_OR; } grn_table_sort_key *sort_keys = NULL; @@ -8317,6 +8256,24 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key) matched_record_keys); grn_table_sort(ctx, matched_record_keys, 0, static_cast<int>(limit), sorted_result, sort_keys, n_sort_keys); + } else if (flags & FT_SORTED) { + grn_table_sort_key score_sort_key; + score_sort_key.key = grn_obj_column(ctx, + matched_record_keys, + MRN_COLUMN_NAME_SCORE, + strlen(MRN_COLUMN_NAME_SCORE)); + score_sort_key.offset = 0; + score_sort_key.flags = GRN_TABLE_SORT_DESC; + if (sorted_result) { + grn_obj_unlink(ctx, sorted_result); + } + sorted_result = grn_table_create(ctx, NULL, + 0, NULL, + GRN_OBJ_TABLE_NO_KEY, NULL, + matched_record_keys); + grn_table_sort(ctx, matched_record_keys, 0, -1, + sorted_result, &score_sort_key, 1); + grn_obj_unlink(ctx, score_sort_key.key); } if (sort_keys) { for (int i = 0; i < n_sort_keys; i++) { @@ -8586,6 +8543,26 @@ ulonglong ha_mroonga::file_size(const char *path) } } +bool ha_mroonga::have_unique_index() +{ + MRN_DBUG_ENTER_METHOD(); + + uint n_keys = table->s->keys; + + for (uint i = 0; i < n_keys; i++) { + if (i == table->s->primary_key) { + continue; + } + + KEY *key_info = &(table->key_info[i]); + if (key_info->flags & HA_NOSAME) { + DBUG_RETURN(true); + } + } + + DBUG_RETURN(false); +} + void ha_mroonga::push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag) { char search_name[MRN_BUFFER_SIZE]; @@ -8712,27 +8689,27 @@ void ha_mroonga::clear_indexes() DBUG_VOID_RETURN; } -int ha_mroonga::alter_share_add(const char *path, TABLE_SHARE *table_share) +int ha_mroonga::add_wrap_hton(const char *path, handlerton *wrap_handlerton) { MRN_DBUG_ENTER_METHOD(); st_mrn_slot_data *slot_data = mrn_get_slot_data(ha_thd(), true); if (!slot_data) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - st_mrn_alter_share *alter_share = - (st_mrn_alter_share *)malloc(sizeof(st_mrn_alter_share)); - if (!alter_share) + st_mrn_wrap_hton *wrap_hton = + (st_mrn_wrap_hton *)malloc(sizeof(st_mrn_wrap_hton)); + if (!wrap_hton) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - alter_share->next = NULL; - strcpy(alter_share->path, path); - alter_share->alter_share = table_share; - if (slot_data->first_alter_share) + wrap_hton->next = NULL; + strcpy(wrap_hton->path, path); + wrap_hton->hton = wrap_handlerton; + if (slot_data->first_wrap_hton) { - st_mrn_alter_share *tmp_alter_share = slot_data->first_alter_share; - while (tmp_alter_share->next) - tmp_alter_share = tmp_alter_share->next; - tmp_alter_share->next = alter_share; + st_mrn_wrap_hton *tmp_wrap_hton = slot_data->first_wrap_hton; + while (tmp_wrap_hton->next) + tmp_wrap_hton = tmp_wrap_hton->next; + tmp_wrap_hton->next = wrap_hton; } else { - slot_data->first_alter_share = alter_share; + slot_data->first_wrap_hton = wrap_hton; } DBUG_RETURN(0); } @@ -8848,6 +8825,320 @@ int ha_mroonga::drop_index(MRN_SHARE *target_share, uint key_index) DBUG_RETURN(error); } +int ha_mroonga::drop_indexes_normal(const char *table_name, grn_obj *table) +{ + MRN_DBUG_ENTER_METHOD(); + + int error = 0; + + grn_hash *columns_raw = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, + GRN_OBJ_TABLE_HASH_KEY); + mrn::SmartGrnObj columns(ctx, reinterpret_cast<grn_obj *>(columns_raw)); + if (!columns.get()) { + char error_message[MRN_MESSAGE_BUFFER_SIZE]; + snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE, + "failed to allocate columns buffer: <%s>: <%s>", + table_name, ctx->errbuf); + error = HA_ERR_OUT_OF_MEM; + my_message(ER_ERROR_ON_WRITE, error_message, MYF(0)); + GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message); + DBUG_RETURN(error); + } + + grn_table_columns(ctx, table, "", 0, columns.get()); + grn_table_cursor *cursor = grn_table_cursor_open(ctx, + columns.get(), + NULL, 0, + NULL, 0, + 0, -1, + 0); + if (!cursor) { + char error_message[MRN_MESSAGE_BUFFER_SIZE]; + snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE, + "failed to allocate columns cursor: <%s>: <%s>", + table_name, ctx->errbuf); + error = HA_ERR_OUT_OF_MEM; + my_message(ER_ERROR_ON_WRITE, error_message, MYF(0)); + GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message); + DBUG_RETURN(error); + } + + while (grn_table_cursor_next(ctx, cursor) != GRN_ID_NIL) { + void *key; + grn_table_cursor_get_key(ctx, cursor, &key); + grn_id *id = reinterpret_cast<grn_id *>(key); + mrn::SmartGrnObj column(ctx, grn_ctx_at(ctx, *id)); + if (!column.get()) { + continue; + } + + grn_operator index_operators[] = { + GRN_OP_EQUAL, + GRN_OP_MATCH, + GRN_OP_LESS, + GRN_OP_REGEXP + }; + size_t n_index_operators = sizeof(index_operators) / sizeof(grn_operator); + for (size_t i = 0; i < n_index_operators; i++) { + grn_index_datum index_datum; + while (grn_column_find_index_data(ctx, + column.get(), + index_operators[i], + &index_datum, + 1) > 0) { + grn_id index_table_id = index_datum.index->header.domain; + mrn::SmartGrnObj index_table(ctx, grn_ctx_at(ctx, index_table_id)); + char index_table_name[GRN_TABLE_MAX_KEY_SIZE]; + int index_table_name_length; + index_table_name_length = grn_obj_name(ctx, index_table.get(), + index_table_name, + GRN_TABLE_MAX_KEY_SIZE); + if (mrn::IndexTableName::is_custom_name(table_name, + strlen(table_name), + index_table_name, + index_table_name_length)) { + char index_column_name[GRN_TABLE_MAX_KEY_SIZE]; + int index_column_name_length; + index_column_name_length = grn_obj_name(ctx, + index_datum.index, + index_column_name, + GRN_TABLE_MAX_KEY_SIZE); + grn_rc rc = grn_obj_remove(ctx, index_datum.index); + if (rc != GRN_SUCCESS) { + char error_message[MRN_MESSAGE_BUFFER_SIZE]; + snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE, + "failed to drop index column: <%.*s>: <%s>", + index_column_name_length, index_column_name, + ctx->errbuf); + error = ER_ERROR_ON_WRITE; + my_message(error, error_message, MYF(0)); + GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message); + } + } else { + grn_rc rc = grn_obj_remove(ctx, index_table.get()); + if (rc == GRN_SUCCESS) { + index_table.release(); + } else { + char error_message[MRN_MESSAGE_BUFFER_SIZE]; + snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE, + "failed to drop index table: <%.*s>: <%s>", + index_table_name_length, index_table_name, + ctx->errbuf); + error = ER_ERROR_ON_WRITE; + my_message(error, error_message, MYF(0)); + GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message); + } + } + + if (error != 0) { + break; + } + } + + if (error != 0) { + break; + } + } + + if (error != 0) { + break; + } + } + + grn_table_cursor_close(ctx, cursor); + + DBUG_RETURN(error); +} + +int ha_mroonga::drop_indexes_multiple(const char *table_name, grn_obj *table) +{ + MRN_DBUG_ENTER_METHOD(); + + int error = 0; + + char index_table_name_prefix[GRN_TABLE_MAX_KEY_SIZE]; + snprintf(index_table_name_prefix, GRN_TABLE_MAX_KEY_SIZE, + "%s%s", table_name, mrn::IndexTableName::SEPARATOR); + grn_table_cursor *cursor = + grn_table_cursor_open(ctx, + grn_ctx_db(ctx), + index_table_name_prefix, + strlen(index_table_name_prefix), + NULL, 0, + 0, -1, + GRN_CURSOR_PREFIX); + if (!cursor) { + char error_message[MRN_MESSAGE_BUFFER_SIZE]; + snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE, + "failed to allocate index tables cursor: <%s>: <%s>", + table_name, ctx->errbuf); + error = HA_ERR_OUT_OF_MEM; + my_message(ER_ERROR_ON_WRITE, error_message, MYF(0)); + GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message); + DBUG_RETURN(error); + } + + grn_id table_id = grn_obj_id(ctx, table); + grn_id id; + while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { + mrn::SmartGrnObj object(ctx, grn_ctx_at(ctx, id)); + if (!object.get()) { + continue; + } + if (!grn_obj_is_table(ctx, object.get())) { + continue; + } + + char multiple_column_index_table_name[GRN_TABLE_MAX_KEY_SIZE]; + int multiple_column_index_table_name_length; + multiple_column_index_table_name_length = + grn_obj_name(ctx, + object.get(), + multiple_column_index_table_name, + GRN_TABLE_MAX_KEY_SIZE); + + char multiple_column_index_name[GRN_TABLE_MAX_KEY_SIZE]; + snprintf(multiple_column_index_name, GRN_TABLE_MAX_KEY_SIZE, + "%.*s.%s", + multiple_column_index_table_name_length, + multiple_column_index_table_name, + INDEX_COLUMN_NAME); + mrn::SmartGrnObj index_column(ctx, multiple_column_index_name); + if (!index_column.get()) { + continue; + } + + if (grn_obj_get_range(ctx, index_column.get()) != table_id) { + continue; + } + + grn_rc rc = grn_obj_remove(ctx, object.get()); + if (rc == GRN_SUCCESS) { + object.release(); + index_column.release(); + } else { + char error_message[MRN_MESSAGE_BUFFER_SIZE]; + snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE, + "failed to drop multiple column index table: <%.*s>: <%s>", + multiple_column_index_table_name_length, + multiple_column_index_table_name, + ctx->errbuf); + error = ER_ERROR_ON_WRITE; + my_message(error, error_message, MYF(0)); + GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message); + break; + } + } + + grn_table_cursor_close(ctx, cursor); + + DBUG_RETURN(error); +} + +int ha_mroonga::drop_indexes(const char *table_name) +{ + MRN_DBUG_ENTER_METHOD(); + int error = 0; + + mrn::SmartGrnObj table(ctx, table_name); + if (!table.get()) { + DBUG_RETURN(0); + } + + error = drop_indexes_normal(table_name, table.get()); + if (error == 0) { + error = drop_indexes_multiple(table_name, table.get()); + } + + DBUG_RETURN(error); +} + +bool ha_mroonga::find_column_flags(Field *field, MRN_SHARE *mrn_share, int i, + grn_obj_flags *column_flags) +{ + MRN_DBUG_ENTER_METHOD(); + bool found = false; + +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + { + const char *names = field->option_struct->flags; + if (names) { + found = mrn_parse_grn_column_create_flags(ha_thd(), + ctx, + names, + strlen(names), + column_flags); + DBUG_RETURN(found); + } + } +#endif + + if (mrn_share->col_flags[i]) { + found = mrn_parse_grn_column_create_flags(ha_thd(), + ctx, + mrn_share->col_flags[i], + mrn_share->col_flags_length[i], + column_flags); + DBUG_RETURN(found); + } + + DBUG_RETURN(found); +} + +grn_obj *ha_mroonga::find_column_type(Field *field, MRN_SHARE *mrn_share, int i, + int error_code) +{ + MRN_DBUG_ENTER_METHOD(); + + const char *grn_type_name = NULL; +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + grn_type_name = field->option_struct->groonga_type; +#endif + if (!grn_type_name) { + grn_type_name = mrn_share->col_type[i]; + } + + grn_obj *type = NULL; + if (grn_type_name) { + type = grn_ctx_get(ctx, grn_type_name, -1); + if (!type) { + char error_message[MRN_BUFFER_SIZE]; + snprintf(error_message, MRN_BUFFER_SIZE, + "unknown custom Groonga type name for <%s> column: <%s>", + field->field_name, grn_type_name); + GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message); + my_message(error_code, error_message, MYF(0)); + + DBUG_RETURN(NULL); + } + } else { + grn_builtin_type grn_type_id = mrn_grn_type_from_field(ctx, field, false); + type = grn_ctx_at(ctx, grn_type_id); + } + + DBUG_RETURN(type); +} + +grn_obj *ha_mroonga::find_tokenizer(KEY *key, MRN_SHARE *mrn_share, int i) +{ + MRN_DBUG_ENTER_METHOD(); + grn_obj *tokenizer; + const char *tokenizer_name = NULL; + uint tokenizer_name_length = 0; +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + if (key->option_struct->tokenizer) { + tokenizer_name = key->option_struct->tokenizer; + tokenizer_name_length = strlen(tokenizer_name); + } +#endif + if (!tokenizer_name) { + tokenizer_name = mrn_share->key_tokenizer[i]; + tokenizer_name_length = mrn_share->key_tokenizer_length[i]; + } + tokenizer = find_tokenizer(tokenizer_name, tokenizer_name_length); + DBUG_RETURN(tokenizer); +} + grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length) { MRN_DBUG_ENTER_METHOD(); @@ -8862,92 +9153,137 @@ grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length) if (!tokenizer) { char message[MRN_BUFFER_SIZE]; sprintf(message, - "specified fulltext parser <%.*s> doesn't exist. " - "default fulltext parser <%s> is used instead.", + "specified tokenizer for fulltext index <%.*s> doesn't exist. " + "The default tokenizer for fulltext index <%s> is used instead.", name_length, name, - MRN_PARSER_DEFAULT); + MRN_DEFAULT_TOKENIZER); push_warning(ha_thd(), MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION, message); tokenizer = grn_ctx_get(ctx, - MRN_PARSER_DEFAULT, - strlen(MRN_PARSER_DEFAULT)); + MRN_DEFAULT_TOKENIZER, + strlen(MRN_DEFAULT_TOKENIZER)); } if (!tokenizer) { push_warning(ha_thd(), MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION, - "couldn't find fulltext parser. " - "Bigram fulltext parser is used instead."); + "couldn't find tokenizer for fulltext index. " + "Bigram tokenizer is used instead."); tokenizer = grn_ctx_at(ctx, GRN_DB_BIGRAM); } DBUG_RETURN(tokenizer); } -grn_obj *ha_mroonga::find_normalizer(KEY *key_info) +grn_obj *ha_mroonga::find_normalizer(KEY *key) +{ + MRN_DBUG_ENTER_METHOD(); + +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + if (key->option_struct->normalizer) { + grn_obj *normalizer = find_normalizer(key, + key->option_struct->normalizer); + DBUG_RETURN(normalizer); + } +#endif + + if (key->comment.length > 0) { + mrn::ParametersParser parser(key->comment.str, + key->comment.length); + parser.parse(); + grn_obj *normalizer = find_normalizer(key, parser["normalizer"]); + DBUG_RETURN(normalizer); + } + + grn_obj *normalizer = find_normalizer(key, NULL); + DBUG_RETURN(normalizer); +} + +grn_obj *ha_mroonga::find_normalizer(KEY *key, const char *name) { MRN_DBUG_ENTER_METHOD(); + grn_obj *normalizer = NULL; bool use_normalizer = true; -#if MYSQL_VERSION_ID >= 50500 - if (key_info->comment.length > 0) { - mrn::ParametersParser parser(key_info->comment.str, - key_info->comment.length); - parser.parse(); - const char *normalizer_name = parser["normalizer"]; - if (normalizer_name) { - if (strcmp(normalizer_name, "none") == 0) { - use_normalizer = false; - } else { - normalizer = grn_ctx_get(ctx, normalizer_name, -1); - } + if (name) { + if (strcmp(name, "none") == 0) { + use_normalizer = false; + } else { + normalizer = grn_ctx_get(ctx, name, -1); } } -#endif if (use_normalizer && !normalizer) { - Field *field = key_info->key_part[0].field; + Field *field = key->key_part[0].field; mrn::FieldNormalizer field_normalizer(ctx, ha_thd(), field); normalizer = field_normalizer.find_grn_normalizer(); } + DBUG_RETURN(normalizer); } -bool ha_mroonga::find_index_column_flags(KEY *key_info, grn_obj_flags *index_column_flags) +bool ha_mroonga::find_index_column_flags(KEY *key, grn_obj_flags *index_column_flags) { MRN_DBUG_ENTER_METHOD(); bool found = false; -#if MYSQL_VERSION_ID >= 50500 - if (key_info->comment.length > 0) { - mrn::ParametersParser parser(key_info->comment.str, - key_info->comment.length); - parser.parse(); - const char *names = parser["index_flags"]; + +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + { + const char *names = key->option_struct->flags; if (names) { found = mrn_parse_grn_index_column_flags(ha_thd(), ctx, names, strlen(names), index_column_flags); + DBUG_RETURN(found); } } #endif + + if (key->comment.length > 0) { + mrn::ParametersParser parser(key->comment.str, + key->comment.length); + parser.parse(); + const char *names = parser["flags"]; + if (!names) { + // Deprecated. It's for backward compatibility. + names = parser["index_flags"]; + } + if (names) { + found = mrn_parse_grn_index_column_flags(ha_thd(), + ctx, + names, + strlen(names), + index_column_flags); + } + } + DBUG_RETURN(found); } -bool ha_mroonga::find_token_filters(KEY *key_info, grn_obj *token_filters) +bool ha_mroonga::find_token_filters(KEY *key, grn_obj *token_filters) { MRN_DBUG_ENTER_METHOD(); bool found = false; -#if MYSQL_VERSION_ID >= 50500 - if (key_info->comment.length > 0) { - mrn::ParametersParser parser(key_info->comment.str, - key_info->comment.length); + +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + if (key->option_struct->token_filters) { + found = find_token_filters_fill(token_filters, + key->option_struct->token_filters, + strlen(key->option_struct->token_filters)); + DBUG_RETURN(found); + } +#endif + + if (key->comment.length > 0) { + mrn::ParametersParser parser(key->comment.str, + key->comment.length); parser.parse(); const char *names = parser["token_filters"]; if (names) { found = find_token_filters_fill(token_filters, names, strlen(names)); } } -#endif + DBUG_RETURN(found); } @@ -9356,8 +9692,8 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map, } else { DBUG_PRINT("info", ("mroonga: count skip: without fulltext")); uint key_nr = active_index; - KEY key_info = table->key_info[key_nr]; - KEY_PART_INFO *key_part = key_info.key_part; + KEY *key_info = &(table->key_info[key_nr]); + KEY_PART_INFO *key_part = key_info->key_part; for (where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex); where; where = where->next) { @@ -9386,17 +9722,17 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map, if (field->table != table) break; uint j; - for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { + for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { if (key_part[j].field == field) { if (!(start_key_part_map >> j) && !(end_key_part_map >> j)) - j = KEY_N_KEY_PARTS(&key_info); + j = KEY_N_KEY_PARTS(key_info); else i++; break; } } - if (j >= KEY_N_KEY_PARTS(&key_info)) + if (j >= KEY_N_KEY_PARTS(key_info)) break; } if (i >= select_lex->select_n_where_fields) @@ -9864,8 +10200,12 @@ int ha_mroonga::generic_store_bulk_datetime(Field *field, grn_obj *buf) long long int time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0); GRN_TIME_SET(ctx, buf, time); @@ -9896,8 +10236,12 @@ int ha_mroonga::generic_store_bulk_year(Field *field, grn_obj *buf) mrn::TimeConverter time_converter; long long int time = time_converter.tm_to_grn_time(&date, usec, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0); GRN_TIME_SET(ctx, buf, time); @@ -9917,8 +10261,12 @@ int ha_mroonga::generic_store_bulk_datetime2(Field *field, grn_obj *buf) long long int time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0); GRN_TIME_SET(ctx, buf, time); @@ -9938,8 +10286,12 @@ int ha_mroonga::generic_store_bulk_time2(Field *field, grn_obj *buf) long long int time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0); GRN_TIME_SET(ctx, buf, time); @@ -9959,8 +10311,12 @@ int ha_mroonga::generic_store_bulk_new_date(Field *field, grn_obj *buf) long long int time = time_converter.mysql_time_to_grn_time(&mysql_date, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0); GRN_TIME_SET(ctx, buf, time); @@ -10628,8 +10984,8 @@ void ha_mroonga::storage_store_fields(uchar *buf, grn_id record_id) const char *column_name = field->field_name; if (ignoring_no_key_columns) { - KEY key_info = table->s->key_info[active_index]; - if (strcmp(key_info.key_part[0].field->field_name, column_name)) { + KEY *key_info = &(table->s->key_info[active_index]); + if (strcmp(key_info->key_part[0].field->field_name, column_name)) { continue; } } @@ -10831,8 +11187,12 @@ int ha_mroonga::storage_encode_key_timestamp(Field *field, const uchar *key, mrn::TimeConverter time_converter; time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } memcpy(buf, &time, 8); *size = 8; @@ -10878,8 +11238,12 @@ int ha_mroonga::storage_encode_key_time(Field *field, const uchar *key, mrn::TimeConverter time_converter; time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } #else int mysql_time = (int)sint3korr(key); @@ -10913,8 +11277,12 @@ int ha_mroonga::storage_encode_key_year(Field *field, const uchar *key, long long int time = time_converter.tm_to_grn_time(&datetime, usec, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } memcpy(buf, &time, 8); *size = 8; @@ -10962,8 +11330,12 @@ int ha_mroonga::storage_encode_key_datetime(Field *field, const uchar *key, time = time_converter.tm_to_grn_time(&date, usec, &truncated); } if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } memcpy(buf, &time, 8); *size = 8; @@ -10988,8 +11360,12 @@ int ha_mroonga::storage_encode_key_timestamp2(Field *field, const uchar *key, long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } memcpy(buf, &grn_time, 8); *size = 8; @@ -11015,8 +11391,12 @@ int ha_mroonga::storage_encode_key_datetime2(Field *field, const uchar *key, long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } memcpy(buf, &grn_time, 8); *size = 8; @@ -11042,8 +11422,12 @@ int ha_mroonga::storage_encode_key_time2(Field *field, const uchar *key, long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } memcpy(buf, &grn_time, 8); *size = 8; @@ -11212,8 +11596,12 @@ int ha_mroonga::storage_encode_key(Field *field, const uchar *key, long long int time = time_converter.tm_to_grn_time(&date, usec, &truncated); if (truncated) { + if (MRN_ABORT_ON_WARNING(ha_thd())) { + error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()); + } field->set_warning(MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, 1); + MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()), + 1); } memcpy(buf, &time, 8); *size = 8; @@ -11381,12 +11769,11 @@ int ha_mroonga::reset() replacing_ = false; written_by_row_based_binlog = 0; mrn_lock_type = F_UNLCK; - mrn_clear_alter_share(thd); + mrn_clear_slot_data(thd); current_ft_item = NULL; DBUG_RETURN(error); } -#ifdef MRN_HANDLER_CLONE_NEED_NAME handler *ha_mroonga::wrapper_clone(const char *name, MEM_ROOT *mem_root) { handler *cloned_handler; @@ -11426,47 +11813,6 @@ handler *ha_mroonga::clone(const char *name, MEM_ROOT *mem_root) } DBUG_RETURN(cloned_handler); } -#else -handler *ha_mroonga::wrapper_clone(MEM_ROOT *mem_root) -{ - handler *cloned_handler; - MRN_DBUG_ENTER_METHOD(); - if (!(cloned_handler = get_new_handler(table->s, mem_root, - table->s->db_type()))) - DBUG_RETURN(NULL); - ((ha_mroonga *) cloned_handler)->is_clone = true; - ((ha_mroonga *) cloned_handler)->parent_for_clone = this; - ((ha_mroonga *) cloned_handler)->mem_root_for_clone = mem_root; - if (cloned_handler->ha_open(table, table->s->normalized_path.str, - table->db_stat, HA_OPEN_IGNORE_IF_LOCKED)) - { - delete cloned_handler; - DBUG_RETURN(NULL); - } - DBUG_RETURN(cloned_handler); -} - -handler *ha_mroonga::storage_clone(MEM_ROOT *mem_root) -{ - MRN_DBUG_ENTER_METHOD(); - handler *cloned_handler; - cloned_handler = handler::clone(mem_root); - DBUG_RETURN(cloned_handler); -} - -handler *ha_mroonga::clone(MEM_ROOT *mem_root) -{ - MRN_DBUG_ENTER_METHOD(); - handler *cloned_handler; - if (share->wrapper_mode) - { - cloned_handler = wrapper_clone(mem_root); - } else { - cloned_handler = storage_clone(mem_root); - } - DBUG_RETURN(cloned_handler); -} -#endif uint8 ha_mroonga::wrapper_table_cache_type() { @@ -11511,8 +11857,8 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno, { MRN_DBUG_ENTER_METHOD(); ha_rows rows; - KEY key_info = table->key_info[keyno]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[keyno]); + if (mrn_is_geo_key(key_info)) { rows = handler::multi_range_read_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, flags, cost); DBUG_RETURN(rows); @@ -11577,8 +11923,8 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info(uint keyno, uint n_ranges, { MRN_DBUG_ENTER_METHOD(); ha_rows rows; - KEY key_info = table->key_info[keyno]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[keyno]); + if (mrn_is_geo_key(key_info)) { rows = handler::multi_range_read_info(keyno, n_ranges, keys, #ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS key_parts, @@ -11651,8 +11997,8 @@ int ha_mroonga::wrapper_multi_range_read_init(RANGE_SEQ_IF *seq, { MRN_DBUG_ENTER_METHOD(); int error = 0; - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { error = handler::multi_range_read_init(seq, seq_init_param, n_ranges, mode, buf); DBUG_RETURN(error); @@ -11700,8 +12046,8 @@ int ha_mroonga::wrapper_multi_range_read_next(range_id_t *range_info) { MRN_DBUG_ENTER_METHOD(); int error = 0; - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { error = handler::multi_range_read_next(range_info); DBUG_RETURN(error); } @@ -11743,8 +12089,8 @@ int ha_mroonga::wrapper_read_multi_range_first(KEY_MULTI_RANGE **found_range_p, { int error = 0; MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { error = handler::read_multi_range_first(found_range_p, ranges, range_count, sorted, buffer); DBUG_RETURN(error); @@ -11795,8 +12141,8 @@ int ha_mroonga::wrapper_read_multi_range_next(KEY_MULTI_RANGE **found_range_p) { int error = 0; MRN_DBUG_ENTER_METHOD(); - KEY key_info = table->key_info[active_index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[active_index]); + if (mrn_is_geo_key(key_info)) { error = handler::read_multi_range_next(found_range_p); DBUG_RETURN(error); } @@ -11970,9 +12316,9 @@ int ha_mroonga::wrapper_delete_all_rows() uint i; uint n_keys = table->s->keys; for (i = 0; i < n_keys; i++) { - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (!(wrapper_is_target_index(&key_info))) { + if (!(wrapper_is_target_index(key_info))) { continue; } @@ -12016,7 +12362,6 @@ int ha_mroonga::delete_all_rows() DBUG_RETURN(error); } -#ifdef MRN_HANDLER_HAVE_TRUNCATE int ha_mroonga::wrapper_truncate() { int error = 0; @@ -12033,7 +12378,6 @@ int ha_mroonga::wrapper_truncate() DBUG_RETURN(error); } -#endif int ha_mroonga::wrapper_truncate_index() { @@ -12055,9 +12399,9 @@ int ha_mroonga::wrapper_truncate_index() uint i; uint n_keys = table->s->keys; for (i = 0; i < n_keys; i++) { - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); - if (!(wrapper_is_target_index(&key_info))) { + if (!(wrapper_is_target_index(key_info))) { continue; } @@ -12130,11 +12474,11 @@ int ha_mroonga::storage_truncate_index() continue; } - KEY key_info = table->key_info[i]; + KEY *key_info = &(table->key_info[i]); if ( - !(key_info.flags & HA_NOSAME) && - (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) + !(key_info->flags & HA_NOSAME) && + (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) ) { continue; } @@ -12155,7 +12499,6 @@ err: DBUG_RETURN(error); } -#ifdef MRN_HANDLER_HAVE_TRUNCATE int ha_mroonga::truncate() { MRN_DBUG_ENTER_METHOD(); @@ -12168,7 +12511,6 @@ int ha_mroonga::truncate() } DBUG_RETURN(error); } -#endif double ha_mroonga::wrapper_scan_time() { @@ -12207,8 +12549,8 @@ double ha_mroonga::wrapper_read_time(uint index, uint ranges, ha_rows rows) double res; MRN_DBUG_ENTER_METHOD(); if (index < MAX_KEY) { - KEY key_info = table->key_info[index]; - if (mrn_is_geo_key(&key_info)) { + KEY *key_info = &(table->key_info[index]); + if (mrn_is_geo_key(key_info)) { res = handler::read_time(index, ranges, rows); DBUG_RETURN(res); } @@ -12387,16 +12729,14 @@ int ha_mroonga::wrapper_rename_table(const char *from, const char *to, int error = 0; handler *hnd; MRN_DBUG_ENTER_METHOD(); - MRN_SET_WRAP_SHARE_KEY(tmp_share, tmp_share->table_share); - if (!(hnd = - tmp_share->hton->create(tmp_share->hton, tmp_share->table_share, - current_thd->mem_root))) + + hnd = get_new_handler(tmp_share->table_share, + current_thd->mem_root, + tmp_share->hton); + if (!hnd) { - MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - hnd->init(); - MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share); if ((error = hnd->ha_rename_table(from, to))) { @@ -12610,17 +12950,11 @@ int ha_mroonga::rename_table(const char *from, const char *to) if (strcmp(from_mapper.db_name(), to_mapper.db_name())) DBUG_RETURN(HA_ERR_WRONG_COMMAND); -#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS table_list.init_one_table(from_mapper.db_name(), strlen(from_mapper.db_name()), from_mapper.mysql_table_name(), strlen(from_mapper.mysql_table_name()), from_mapper.mysql_table_name(), TL_WRITE); -#else - table_list.init_one_table(from_mapper.db_name(), - from_mapper.mysql_table_name(), - TL_WRITE); -#endif mrn_open_mutex_lock(NULL); tmp_table_share = mrn_create_tmp_table_share(&table_list, from, &error); mrn_open_mutex_unlock(NULL); @@ -12650,21 +12984,20 @@ int ha_mroonga::rename_table(const char *from, const char *to) to_mapper.table_name()); } + if (!error && to_mapper.table_name()[0] == '#') { + error = add_wrap_hton(to, tmp_share->hton); + } else if (error && from_mapper.table_name()[0] == '#') { + add_wrap_hton(from, tmp_share->hton); + } if (!error) { mrn_free_long_term_share(tmp_share->long_term_share); tmp_share->long_term_share = NULL; } mrn_free_share(tmp_share); - if (!error && to_mapper.table_name()[0] == '#') { - if ((error = alter_share_add(to, tmp_table_share))) - DBUG_RETURN(error); - } else if (error && from_mapper.table_name()[0] == '#') { - alter_share_add(from, tmp_table_share); - } else { - mrn_open_mutex_lock(NULL); - mrn_free_tmp_table_share(tmp_table_share); - mrn_open_mutex_unlock(NULL); - } + mrn_open_mutex_lock(NULL); + mrn_free_tmp_table_share(tmp_table_share); + mrn_open_mutex_unlock(NULL); + DBUG_RETURN(error); } @@ -13669,6 +14002,7 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter( } memcpy(wrap_altered_table, altered_table, sizeof(TABLE)); memcpy(wrap_altered_table_share, altered_table->s, sizeof(TABLE_SHARE)); + mrn_init_sql_alloc(ha_thd(), &(wrap_altered_table_share->mem_root)); n_keys = ha_alter_info->index_drop_count; for (i = 0; i < n_keys; ++i) { @@ -13785,6 +14119,25 @@ bool ha_mroonga::wrapper_prepare_inplace_alter_table( if (!alter_handler_flags) { DBUG_RETURN(false); } + +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + int error = 0; + MRN_SHARE *tmp_share; + tmp_share = mrn_get_share(altered_table->s->table_name.str, + altered_table, + &error); + if (error != 0) { + DBUG_RETURN(true); + } + + if (parse_engine_table_options(ha_thd(), + tmp_share->hton, + wrap_altered_table->s)) { + mrn_free_share(tmp_share); + DBUG_RETURN(true); + } +#endif + MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info); MRN_SET_WRAP_SHARE_KEY(share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); @@ -13793,6 +14146,11 @@ bool ha_mroonga::wrapper_prepare_inplace_alter_table( MRN_SET_BASE_ALTER_KEY(this, ha_alter_info); MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); + +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + mrn_free_share(tmp_share); +#endif + DBUG_RETURN(result); } @@ -13857,8 +14215,8 @@ bool ha_mroonga::wrapper_inplace_alter_table( ha_alter_info->key_count); MRN_SHARE *tmp_share; TABLE_SHARE tmp_table_share; - char **key_parser; - uint *key_parser_length; + char **key_tokenizer; + uint *key_tokenizer_length; KEY *p_key_info = &table->key_info[table_share->primary_key]; bool need_fill_index = false; memset(index_tables, 0, sizeof(grn_obj *) * ha_alter_info->key_count); @@ -13868,8 +14226,8 @@ bool ha_mroonga::wrapper_inplace_alter_table( if (!(tmp_share = (MRN_SHARE *) mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), &tmp_share, sizeof(*tmp_share), - &key_parser, sizeof(char *) * (tmp_table_share.keys), - &key_parser_length, sizeof(uint) * (tmp_table_share.keys), + &key_tokenizer, sizeof(char *) * (tmp_table_share.keys), + &key_tokenizer_length, sizeof(uint) * (tmp_table_share.keys), NullS)) ) { MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); @@ -13880,8 +14238,8 @@ bool ha_mroonga::wrapper_inplace_alter_table( tmp_share->table_share = &tmp_table_share; tmp_share->index_table = NULL; tmp_share->index_table_length = NULL; - tmp_share->key_parser = key_parser; - tmp_share->key_parser_length = key_parser_length; + tmp_share->key_tokenizer = key_tokenizer; + tmp_share->key_tokenizer_length = key_tokenizer_length; bitmap_clear_all(table->read_set); mrn_set_bitmap_by_key(table->read_set, p_key_info); n_keys = ha_alter_info->index_add_count; @@ -13939,14 +14297,32 @@ bool ha_mroonga::wrapper_inplace_alter_table( bitmap_set_all(table->read_set); if (!error && alter_handler_flags) { - MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info); - MRN_SET_WRAP_SHARE_KEY(share, table->s); - MRN_SET_WRAP_TABLE_KEY(this, table); - result = wrap_handler->ha_inplace_alter_table(wrap_altered_table, - ha_alter_info); - MRN_SET_BASE_ALTER_KEY(this, ha_alter_info); - MRN_SET_BASE_SHARE_KEY(share, table->s); - MRN_SET_BASE_TABLE_KEY(this, table); +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS + { + MRN_SHARE *alter_tmp_share; + alter_tmp_share = mrn_get_share(altered_table->s->table_name.str, + altered_table, + &error); + if (alter_tmp_share) { + if (parse_engine_table_options(ha_thd(), + alter_tmp_share->hton, + wrap_altered_table->s)) { + error = MRN_GET_ERROR_NUMBER; + } + mrn_free_share(alter_tmp_share); + } + } +#endif + if (!error) { + MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info); + MRN_SET_WRAP_SHARE_KEY(share, table->s); + MRN_SET_WRAP_TABLE_KEY(this, table); + result = wrap_handler->ha_inplace_alter_table(wrap_altered_table, + ha_alter_info); + MRN_SET_BASE_ALTER_KEY(this, ha_alter_info); + MRN_SET_BASE_SHARE_KEY(share, table->s); + MRN_SET_BASE_TABLE_KEY(this, table); + } } if (result || error) @@ -13954,8 +14330,7 @@ bool ha_mroonga::wrapper_inplace_alter_table( n_keys = ha_alter_info->index_add_count; for (i = 0; i < n_keys; ++i) { uint key_pos = ha_alter_info->index_add_buffer[i]; - KEY *key = - &altered_table->key_info[key_pos]; + KEY *key = &altered_table->key_info[key_pos]; if (!(key->flags & HA_FULLTEXT || mrn_is_geo_key(key))) { continue; } @@ -14007,8 +14382,8 @@ bool ha_mroonga::storage_inplace_alter_table_index( ha_alter_info->key_count); MRN_SHARE *tmp_share; TABLE_SHARE tmp_table_share; - char **index_table, **key_parser, **col_flags, **col_type; - uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length; + char **index_table, **key_tokenizer, **col_flags, **col_type; + uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length; bool have_multiple_column_index = false; memset(index_tables, 0, sizeof(grn_obj *) * ha_alter_info->key_count); memset(index_columns, 0, sizeof(grn_obj *) * ha_alter_info->key_count); @@ -14019,8 +14394,8 @@ bool ha_mroonga::storage_inplace_alter_table_index( &tmp_share, sizeof(*tmp_share), &index_table, sizeof(char *) * tmp_table_share.keys, &index_table_length, sizeof(uint) * tmp_table_share.keys, - &key_parser, sizeof(char *) * tmp_table_share.keys, - &key_parser_length, sizeof(uint) * tmp_table_share.keys, + &key_tokenizer, sizeof(char *) * tmp_table_share.keys, + &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys, &col_flags, sizeof(char *) * tmp_table_share.fields, &col_flags_length, sizeof(uint) * tmp_table_share.fields, &col_type, sizeof(char *) * tmp_table_share.fields, @@ -14035,8 +14410,8 @@ bool ha_mroonga::storage_inplace_alter_table_index( tmp_share->table_share = &tmp_table_share; tmp_share->index_table = index_table; tmp_share->index_table_length = index_table_length; - tmp_share->key_parser = key_parser; - tmp_share->key_parser_length = key_parser_length; + tmp_share->key_tokenizer = key_tokenizer; + tmp_share->key_tokenizer_length = key_tokenizer_length; tmp_share->col_flags = col_flags; tmp_share->col_flags_length = col_flags_length; tmp_share->col_type = col_type; @@ -14145,8 +14520,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column( MRN_SHARE *tmp_share; TABLE_SHARE tmp_table_share; - char **index_table, **key_parser, **col_flags, **col_type; - uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length; + char **index_table, **key_tokenizer, **col_flags, **col_type; + uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length; tmp_table_share.keys = 0; tmp_table_share.fields = altered_table->s->fields; tmp_share = (MRN_SHARE *)mrn_my_multi_malloc( @@ -14154,8 +14529,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column( &tmp_share, sizeof(*tmp_share), &index_table, sizeof(char *) * tmp_table_share.keys, &index_table_length, sizeof(uint) * tmp_table_share.keys, - &key_parser, sizeof(char *) * tmp_table_share.keys, - &key_parser_length, sizeof(uint) * tmp_table_share.keys, + &key_tokenizer, sizeof(char *) * tmp_table_share.keys, + &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys, &col_flags, sizeof(char *) * tmp_table_share.fields, &col_flags_length, sizeof(uint) * tmp_table_share.fields, &col_type, sizeof(char *) * tmp_table_share.fields, @@ -14169,8 +14544,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column( tmp_share->table_share = &tmp_table_share; tmp_share->index_table = index_table; tmp_share->index_table_length = index_table_length; - tmp_share->key_parser = key_parser; - tmp_share->key_parser_length = key_parser_length; + tmp_share->key_tokenizer = key_tokenizer; + tmp_share->key_tokenizer_length = key_tokenizer_length; tmp_share->col_flags = col_flags; tmp_share->col_flags_length = col_flags_length; tmp_share->col_type = col_type; @@ -14187,7 +14562,6 @@ bool ha_mroonga::storage_inplace_alter_table_add_column( continue; } - grn_obj *col_type; Field *field = altered_table->s->field[i]; const char *column_name = field->field_name; int column_name_size = strlen(column_name); @@ -14199,20 +14573,19 @@ bool ha_mroonga::storage_inplace_alter_table_add_column( } grn_obj_flags col_flags = GRN_OBJ_PERSISTENT; - if (tmp_share->col_flags[i]) { - col_flags |= mrn_parse_grn_column_create_flags(ha_thd(), - ctx, - tmp_share->col_flags[i], - tmp_share->col_flags_length[i]); - } else { + if (!find_column_flags(field, tmp_share, i, &col_flags)) { col_flags |= GRN_OBJ_COLUMN_SCALAR; } - grn_builtin_type gtype = mrn_grn_type_from_field(ctx, field, false); - if (tmp_share->col_type[i]) { - col_type = grn_ctx_get(ctx, tmp_share->col_type[i], -1); - } else { - col_type = grn_ctx_at(ctx, gtype); + grn_obj *col_type; + { + int column_type_error_code = ER_WRONG_FIELD_SPEC; + col_type = find_column_type(field, tmp_share, i, column_type_error_code); + if (!col_type) { + error = column_type_error_code; + have_error = true; + break; + } } char *col_path = NULL; // we don't specify path @@ -14418,6 +14791,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table( bool result; MRN_DBUG_ENTER_METHOD(); if (!alter_handler_flags) { + free_root(&(wrap_altered_table_share->mem_root), MYF(0)); my_free(alter_key_info_buffer); alter_key_info_buffer = NULL; DBUG_RETURN(false); @@ -14431,6 +14805,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table( MRN_SET_BASE_ALTER_KEY(this, ha_alter_info); MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); + free_root(&(wrap_altered_table_share->mem_root), MYF(0)); my_free(alter_key_info_buffer); alter_key_info_buffer = NULL; DBUG_RETURN(result); @@ -14538,8 +14913,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info, THD *thd = ha_thd(); MRN_SHARE *tmp_share; TABLE_SHARE tmp_table_share; - char **key_parser; - uint *key_parser_length; + char **key_tokenizer; + uint *key_tokenizer_length; MRN_DBUG_ENTER_METHOD(); if (!(wrap_alter_key_info = (KEY *) mrn_my_malloc(sizeof(KEY) * num_of_keys, MYF(MY_WME)))) { @@ -14553,8 +14928,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info, if (!(tmp_share = (MRN_SHARE *) mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), &tmp_share, sizeof(*tmp_share), - &key_parser, sizeof(char *) * (n_keys + num_of_keys), - &key_parser_length, sizeof(uint) * (n_keys + num_of_keys), + &key_tokenizer, sizeof(char *) * (n_keys + num_of_keys), + &key_tokenizer_length, sizeof(uint) * (n_keys + num_of_keys), NullS)) ) { MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); @@ -14565,8 +14940,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info, tmp_share->table_share = &tmp_table_share; tmp_share->index_table = NULL; tmp_share->index_table_length = NULL; - tmp_share->key_parser = key_parser; - tmp_share->key_parser_length = key_parser_length; + tmp_share->key_tokenizer = key_tokenizer; + tmp_share->key_tokenizer_length = key_tokenizer_length; tmp_share->col_flags = NULL; tmp_share->col_type = NULL; #ifdef MRN_HANDLER_HAVE_FINAL_ADD_INDEX @@ -14677,8 +15052,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info, MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_columns, num_of_keys + n_keys); MRN_SHARE *tmp_share; TABLE_SHARE tmp_table_share; - char **index_table, **key_parser, **col_flags, **col_type; - uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length; + char **index_table, **key_tokenizer, **col_flags, **col_type; + uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length; bool have_multiple_column_index = false; MRN_DBUG_ENTER_METHOD(); @@ -14689,8 +15064,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info, &tmp_share, sizeof(*tmp_share), &index_table, sizeof(char*) * tmp_table_share.keys, &index_table_length, sizeof(uint) * tmp_table_share.keys, - &key_parser, sizeof(char *) * tmp_table_share.keys, - &key_parser_length, sizeof(uint) * tmp_table_share.keys, + &key_tokenizer, sizeof(char *) * tmp_table_share.keys, + &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys, &col_flags, sizeof(char *) * tmp_table_share.fields, &col_flags_length, sizeof(uint) * tmp_table_share.fields, &col_type, sizeof(char *) * tmp_table_share.fields, @@ -14705,8 +15080,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info, tmp_share->table_share = &tmp_table_share; tmp_share->index_table = index_table; tmp_share->index_table_length = index_table_length; - tmp_share->key_parser = key_parser; - tmp_share->key_parser_length = key_parser_length; + tmp_share->key_tokenizer = key_tokenizer; + tmp_share->key_tokenizer_length = key_tokenizer_length; tmp_share->col_flags = col_flags; tmp_share->col_flags_length = col_flags_length; tmp_share->col_type = col_type; @@ -15238,11 +15613,11 @@ int ha_mroonga::reset_auto_increment(ulonglong value) void ha_mroonga::set_pk_bitmap() { - KEY key_info = table->key_info[table_share->primary_key]; - uint j; MRN_DBUG_ENTER_METHOD(); - for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) { - Field *field = key_info.key_part[j].field; + KEY *key_info = &(table->key_info[table_share->primary_key]); + uint j; + for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) { + Field *field = key_info->key_part[j].field; bitmap_set_bit(table->read_set, field->field_index); } DBUG_VOID_RETURN; @@ -15556,17 +15931,11 @@ char *ha_mroonga::storage_get_foreign_key_create_info() build_table_filename(ref_path, sizeof(ref_path) - 1, table_share->db.str, ref_table_buff, "", 0); DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path)); -#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS table_list.init_one_table(table_share->db.str, table_share->db.length, ref_table_buff, ref_table_name_length, ref_table_buff, TL_WRITE); -#else - table_list.init_one_table(table_share->db.str, - ref_table_buff, - TL_WRITE); -#endif mrn_open_mutex_lock(table_share); tmp_ref_table_share = mrn_create_tmp_table_share(&table_list, ref_path, &error); @@ -15768,17 +16137,11 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd, build_table_filename(ref_path, sizeof(ref_path) - 1, table_share->db.str, ref_table_buff, "", 0); DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path)); -#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS table_list.init_one_table(table_share->db.str, table_share->db.length, ref_table_buff, ref_table_name_length, ref_table_buff, TL_WRITE); -#else - table_list.init_one_table(table_share->db.str, - ref_table_buff, - TL_WRITE); -#endif mrn_open_mutex_lock(table_share); tmp_ref_table_share = mrn_create_tmp_table_share(&table_list, ref_path, &error); @@ -15831,7 +16194,6 @@ int ha_mroonga::get_foreign_key_list(THD *thd, DBUG_RETURN(res); } -#ifdef MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST int ha_mroonga::wrapper_get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list) { @@ -15866,7 +16228,6 @@ int ha_mroonga::get_parent_foreign_key_list(THD *thd, } DBUG_RETURN(res); } -#endif uint ha_mroonga::wrapper_referenced_by_foreign_key() { diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp index 78d5c3d2465..37059210dd1 100644 --- a/storage/mroonga/ha_mroonga.hpp +++ b/storage/mroonga/ha_mroonga.hpp @@ -33,18 +33,11 @@ extern "C" { #include <groonga.h> #include "mrn_mysql_compat.h" -#if (MYSQL_VERSION_ID >= 50603) || \ - (MYSQL_VERSION_ID >= 50513 && MYSQL_VERSION_ID < 50600) || \ - (MYSQL_VERSION_ID >= 50158 && MYSQL_VERSION_ID < 50500) -# define MRN_HANDLER_CLONE_NEED_NAME 1 -#endif - #if (MYSQL_VERSION_ID >= 50514 && MYSQL_VERSION_ID < 50600) # define MRN_HANDLER_HAVE_FINAL_ADD_INDEX 1 #endif -#if (MYSQL_VERSION_ID >= 50603) || \ - (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50209) +#if (MYSQL_VERSION_ID >= 50603) || defined(MRN_MARIADB_P) # 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 @@ -56,8 +49,7 @@ extern "C" { # define MRN_HANDLER_HAVE_HA_INDEX_NEXT_SAME 1 #endif -#if (MYSQL_VERSION_ID >= 50604) || \ - (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50302) +#if (MYSQL_VERSION_ID >= 50604) || defined(MRN_MARIADB_P) # define MRN_HANDLER_HAVE_HA_CLOSE 1 # define MRN_HANDLER_HAVE_MULTI_RANGE_READ 1 #endif @@ -77,15 +69,10 @@ extern "C" { # endif #endif -#if (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50302) +#ifdef MRN_MARIADB_P # define MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS #endif -#if MYSQL_VERSION_ID >= 50500 -# define MRN_HANDLER_HAVE_TRUNCATE -# define MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST -#endif - #if MYSQL_VERSION_ID < 50600 # define MRN_HANDLER_HAVE_GET_TABLESPACE_NAME #endif @@ -94,10 +81,6 @@ extern "C" { # define MRN_HANDLER_HAVE_SET_HA_SHARE_REF #endif -#if MYSQL_VERSION_ID >= 50500 -# define MRN_TABLE_LIST_INIT_REQUIRE_ALIAS -#endif - #if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P) # define MRN_BIG_TABLES #elif defined(BIG_TABLES) @@ -110,17 +93,10 @@ extern "C" { # define MRN_HA_ROWS_FORMAT "lu" #endif -#if (MYSQL_VERSION_ID < 50519) || \ - defined(MRN_MARIADB_P) || \ - (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID < 50604) +#ifdef MRN_MARIADB_P # define MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR #endif -#if MYSQL_VERSION_ID >= 50500 -# define MRN_HAVE_HA_EXTRA_ADD_CHILDREN_LIST -# define MRN_HAVE_HA_EXTRA_IS_ATTACHED_CHILDREN -#endif - #ifdef MRN_MARIADB_P # define MRN_HAVE_HA_EXTRA_DETACH_CHILD # define MRN_HAVE_HA_EXTRA_PREPARE_FOR_FORCED_CLOSE @@ -147,10 +123,6 @@ extern "C" { # define MRN_FIELD_STORE_TIME_NEED_TYPE #endif -#if MYSQL_VERSION_ID < 50500 -# define MRN_HAVE_TL_WRITE_ALLOW_READ -#endif - #if MYSQL_VERSION_ID < 50706 || defined(MRN_MARIADB_P) # define MRN_HAVE_TL_WRITE_DELAYED #endif @@ -159,9 +131,7 @@ extern "C" { # define MRN_HAVE_TL_WRITE_CONCURRENT_DEFAULT #endif -#if (defined(MRN_MARIADB_P) && \ - ((MYSQL_VERSION_ID >= 50306 && MYSQL_VERSION_ID < 50500) || \ - MYSQL_VERSION_ID >= 50523)) +#ifdef MRN_MARIADB_P # define MRN_HANDLER_AUTO_REPAIR_HAVE_ERROR #endif @@ -191,6 +161,9 @@ extern "C" { #if (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100010) # define MRN_HAVE_TDC_LOCK_TABLE_SHARE +# if MYSQL_VERSION_ID >= 100100 +# define MRN_TABLE_SHARE_TDC_IS_POINTER +# endif #endif #ifdef MRN_MARIADB_P @@ -256,6 +229,22 @@ struct st_mrn_ft_info ha_mroonga *mroonga; }; +#ifdef MRN_SUPPORT_CUSTOM_OPTIONS +struct ha_field_option_struct +{ + const char *groonga_type; + const char *flags; +}; + +struct ha_index_option_struct +{ + const char *tokenizer; + const char *normalizer; + const char *token_filters; + const char *flags; +}; +#endif + /* handler class */ class ha_mroonga: public handler { @@ -446,11 +435,7 @@ public: int reset(); -#ifdef MRN_HANDLER_CLONE_NEED_NAME handler *clone(const char *name, MEM_ROOT *mem_root); -#else - handler *clone(MEM_ROOT *mem_root); -#endif uint8 table_cache_type(); #ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, @@ -481,9 +466,7 @@ public: #endif int end_bulk_insert(); int delete_all_rows(); -#ifdef MRN_HANDLER_HAVE_TRUNCATE int truncate(); -#endif // MRN_HANDLER_HAVE_TRUNCATE double scan_time(); double read_time(uint index, uint ranges, ha_rows rows); const key_map *keys_to_use_for_scanning(); @@ -567,9 +550,7 @@ protected: #endif bool can_switch_engines(); int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); -#ifdef MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST int get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); -#endif uint referenced_by_foreign_key(); void init_table_handle_for_HANDLER(); void free_foreign_key_create_info(char* str); @@ -597,6 +578,8 @@ private: void mkdir_p(const char *directory); ulonglong file_size(const char *path); + bool have_unique_index(); + void push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag); void clear_cursor(); void clear_cursor_geo(); @@ -604,14 +587,23 @@ private: void clear_search_result(); void clear_search_result_geo(); void clear_indexes(); - int alter_share_add(const char *path, TABLE_SHARE *table_share); + int add_wrap_hton(const char *path, handlerton *wrap_handlerton); void remove_related_files(const char *base_path); void remove_grn_obj_force(const char *name); int drop_index(MRN_SHARE *target_share, uint key_index); + int drop_indexes_normal(const char *table_name, grn_obj *table); + int drop_indexes_multiple(const char *table_name, grn_obj *table); + int drop_indexes(const char *table_name); + bool find_column_flags(Field *field, MRN_SHARE *mrn_share, int i, + grn_obj_flags *column_flags); + grn_obj *find_column_type(Field *field, MRN_SHARE *mrn_share, int i, + int error_code); + grn_obj *find_tokenizer(KEY *key, MRN_SHARE *mrn_share, int i); grn_obj *find_tokenizer(const char *name, int name_length); - grn_obj *find_normalizer(KEY *key_info); - bool find_index_column_flags(KEY *key_info, grn_obj_flags *index_column_flags); - bool find_token_filters(KEY *key_info, grn_obj *token_filters); + grn_obj *find_normalizer(KEY *key); + grn_obj *find_normalizer(KEY *key, const char *name); + bool find_index_column_flags(KEY *key, grn_obj_flags *index_column_flags); + bool find_token_filters(KEY *key, grn_obj *token_filters); bool find_token_filters_put(grn_obj *token_filters, const char *token_filter_name, int token_filter_name_length); @@ -788,12 +780,9 @@ private: int close_databases(); int ensure_database_open(const char *name); int ensure_database_remove(const char *name); - int wrapper_delete_table(const char *name, MRN_SHARE *tmp_share, - const char *table_name); - int wrapper_delete_index(const char *name, MRN_SHARE *tmp_share, - const char *table_name); - int storage_delete_table(const char *name, MRN_SHARE *tmp_share, + int wrapper_delete_table(const char *name, handlerton *wrap_handlerton, const char *table_name); + int generic_delete_table(const char *name, const char *table_name); int wrapper_open(const char *name, int mode, uint test_if_locked); int wrapper_open_indexes(const char *name); int storage_open(const char *name, int mode, uint test_if_locked); @@ -987,13 +976,8 @@ private: void storage_cond_pop(); bool wrapper_get_error_message(int error, String *buf); bool storage_get_error_message(int error, String *buf); -#ifdef MRN_HANDLER_CLONE_NEED_NAME handler *wrapper_clone(const char *name, MEM_ROOT *mem_root); handler *storage_clone(const char *name, MEM_ROOT *mem_root); -#else - handler *wrapper_clone(MEM_ROOT *mem_root); - handler *storage_clone(MEM_ROOT *mem_root); -#endif uint8 wrapper_table_cache_type(); uint8 storage_table_cache_type(); #ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ @@ -1049,9 +1033,7 @@ private: const char *function_name); int wrapper_delete_all_rows(); int storage_delete_all_rows(); -#ifdef MRN_HANDLER_HAVE_TRUNCATE int wrapper_truncate(); -#endif // MRN_HANDLER_HAVE_TRUNCATE int wrapper_truncate_index(); int storage_truncate(); int storage_truncate_index(); @@ -1216,10 +1198,8 @@ private: bool storage_can_switch_engines(); int wrapper_get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); int storage_get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); -#ifdef MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST int wrapper_get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); int storage_get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); -#endif uint wrapper_referenced_by_foreign_key(); uint storage_referenced_by_foreign_key(); void wrapper_init_table_handle_for_HANDLER(); diff --git a/storage/mroonga/lib/mrn_condition_converter.cpp b/storage/mroonga/lib/mrn_condition_converter.cpp index 1bfae1d4f8a..1527a546938 100644 --- a/storage/mroonga/lib/mrn_condition_converter.cpp +++ b/storage/mroonga/lib/mrn_condition_converter.cpp @@ -17,10 +17,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "mrn_condition_converter.hpp" #include "mrn_time_converter.hpp" #include "mrn_smart_grn_obj.hpp" diff --git a/storage/mroonga/lib/mrn_condition_converter.hpp b/storage/mroonga/lib/mrn_condition_converter.hpp index bb85f5cdef5..3a7fbd048dc 100644 --- a/storage/mroonga/lib/mrn_condition_converter.hpp +++ b/storage/mroonga/lib/mrn_condition_converter.hpp @@ -20,11 +20,12 @@ #ifndef MRN_CONDITION_CONVERTER_HPP_ #define MRN_CONDITION_CONVERTER_HPP_ -#include <groonga.h> #include <mrn_mysql_compat.h> #include <item_cmpfunc.h> +#include <groonga.h> + namespace mrn { class ConditionConverter { public: diff --git a/storage/mroonga/lib/mrn_database_manager.cpp b/storage/mroonga/lib/mrn_database_manager.cpp index 365f47337fa..753d1551ff4 100644 --- a/storage/mroonga/lib/mrn_database_manager.cpp +++ b/storage/mroonga/lib/mrn_database_manager.cpp @@ -2,7 +2,7 @@ /* Copyright(C) 2010 Tetsuro IKEDA Copyright(C) 2010-2013 Kentoku SHIBA - Copyright(C) 2011-2014 Kouhei Sutou <kou@clear-code.com> + Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -126,13 +126,12 @@ namespace mrn { mapper.db_name(), strlen(mapper.db_name()), &db_address, NULL); memcpy(db_address, db, sizeof(grn_obj *)); + error = ensure_normalizers_registered(*db); } else { memcpy(db, db_address, sizeof(grn_obj *)); grn_ctx_use(ctx_, *db); } - error = ensure_normalizers_registered(*db); - DBUG_RETURN(error); } @@ -313,18 +312,18 @@ namespace mrn { int error = 0; #ifdef WITH_GROONGA_NORMALIZER_MYSQL { +# ifdef MRN_GROONGA_NORMALIZER_MYSQL_EMBEDDED + GRN_PLUGIN_IMPL_NAME_TAGGED(init, normalizers_mysql)(ctx_); + GRN_PLUGIN_IMPL_NAME_TAGGED(register, normalizers_mysql)(ctx_); +# else grn_obj *mysql_normalizer; mysql_normalizer = grn_ctx_get(ctx_, "NormalizerMySQLGeneralCI", -1); if (mysql_normalizer) { grn_obj_unlink(ctx_, mysql_normalizer); } else { -# ifdef MRN_GROONGA_NORMALIZER_MYSQL_EMBED - GRN_PLUGIN_IMPL_NAME_TAGGED(init, normalizers_mysql)(ctx_); - GRN_PLUGIN_IMPL_NAME_TAGGED(register, normalizers_mysql)(ctx_); -# else grn_plugin_register(ctx_, GROONGA_NORMALIZER_MYSQL_PLUGIN_NAME); -# endif } +# endif } #endif diff --git a/storage/mroonga/lib/mrn_database_repairer.cpp b/storage/mroonga/lib/mrn_database_repairer.cpp index 151330c9999..f04c027f8bb 100644 --- a/storage/mroonga/lib/mrn_database_repairer.cpp +++ b/storage/mroonga/lib/mrn_database_repairer.cpp @@ -233,7 +233,7 @@ namespace mrn { bool *succeeded = static_cast<bool *>(user_data); if (grn_db_recover(ctx_, db) != GRN_SUCCESS) { push_warning_printf(thd_, - Sql_condition::WARN_LEVEL_WARN, + MRN_SEVERITY_WARNING, ER_NOT_KEYFILE, "mroonga: repair: " "Failed to recover database: <%s>: <%s>", diff --git a/storage/mroonga/lib/mrn_encoding.cpp b/storage/mroonga/lib/mrn_encoding.cpp index 35b8909fba2..f6f66758b2f 100644 --- a/storage/mroonga/lib/mrn_encoding.cpp +++ b/storage/mroonga/lib/mrn_encoding.cpp @@ -18,7 +18,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <mrn_mysql.h> #include <mrn_err.h> #include "mrn_encoding.hpp" diff --git a/storage/mroonga/lib/mrn_encoding.hpp b/storage/mroonga/lib/mrn_encoding.hpp index b29b44d967e..9c3a65da0f1 100644 --- a/storage/mroonga/lib/mrn_encoding.hpp +++ b/storage/mroonga/lib/mrn_encoding.hpp @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com> + Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,11 +20,11 @@ #ifndef MRN_ENCODING_HPP_ #define MRN_ENCODING_HPP_ -#include <groonga.h> - #include <mrn_mysql.h> #include <mrn_mysql_compat.h> +#include <groonga.h> + namespace mrn { namespace encoding { void init(void); diff --git a/storage/mroonga/lib/mrn_field_normalizer.cpp b/storage/mroonga/lib/mrn_field_normalizer.cpp index f0b9d921599..d5b0b3ff43e 100644 --- a/storage/mroonga/lib/mrn_field_normalizer.cpp +++ b/storage/mroonga/lib/mrn_field_normalizer.cpp @@ -17,8 +17,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <mrn_mysql.h> - #include "mrn_field_normalizer.hpp" #include "mrn_encoding.hpp" diff --git a/storage/mroonga/lib/mrn_field_normalizer.hpp b/storage/mroonga/lib/mrn_field_normalizer.hpp index 5fd8974ce5b..3a855693481 100644 --- a/storage/mroonga/lib/mrn_field_normalizer.hpp +++ b/storage/mroonga/lib/mrn_field_normalizer.hpp @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com> + Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,11 +20,11 @@ #ifndef MRN_FIELD_NORMALIZER_HPP_ #define MRN_FIELD_NORMALIZER_HPP_ -#include <groonga.h> - #include <mrn_mysql.h> #include <mrn_mysql_compat.h> +#include <groonga.h> + namespace mrn { class FieldNormalizer { public: diff --git a/storage/mroonga/lib/mrn_index_table_name.cpp b/storage/mroonga/lib/mrn_index_table_name.cpp index 93f4ff8f8fd..a4a687c7996 100644 --- a/storage/mroonga/lib/mrn_index_table_name.cpp +++ b/storage/mroonga/lib/mrn_index_table_name.cpp @@ -26,6 +26,32 @@ #define MRN_CLASS_NAME "mrn::IndexTableName" namespace mrn { + const char *IndexTableName::SEPARATOR = "-"; + + bool IndexTableName::is_custom_name(const char *table_name, + size_t table_name_length, + const char *index_table_name, + size_t index_table_name_length) + { + MRN_DBUG_ENTER_METHOD(); + + if (index_table_name_length <= (table_name_length + strlen(SEPARATOR))) { + DBUG_RETURN(true); + } + + if (strncmp(table_name, index_table_name, table_name_length) != 0) { + DBUG_RETURN(true); + } + + if (strncmp(SEPARATOR, + index_table_name + table_name_length, + strlen(SEPARATOR)) != 0) { + DBUG_RETURN(true); + } + + DBUG_RETURN(false); + } + IndexTableName::IndexTableName(const char *table_name, const char *mysql_index_name) : table_name_(table_name), @@ -38,7 +64,10 @@ namespace mrn { mysql_index_name_multibyte, mysql_index_name_multibyte + strlen(mysql_index_name_)); snprintf(name_, MRN_MAX_KEY_SIZE, - "%s-%s", table_name_, encoded_mysql_index_name_multibyte); + "%s%s%s", + table_name_, + SEPARATOR, + encoded_mysql_index_name_multibyte); length_ = strlen(name_); } diff --git a/storage/mroonga/lib/mrn_index_table_name.hpp b/storage/mroonga/lib/mrn_index_table_name.hpp index 4ac4bfe087b..c4f16228610 100644 --- a/storage/mroonga/lib/mrn_index_table_name.hpp +++ b/storage/mroonga/lib/mrn_index_table_name.hpp @@ -26,6 +26,13 @@ namespace mrn { class IndexTableName { public: + static const char *SEPARATOR; + + static bool is_custom_name(const char *table_name, + size_t table_name_length, + const char *index_table_name, + size_t index_table_name_length); + IndexTableName(const char *table_name, const char *mysql_index_name); const char *c_str(); size_t length(); diff --git a/storage/mroonga/lib/mrn_lock.cpp b/storage/mroonga/lib/mrn_lock.cpp index 3340149b237..f518bca9af3 100644 --- a/storage/mroonga/lib/mrn_lock.cpp +++ b/storage/mroonga/lib/mrn_lock.cpp @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com> + Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,12 +20,17 @@ #include "mrn_lock.hpp" namespace mrn { - Lock::Lock(mysql_mutex_t *mutex) - : mutex_(mutex) { - mysql_mutex_lock(mutex_); + Lock::Lock(mysql_mutex_t *mutex, bool execute) + : mutex_(mutex), + execute_(execute) { + if (execute_) { + mysql_mutex_lock(mutex_); + } } Lock::~Lock() { - mysql_mutex_unlock(mutex_); + if (execute_) { + mysql_mutex_unlock(mutex_); + } } } diff --git a/storage/mroonga/lib/mrn_lock.hpp b/storage/mroonga/lib/mrn_lock.hpp index 08e47b39c58..2ec71370fa1 100644 --- a/storage/mroonga/lib/mrn_lock.hpp +++ b/storage/mroonga/lib/mrn_lock.hpp @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com> + Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -26,10 +26,11 @@ namespace mrn { class Lock { public: - Lock(mysql_mutex_t *mutex); + Lock(mysql_mutex_t *mutex, bool execute=true); ~Lock(); private: mysql_mutex_t *mutex_; + bool execute_; }; } diff --git a/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp b/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp index 1e55636f1bc..c7ef9dd5851 100644 --- a/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp +++ b/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp @@ -23,6 +23,7 @@ #include "mrn_multiple_column_key_codec.hpp" #include "mrn_field_normalizer.hpp" #include "mrn_smart_grn_obj.hpp" +#include "mrn_time_converter.hpp" #include "mrn_value_decoder.hpp" // for debug @@ -36,6 +37,13 @@ uint8 *key_ = (uint8 *)(key); \ while (size_--) { *buf_++ = *key_++; } \ } +#define mrn_byte_order_network_to_host(buf, key, size) \ +{ \ + uint32 size_ = (uint32)(size); \ + uint8 *buf_ = (uint8 *)(buf); \ + uint8 *key_ = (uint8 *)(key); \ + while (size_) { *buf_++ = *key_++; size_--; } \ +} #else /* WORDS_BIGENDIAN */ #define mrn_byte_order_host_to_network(buf, key, size) \ { \ @@ -44,6 +52,13 @@ uint8 *key_ = (uint8 *)(key) + size_; \ while (size_--) { *buf_++ = *(--key_); } \ } +#define mrn_byte_order_network_to_host(buf, key, size) \ +{ \ + uint32 size_ = (uint32)(size); \ + uint8 *buf_ = (uint8 *)(buf); \ + uint8 *key_ = (uint8 *)(key) + size_; \ + while (size_) { *buf_++ = *(--key_); size_--; } \ +} #endif /* WORDS_BIGENDIAN */ namespace mrn { @@ -87,6 +102,7 @@ namespace mrn { DataType data_type = TYPE_UNKNOWN; uint data_size = 0; get_key_info(key_part, &data_type, &data_size); + uint grn_key_data_size = data_size; switch (data_type) { case TYPE_UNKNOWN: @@ -97,26 +113,17 @@ namespace mrn { case TYPE_LONG_LONG_NUMBER: { long long int long_long_value = 0; - switch (data_size) { - case 3: - long_long_value = (long long int)sint3korr(current_mysql_key); - break; - case 8: - long_long_value = (long long int)sint8korr(current_mysql_key); - break; - } - mrn_byte_order_host_to_network(current_grn_key, &long_long_value, - data_size); - *((uint8 *)(current_grn_key)) ^= 0x80; + long_long_value = sint8korr(current_mysql_key); + encode_long_long_int(long_long_value, current_grn_key); } break; case TYPE_NUMBER: - mrn_byte_order_host_to_network(current_grn_key, current_mysql_key, data_size); { - Field_num *number_field = (Field_num *)field; - if (!number_field->unsigned_flag) { - *((uint8 *)(current_grn_key)) ^= 0x80; - } + Field_num *number_field = static_cast<Field_num *>(field); + encode_number(current_mysql_key, + data_size, + !number_field->unsigned_flag, + current_grn_key); } break; case TYPE_FLOAT: @@ -133,6 +140,44 @@ namespace mrn { encode_double(value, data_size, current_grn_key); } break; + case TYPE_DATETIME: + { + long long int mysql_datetime; +#ifdef WORDS_BIGENDIAN + if (field->table && field->table->s->db_low_byte_first) { + mysql_datetime = sint8korr(current_mysql_key); + } else +#endif + { + value_decoder::decode(&mysql_datetime, current_mysql_key); + } + TimeConverter time_converter; + bool truncated; + long long int grn_time = + time_converter.mysql_datetime_to_grn_time(mysql_datetime, + &truncated); + encode_long_long_int(grn_time, current_grn_key); + } + break; +#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2 + case TYPE_DATETIME2: + { + Field_datetimef *datetimef_field = + static_cast<Field_datetimef *>(field); + long long int mysql_datetime_packed = + my_datetime_packed_from_binary(current_mysql_key, + datetimef_field->decimals()); + MYSQL_TIME mysql_time; + TIME_from_longlong_datetime_packed(&mysql_time, mysql_datetime_packed); + TimeConverter time_converter; + bool truncated; + long long int grn_time = + time_converter.mysql_time_to_grn_time(&mysql_time, &truncated); + grn_key_data_size = 8; + encode_long_long_int(grn_time, current_grn_key); + } + break; +#endif case TYPE_BYTE_SEQUENCE: memcpy(current_grn_key, current_mysql_key, data_size); break; @@ -140,7 +185,8 @@ namespace mrn { encode_reverse(current_mysql_key, data_size, current_grn_key); break; case TYPE_BYTE_BLOB: - encode_blob(field, current_mysql_key, current_grn_key, &data_size); + encode_blob(current_mysql_key, &data_size, field, current_grn_key); + grn_key_data_size = data_size; break; } @@ -149,8 +195,8 @@ namespace mrn { } current_mysql_key += data_size; - current_grn_key += data_size; - *grn_key_length += data_size; + current_grn_key += grn_key_data_size; + *grn_key_length += grn_key_data_size; } DBUG_RETURN(error); @@ -185,6 +231,7 @@ namespace mrn { DataType data_type = TYPE_UNKNOWN; uint data_size = 0; get_key_info(key_part, &data_type, &data_size); + uint grn_key_data_size = data_size; switch (data_type) { case TYPE_UNKNOWN: @@ -194,43 +241,68 @@ namespace mrn { break; case TYPE_LONG_LONG_NUMBER: { - long long int long_long_value = 0; - switch (data_size) { - case 3: - long_long_value = (long long int)sint3korr(current_grn_key); - break; - case 8: - long_long_value = (long long int)sint8korr(current_grn_key); - break; - } - *((uint8 *)(&long_long_value)) ^= 0x80; - mrn_byte_order_host_to_network(current_mysql_key, &long_long_value, - data_size); + long long int value; + decode_long_long_int(current_grn_key, &value); + int8store(current_mysql_key, value); } break; case TYPE_NUMBER: { - uchar buffer[8]; - memcpy(buffer, current_grn_key, data_size); - Field_num *number_field = (Field_num *)field; - if (!number_field->unsigned_flag) { - buffer[0] ^= 0x80; - } - mrn_byte_order_host_to_network(current_mysql_key, buffer, - data_size); + Field_num *number_field = static_cast<Field_num *>(field); + decode_number(current_grn_key, + grn_key_data_size, + !number_field->unsigned_flag, + current_mysql_key); } break; case TYPE_FLOAT: - decode_float(current_grn_key, current_mysql_key, data_size); + decode_float(current_grn_key, grn_key_data_size, current_mysql_key); break; case TYPE_DOUBLE: - decode_double(current_grn_key, current_mysql_key, data_size); + decode_double(current_grn_key, grn_key_data_size, current_mysql_key); + break; + case TYPE_DATETIME: + { + long long int grn_time; + decode_long_long_int(current_grn_key, &grn_time); + TimeConverter time_converter; + long long int mysql_datetime = + time_converter.grn_time_to_mysql_datetime(grn_time); +#ifdef WORDS_BIGENDIAN + if (field->table && field->table->s->db_low_byte_first) { + int8store(current_mysql_key, mysql_datetime); + } else +#endif + { + longlongstore(current_mysql_key, mysql_datetime); + } + } + break; +#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2 + case TYPE_DATETIME2: + { + Field_datetimef *datetimef_field = + static_cast<Field_datetimef *>(field); + long long int grn_time; + grn_key_data_size = 8; + decode_long_long_int(current_grn_key, &grn_time); + TimeConverter time_converter; + MYSQL_TIME mysql_time; + mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME; + time_converter.grn_time_to_mysql_time(grn_time, &mysql_time); + long long int mysql_datetime_packed = + TIME_to_longlong_datetime_packed(&mysql_time); + my_datetime_packed_to_binary(mysql_datetime_packed, + current_mysql_key, + datetimef_field->decimals()); + } break; +#endif case TYPE_BYTE_SEQUENCE: - memcpy(current_mysql_key, current_grn_key, data_size); + memcpy(current_mysql_key, current_grn_key, grn_key_data_size); break; case TYPE_BYTE_REVERSE: - decode_reverse(current_grn_key, current_mysql_key, data_size); + decode_reverse(current_grn_key, grn_key_data_size, current_mysql_key); break; case TYPE_BYTE_BLOB: memcpy(current_mysql_key, @@ -240,6 +312,7 @@ namespace mrn { current_grn_key, data_size); data_size += HA_KEY_BLOB_LENGTH; + grn_key_data_size = data_size; break; } @@ -247,7 +320,7 @@ namespace mrn { break; } - current_grn_key += data_size; + current_grn_key += grn_key_data_size; current_mysql_key += data_size; *mysql_key_length += data_size; } @@ -275,10 +348,19 @@ namespace mrn { DataType data_type = TYPE_UNKNOWN; uint data_size = 0; get_key_info(key_part, &data_type, &data_size); - total_size += data_size; - if (data_type == TYPE_BYTE_BLOB) { - total_size += HA_KEY_BLOB_LENGTH; + switch (data_type) { +#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2 + case TYPE_DATETIME2: + data_size = 8; + break; +#endif + case TYPE_BYTE_BLOB: + data_size += HA_KEY_BLOB_LENGTH; + break; + default: + break; } + total_size += data_size; } DBUG_RETURN(total_size); @@ -331,10 +413,22 @@ namespace mrn { *data_size = 1; break; case MYSQL_TYPE_TIMESTAMP: + DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_TIMESTAMP")); + *data_type = TYPE_BYTE_REVERSE; + *data_size = key_part->length; + break; case MYSQL_TYPE_DATE: + DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DATE")); + *data_type = TYPE_BYTE_REVERSE; + *data_size = key_part->length; + break; case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_NEWDATE: DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DATETIME")); + *data_type = TYPE_DATETIME; + *data_size = key_part->length; + break; + case MYSQL_TYPE_NEWDATE: + DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_NEWDATE")); *data_type = TYPE_BYTE_REVERSE; *data_size = key_part->length; break; @@ -350,7 +444,7 @@ namespace mrn { break; case MYSQL_TYPE_TIME: DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_TIME")); - *data_type = TYPE_LONG_LONG_NUMBER; + *data_type = TYPE_NUMBER; *data_size = 3; break; case MYSQL_TYPE_VARCHAR: @@ -374,7 +468,7 @@ namespace mrn { #ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2 case MYSQL_TYPE_DATETIME2: DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DATETIME2")); - *data_type = TYPE_BYTE_SEQUENCE; + *data_type = TYPE_DATETIME2; *data_size = key_part->length; break; #endif @@ -428,77 +522,127 @@ namespace mrn { DBUG_VOID_RETURN; } - void MultipleColumnKeyCodec::encode_float(volatile float value, uint data_size, + void MultipleColumnKeyCodec::encode_number(const uchar *mysql_key, + uint mysql_key_size, + bool is_signed, + uchar *grn_key) { + MRN_DBUG_ENTER_METHOD(); + mrn_byte_order_host_to_network(grn_key, mysql_key, mysql_key_size); + if (is_signed) { + grn_key[0] ^= 0x80; + } + DBUG_VOID_RETURN; + } + + void MultipleColumnKeyCodec::decode_number(const uchar *grn_key, + uint grn_key_size, + bool is_signed, + uchar *mysql_key) { + MRN_DBUG_ENTER_METHOD(); + uchar buffer[8]; + memcpy(buffer, grn_key, grn_key_size); + if (is_signed) { + buffer[0] ^= 0x80; + } + mrn_byte_order_network_to_host(mysql_key, buffer, grn_key_size); + DBUG_VOID_RETURN; + } + + void MultipleColumnKeyCodec::encode_long_long_int(volatile long long int value, + uchar *grn_key) { + MRN_DBUG_ENTER_METHOD(); + uint value_size = 8; + mrn_byte_order_host_to_network(grn_key, &value, value_size); + grn_key[0] ^= 0x80; + DBUG_VOID_RETURN; + } + + void MultipleColumnKeyCodec::decode_long_long_int(const uchar *grn_key, + long long int *value) { + MRN_DBUG_ENTER_METHOD(); + uint grn_key_size = 8; + uchar buffer[8]; + memcpy(buffer, grn_key, grn_key_size); + buffer[0] ^= 0x80; + mrn_byte_order_network_to_host(value, buffer, grn_key_size); + DBUG_VOID_RETURN; + } + + void MultipleColumnKeyCodec::encode_float(volatile float value, + uint value_size, uchar *grn_key) { MRN_DBUG_ENTER_METHOD(); - int n_bits = (data_size * 8 - 1); + int n_bits = (value_size * 8 - 1); volatile int *int_value_pointer = (int *)(&value); int int_value = *int_value_pointer; int_value ^= ((int_value >> n_bits) | (1 << n_bits)); - mrn_byte_order_host_to_network(grn_key, &int_value, data_size); + mrn_byte_order_host_to_network(grn_key, &int_value, value_size); DBUG_VOID_RETURN; } void MultipleColumnKeyCodec::decode_float(const uchar *grn_key, - uchar *mysql_key, - uint data_size) { + uint grn_key_size, + uchar *mysql_key) { MRN_DBUG_ENTER_METHOD(); int int_value; - mrn_byte_order_host_to_network(&int_value, grn_key, data_size); - int max_bit = (data_size * 8 - 1); + mrn_byte_order_network_to_host(&int_value, grn_key, grn_key_size); + int max_bit = (grn_key_size * 8 - 1); *((int *)mysql_key) = int_value ^ (((int_value ^ (1 << max_bit)) >> max_bit) | (1 << max_bit)); DBUG_VOID_RETURN; } - void MultipleColumnKeyCodec::encode_double(volatile double value, uint data_size, + void MultipleColumnKeyCodec::encode_double(volatile double value, + uint value_size, uchar *grn_key) { MRN_DBUG_ENTER_METHOD(); - int n_bits = (data_size * 8 - 1); + int n_bits = (value_size * 8 - 1); volatile long long int *long_long_value_pointer = (long long int *)(&value); volatile long long int long_long_value = *long_long_value_pointer; long_long_value ^= ((long_long_value >> n_bits) | (1LL << n_bits)); - mrn_byte_order_host_to_network(grn_key, &long_long_value, data_size); + mrn_byte_order_host_to_network(grn_key, &long_long_value, value_size); DBUG_VOID_RETURN; } void MultipleColumnKeyCodec::decode_double(const uchar *grn_key, - uchar *mysql_key, - uint data_size) { + uint grn_key_size, + uchar *mysql_key) { MRN_DBUG_ENTER_METHOD(); long long int long_long_value; - mrn_byte_order_host_to_network(&long_long_value, grn_key, data_size); - int max_bit = (data_size * 8 - 1); + mrn_byte_order_network_to_host(&long_long_value, grn_key, grn_key_size); + int max_bit = (grn_key_size * 8 - 1); *((long long int *)mysql_key) = long_long_value ^ (((long_long_value ^ (1LL << max_bit)) >> max_bit) | (1LL << max_bit)); DBUG_VOID_RETURN; } - void MultipleColumnKeyCodec::encode_reverse(const uchar *mysql_key, uint data_size, + void MultipleColumnKeyCodec::encode_reverse(const uchar *mysql_key, + uint mysql_key_size, uchar *grn_key) { MRN_DBUG_ENTER_METHOD(); - for (uint i = 0; i < data_size; i++) { - grn_key[i] = mysql_key[data_size - i - 1]; + for (uint i = 0; i < mysql_key_size; i++) { + grn_key[i] = mysql_key[mysql_key_size - i - 1]; } DBUG_VOID_RETURN; } void MultipleColumnKeyCodec::decode_reverse(const uchar *grn_key, - uchar *mysql_key, - uint data_size) { + uint grn_key_size, + uchar *mysql_key) { MRN_DBUG_ENTER_METHOD(); - for (uint i = 0; i < data_size; i++) { - mysql_key[i] = grn_key[data_size - i - 1]; + for (uint i = 0; i < grn_key_size; i++) { + mysql_key[i] = grn_key[grn_key_size - i - 1]; } DBUG_VOID_RETURN; } - void MultipleColumnKeyCodec::encode_blob(Field *field, - const uchar *mysql_key, - uchar *grn_key, - uint *data_size) { + void MultipleColumnKeyCodec::encode_blob(const uchar *mysql_key, + uint *mysql_key_size, + Field *field, + uchar *grn_key) { + MRN_DBUG_ENTER_METHOD(); FieldNormalizer normalizer(ctx_, thread_, field); if (normalizer.should_normalize()) { #if HA_KEY_BLOB_LENGTH != 2 @@ -517,15 +661,15 @@ namespace mrn { uint16 new_blob_data_length; if (normalized_length <= UINT_MAX16) { memcpy(grn_key, normalized, normalized_length); - if (normalized_length < *data_size) { + if (normalized_length < *mysql_key_size) { memset(grn_key + normalized_length, - '\0', *data_size - normalized_length); + '\0', *mysql_key_size - normalized_length); } new_blob_data_length = normalized_length; } else { push_warning_printf(thread_, MRN_SEVERITY_WARNING, - WARN_DATA_TRUNCATED, + MRN_ERROR_CODE_DATA_TRUNCATE(thread_), "normalized data truncated " "for multiple column index: " "normalized-data-size: <%u> " @@ -539,11 +683,14 @@ namespace mrn { memcpy(grn_key, normalized, blob_data_length); new_blob_data_length = blob_data_length; } - memcpy(grn_key + *data_size, &new_blob_data_length, HA_KEY_BLOB_LENGTH); + memcpy(grn_key + *mysql_key_size, + &new_blob_data_length, + HA_KEY_BLOB_LENGTH); } else { - memcpy(grn_key + *data_size, mysql_key, HA_KEY_BLOB_LENGTH); - memcpy(grn_key, mysql_key + HA_KEY_BLOB_LENGTH, *data_size); + memcpy(grn_key + *mysql_key_size, mysql_key, HA_KEY_BLOB_LENGTH); + memcpy(grn_key, mysql_key + HA_KEY_BLOB_LENGTH, *mysql_key_size); } - *data_size += HA_KEY_BLOB_LENGTH; + *mysql_key_size += HA_KEY_BLOB_LENGTH; + DBUG_VOID_RETURN; } } diff --git a/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp b/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp index fc6ae285357..2b3f935d4e4 100644 --- a/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp +++ b/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp @@ -44,6 +44,10 @@ namespace mrn { TYPE_NUMBER, TYPE_FLOAT, TYPE_DOUBLE, + TYPE_DATETIME, +#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2 + TYPE_DATETIME2, +#endif TYPE_BYTE_SEQUENCE, TYPE_BYTE_REVERSE, TYPE_BYTE_BLOB @@ -56,14 +60,40 @@ namespace mrn { void get_key_info(KEY_PART_INFO *key_part, DataType *data_type, uint *data_size); - void encode_float(volatile float value, uint data_size, uchar *grn_key); - void decode_float(const uchar *grn_key, uchar *mysql_key, uint data_size); - void encode_double(volatile double value, uint data_size, uchar *grn_key); - void decode_double(const uchar *grn_key, uchar *mysql_key, uint data_size); - void encode_reverse(const uchar *mysql_key, uint data_size, uchar *grn_key); - void decode_reverse(const uchar *grn_key, uchar *mysql_key, uint data_size); - void encode_blob(Field *field, - const uchar *mysql_key, uchar *grn_key, uint *data_size); + void encode_number(const uchar *mysql_key, + uint mysql_key_size, + bool is_signed, + uchar *grn_key); + void decode_number(const uchar *grn_key, + uint grn_key_size, + bool is_signed, + uchar *mysql_key); + void encode_long_long_int(volatile long long int value, + uchar *grn_key); + void decode_long_long_int(const uchar *grn_key, + long long int *value); + void encode_float(volatile float value, + uint value_size, + uchar *grn_key); + void decode_float(const uchar *grn_key, + uint grn_key_size, + uchar *mysql_key); + void encode_double(volatile double value, + uint value_size, + uchar *grn_key); + void decode_double(const uchar *grn_key, + uint grn_key_size, + uchar *mysql_key); + void encode_reverse(const uchar *mysql_key, + uint mysql_key_size, + uchar *grn_key); + void decode_reverse(const uchar *grn_key, + uint grn_key_size, + uchar *mysql_key); + void encode_blob(const uchar *mysql_key, + uint *mysql_key_size, + Field *field, + uchar *grn_key); }; } diff --git a/storage/mroonga/lib/mrn_mysqlservices.cpp b/storage/mroonga/lib/mrn_mysqlservices.cpp index 9c7af9acfe0..693aa8607c3 100644 --- a/storage/mroonga/lib/mrn_mysqlservices.cpp +++ b/storage/mroonga/lib/mrn_mysqlservices.cpp @@ -17,10 +17,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <mrn_mysql.h> #include <mrn_mysql_compat.h> diff --git a/storage/mroonga/lib/mrn_smart_grn_obj.cpp b/storage/mroonga/lib/mrn_smart_grn_obj.cpp index 9dbae6528f9..40ea9cb079c 100644 --- a/storage/mroonga/lib/mrn_smart_grn_obj.cpp +++ b/storage/mroonga/lib/mrn_smart_grn_obj.cpp @@ -50,4 +50,10 @@ namespace mrn { grn_obj *SmartGrnObj::get() { return obj_; } + + grn_obj *SmartGrnObj::release() { + grn_obj *obj = obj_; + obj_ = NULL; + return obj; + } } diff --git a/storage/mroonga/lib/mrn_smart_grn_obj.hpp b/storage/mroonga/lib/mrn_smart_grn_obj.hpp index c9c86f3e46e..0a44a6ac9db 100644 --- a/storage/mroonga/lib/mrn_smart_grn_obj.hpp +++ b/storage/mroonga/lib/mrn_smart_grn_obj.hpp @@ -33,6 +33,7 @@ namespace mrn { ~SmartGrnObj(); grn_obj *get(); + grn_obj *release(); }; } diff --git a/storage/mroonga/lib/mrn_time_converter.cpp b/storage/mroonga/lib/mrn_time_converter.cpp index 63b2e53766d..3c6821c8d11 100644 --- a/storage/mroonga/lib/mrn_time_converter.cpp +++ b/storage/mroonga/lib/mrn_time_converter.cpp @@ -1,7 +1,7 @@ /* -*- c-basic-offset: 2 -*- */ /* Copyright(C) 2010-2013 Kentoku SHIBA - Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> + Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -18,10 +18,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "mrn_time_converter.hpp" #ifdef min @@ -257,4 +253,43 @@ namespace mrn { } DBUG_VOID_RETURN; } + + long long int TimeConverter::mysql_datetime_to_grn_time(long long int mysql_datetime, + bool *truncated) { + MRN_DBUG_ENTER_METHOD(); + + MYSQL_TIME mysql_time; + mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME; + mysql_time.neg = 0; + mysql_time.second_part = 0; + mysql_time.second = (mysql_datetime % 100); + mysql_time.minute = (mysql_datetime / 100 % 100); + mysql_time.hour = (mysql_datetime / 10000 % 100); + mysql_time.day = (mysql_datetime / 1000000 % 100); + mysql_time.month = (mysql_datetime / 100000000 % 100); + mysql_time.year = (mysql_datetime / 10000000000LL % 10000); + + long long int grn_time = mysql_time_to_grn_time(&mysql_time, truncated); + + DBUG_RETURN(grn_time); + } + + long long int TimeConverter::grn_time_to_mysql_datetime(long long int grn_time) { + MRN_DBUG_ENTER_METHOD(); + + MYSQL_TIME mysql_time; + mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME; + + grn_time_to_mysql_time(grn_time, &mysql_time); + + long long int mysql_datetime = + (mysql_time.second * 1) + + (mysql_time.minute * 100) + + (mysql_time.hour * 10000) + + (mysql_time.day * 1000000) + + (mysql_time.month * 100000000) + + (mysql_time.year * 10000000000LL); + + DBUG_RETURN(mysql_datetime); + } } diff --git a/storage/mroonga/lib/mrn_time_converter.hpp b/storage/mroonga/lib/mrn_time_converter.hpp index c5c69a0a8ad..9d297f92e59 100644 --- a/storage/mroonga/lib/mrn_time_converter.hpp +++ b/storage/mroonga/lib/mrn_time_converter.hpp @@ -1,7 +1,7 @@ /* -*- c-basic-offset: 2 -*- */ /* Copyright(C) 2010-2013 Kentoku SHIBA - Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> + Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,9 +21,10 @@ #ifndef MRN_TIME_CONVERTER_HPP_ #define MRN_TIME_CONVERTER_HPP_ -#include <groonga.h> #include <mrn_mysql_compat.h> +#include <groonga.h> + namespace mrn { class TimeConverter { public: @@ -34,10 +35,13 @@ namespace mrn { long long int mysql_time_to_grn_time(MYSQL_TIME *mysql_time, bool *truncated); + long long int mysql_datetime_to_grn_time(long long int mysql_datetime, + bool *truncated); long long int tm_to_grn_time(struct tm *time, int usec, bool *truncated); void grn_time_to_mysql_time(long long int grn_time, MYSQL_TIME *mysql_time); + long long int grn_time_to_mysql_datetime(long long int grn_time); private: time_t tm_to_time_gm(struct tm *time, bool *truncated); diff --git a/storage/mroonga/lib/mrn_value_decoder.cpp b/storage/mroonga/lib/mrn_value_decoder.cpp index 8356789915f..c01b01718b1 100644 --- a/storage/mroonga/lib/mrn_value_decoder.cpp +++ b/storage/mroonga/lib/mrn_value_decoder.cpp @@ -60,5 +60,16 @@ namespace mrn { #endif DBUG_VOID_RETURN; } + void decode(long long int *dest, const uchar *source) { + MRN_DBUG_ENTER_FUNCTION(); +#ifdef MRN_DEST_IS_POINTER + longlongget(dest, source); +#else + long long int value; + longlongget(value, source); + *dest = value; +#endif + DBUG_VOID_RETURN; + } } } diff --git a/storage/mroonga/lib/mrn_value_decoder.hpp b/storage/mroonga/lib/mrn_value_decoder.hpp index 8a48de0b003..fe651f574f0 100644 --- a/storage/mroonga/lib/mrn_value_decoder.hpp +++ b/storage/mroonga/lib/mrn_value_decoder.hpp @@ -27,6 +27,7 @@ namespace mrn { void decode(uint16 *dest, const uchar *source); void decode(float *dest, const uchar *source); void decode(double *dest, const uchar *source); + void decode(long long int *dest, const uchar *source); } } diff --git a/storage/mroonga/mrn_constants.hpp b/storage/mroonga/mrn_constants.hpp index 5bc6da6b9b6..b11ebe8bd93 100644 --- a/storage/mroonga/mrn_constants.hpp +++ b/storage/mroonga/mrn_constants.hpp @@ -42,8 +42,8 @@ #define MRN_COLUMN_NAME_ID "_id" #define MRN_COLUMN_NAME_KEY "_key" #define MRN_COLUMN_NAME_SCORE "_score" -#ifndef MRN_PARSER_DEFAULT -# define MRN_PARSER_DEFAULT "TokenBigram" +#ifndef MRN_DEFAULT_TOKENIZER +# define MRN_DEFAULT_TOKENIZER "TokenBigram" #endif #endif /* MRN_CONSTANTS_HPP_ */ diff --git a/storage/mroonga/mrn_err.h b/storage/mroonga/mrn_err.h index cd4515a034e..d109f87bb48 100644 --- a/storage/mroonga/mrn_err.h +++ b/storage/mroonga/mrn_err.h @@ -1,4 +1,6 @@ -/* Copyright(C) 2011 Kentoku SHIBA +/* + Copyright(C) 2011 Kentoku SHIBA + Copyright(C) 2014-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -33,7 +35,7 @@ "The column flag '%-.64s' is unsupported. It is ignored" #define ER_MRN_INVALID_COLUMN_FLAG_NUM 16507 #define ER_MRN_INVALID_COLUMN_FLAG_STR \ - "The column flag '%-.64s' is invalid. '%-64s' is used instead" + "The column flag '%-.64s' is invalid. It is ignored" #define ER_MRN_INVALID_INDEX_FLAG_NUM 16508 #define ER_MRN_INVALID_INDEX_FLAG_STR \ "The index flag '%-.64s' is invalid. It is ignored" diff --git a/storage/mroonga/mrn_mysql_compat.h b/storage/mroonga/mrn_mysql_compat.h index a717220a35c..660c72b4d25 100644 --- a/storage/mroonga/mrn_mysql_compat.h +++ b/storage/mroonga/mrn_mysql_compat.h @@ -33,20 +33,11 @@ #endif #if defined(MRN_MARIADB_P) -# if MYSQL_VERSION_ID >= 50302 && MYSQL_VERSION_ID < 100000 +# if MYSQL_VERSION_ID < 100000 typedef COST_VECT Cost_estimate; # endif #endif -#if MYSQL_VERSION_ID >= 50516 -# define MRN_PLUGIN_HAVE_FLAGS 1 -#endif - -// for MySQL < 5.5 -#ifndef MY_ALL_CHARSETS_SIZE -# define MY_ALL_CHARSETS_SIZE 256 -#endif - #ifndef MRN_MARIADB_P typedef char *range_id_t; #endif @@ -79,9 +70,11 @@ #if MYSQL_VERSION_ID >= 50607 # if MYSQL_VERSION_ID >= 100007 && defined(MRN_MARIADB_P) # define MRN_GET_ERROR_MESSAGE thd_get_error_message(current_thd) +# define MRN_GET_ERROR_NUMBER thd_get_error_number(current_thd) # define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) thd_get_error_row(thd) # else # define MRN_GET_ERROR_MESSAGE current_thd->get_stmt_da()->message() +# define MRN_GET_ERROR_NUMBER current_thd->get_stmt_da()->sql_errno() # if MYSQL_VERSION_ID >= 50706 # define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) \ thd->get_stmt_da()->current_row_for_condition() @@ -91,20 +84,16 @@ # endif # endif #else -# if MYSQL_VERSION_ID >= 50500 -# define MRN_GET_ERROR_MESSAGE current_thd->stmt_da->message() -# define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) thd->warning_info->current_row_for_warning() -# else -# define MRN_GET_ERROR_MESSAGE current_thd->main_da.message() -# define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) thd->row_count -# endif +# define MRN_GET_ERROR_MESSAGE current_thd->stmt_da->message() +# define MRN_GET_ERROR_NUMBER current_thd->stmt_da->sql_errno() +# define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) thd->warning_info->current_row_for_warning() #endif #if MYSQL_VERSION_ID >= 50607 && !defined(MRN_MARIADB_P) # define MRN_ITEM_HAVE_ITEM_NAME #endif -#if MYSQL_VERSION_ID >= 50500 && MYSQL_VERSION_ID < 100000 +#if MYSQL_VERSION_ID < 100000 # define MRN_HAVE_TABLE_DEF_CACHE #endif @@ -124,10 +113,6 @@ # define MRN_TABLE_SHARE_HAVE_LOCK_SHARE #endif -#if MYSQL_VERSION_ID >= 50404 -# define MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA -#endif - #ifndef TIME_FUZZY_DATE /* For MariaDB 10. */ # ifdef TIME_FUZZY_DATES @@ -217,4 +202,42 @@ # define MRN_FORMAT_STRING_LENGTH "u" #endif +#ifdef MRN_MARIADB_P +# define MRN_SUPPORT_CUSTOM_OPTIONS +#endif + +#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000 +# if MYSQL_VERSION_ID >= 100104 +# define mrn_init_sql_alloc(thd, mem_root) \ + init_sql_alloc(mem_root, \ + TABLE_ALLOC_BLOCK_SIZE, \ + 0, \ + MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC)) +# else +# define mrn_init_sql_alloc(thd, mem_root) \ + init_sql_alloc(mem_root, \ + TABLE_ALLOC_BLOCK_SIZE, \ + 0, \ + MYF(0)) +# endif +#else +# define mrn_init_sql_alloc(thd, mem_root) \ + init_sql_alloc(mem_root, \ + TABLE_ALLOC_BLOCK_SIZE, \ + 0) +#endif + +#ifdef MRN_MARIADB_P +# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning +#else +# if MYSQL_VERSION_ID >= 50706 +# define MRN_ABORT_ON_WARNING(thd) false +# else +# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning +# endif +#endif + +#define MRN_ERROR_CODE_DATA_TRUNCATE(thd) \ + (MRN_ABORT_ON_WARNING(thd) ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED) + #endif /* MRN_MYSQL_COMPAT_H_ */ diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp index 890d21a415b..af07dc09cf3 100644 --- a/storage/mroonga/mrn_table.cpp +++ b/storage/mroonga/mrn_table.cpp @@ -35,10 +35,18 @@ #include "mrn_variables.hpp" #include <mrn_lock.hpp> -#if MYSQL_VERSION_ID >= 50603 -# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name), TRUE) +#ifdef MRN_MARIADB_P +# if MYSQL_VERSION_ID >= 100100 +# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name), TRUE) +# else +# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name)) +# endif #else -# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name)) +# if MYSQL_VERSION_ID >= 50603 +# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name), TRUE) +# else +# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name)) +# endif #endif #if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P) @@ -68,9 +76,7 @@ extern "C" { # ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE extern PSI_mutex_key *mrn_table_share_lock_share; # endif -# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA extern PSI_mutex_key *mrn_table_share_lock_ha_data; -# endif # endif extern PSI_mutex_key mrn_share_mutex_key; extern PSI_mutex_key mrn_long_term_share_auto_inc_mutex_key; @@ -80,7 +86,7 @@ extern HASH mrn_open_tables; extern mysql_mutex_t mrn_open_tables_mutex; extern HASH mrn_long_term_share; extern mysql_mutex_t mrn_long_term_share_mutex; -extern char *mrn_default_parser; +extern char *mrn_default_tokenizer; extern char *mrn_default_wrapper_engine; extern handlerton *mrn_hton_ptr; extern HASH mrn_allocated_thds; @@ -333,8 +339,8 @@ int mrn_parse_table_param(MRN_SHARE *share, TABLE *table) for (i = 2; i > 0; i--) #endif { - const char *params_string_value; - uint params_string_length; + const char *params_string_value = NULL; + uint params_string_length = 0; switch (i) { #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -515,16 +521,16 @@ int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i) #if MYSQL_VERSION_ID >= 50500 if (key_info->comment.length == 0) { - if (share->key_parser[i]) { - my_free(share->key_parser[i]); + if (share->key_tokenizer[i]) { + my_free(share->key_tokenizer[i]); } - if ( - !(share->key_parser[i] = mrn_my_strdup(mrn_default_parser, MYF(MY_WME))) - ) { + share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME)); + if (!share->key_tokenizer[i]) { error = HA_ERR_OUT_OF_MEM; goto error; } - share->key_parser_length[i] = strlen(share->key_parser[i]); + share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]); + DBUG_RETURN(0); } DBUG_PRINT("info", ("mroonga create comment string")); @@ -572,21 +578,23 @@ int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i) MRN_PARAM_STR_LIST("table", index_table, i); break; case 6: - MRN_PARAM_STR_LIST("parser", key_parser, i); + MRN_PARAM_STR_LIST("parser", key_tokenizer, i); + break; + case 9: + MRN_PARAM_STR_LIST("tokenizer", key_tokenizer, i); break; default: break; } } #endif - if (!share->key_parser[i]) { - if ( - !(share->key_parser[i] = mrn_my_strdup(mrn_default_parser, MYF(MY_WME))) - ) { + if (!share->key_tokenizer[i]) { + share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME)); + if (!share->key_tokenizer[i]) { error = HA_ERR_OUT_OF_MEM; goto error; } - share->key_parser_length[i] = strlen(share->key_parser[i]); + share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]); } if (param_string) @@ -687,6 +695,9 @@ int mrn_add_column_param(MRN_SHARE *share, Field *field, int i) case 5: MRN_PARAM_STR_LIST("flags", col_flags, i); break; + case 12: + MRN_PARAM_STR_LIST("groonga_type", col_type, i); + break; default: break; } @@ -741,8 +752,8 @@ int mrn_free_share_alloc( { if (share->index_table && share->index_table[i]) my_free(share->index_table[i]); - if (share->key_parser[i]) - my_free(share->key_parser[i]); + if (share->key_tokenizer[i]) + my_free(share->key_tokenizer[i]); } for (i = 0; i < share->table_share->fields; i++) { @@ -817,9 +828,9 @@ error_alloc_long_term_share: MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) { MRN_SHARE *share; - char *tmp_name, **index_table, **key_parser, **col_flags, **col_type; + char *tmp_name, **index_table, **key_tokenizer, **col_flags, **col_type; uint length, *wrap_key_nr, *index_table_length; - uint *key_parser_length, *col_flags_length, *col_type_length, i, j; + uint *key_tokenizer_length, *col_flags_length, *col_type_length, i, j; KEY *wrap_key_info; TABLE_SHARE *wrap_table_share; MRN_DBUG_ENTER_FUNCTION(); @@ -834,8 +845,8 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) &tmp_name, length + 1, &index_table, sizeof(char *) * table->s->keys, &index_table_length, sizeof(uint) * table->s->keys, - &key_parser, sizeof(char *) * table->s->keys, - &key_parser_length, sizeof(uint) * table->s->keys, + &key_tokenizer, sizeof(char *) * table->s->keys, + &key_tokenizer_length, sizeof(uint) * table->s->keys, &col_flags, sizeof(char *) * table->s->fields, &col_flags_length, sizeof(uint) * table->s->fields, &col_type, sizeof(char *) * table->s->fields, @@ -853,8 +864,8 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) share->table_name = tmp_name; share->index_table = index_table; share->index_table_length = index_table_length; - share->key_parser = key_parser; - share->key_parser_length = key_parser_length; + share->key_tokenizer = key_tokenizer; + share->key_tokenizer_length = key_tokenizer_length; share->col_flags = col_flags; share->col_flags_length = col_flags_length; share->col_type = col_type; @@ -903,6 +914,7 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) share->wrap_primary_key = MAX_KEY; } memcpy(wrap_table_share, table->s, sizeof(*wrap_table_share)); + mrn_init_sql_alloc(current_thd, &(wrap_table_share->mem_root)); wrap_table_share->keys = share->wrap_keys; wrap_table_share->key_info = share->wrap_key_info; wrap_table_share->primary_key = share->wrap_primary_key; @@ -917,20 +929,18 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) &(wrap_table_share->LOCK_share), MY_MUTEX_INIT_SLOW); # endif #endif -#ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA -# ifdef WIN32 +#ifdef WIN32 mysql_mutex_init(*mrn_table_share_lock_ha_data, &(wrap_table_share->LOCK_ha_data), MY_MUTEX_INIT_FAST); -# else +#else mysql_mutex_init(key_TABLE_SHARE_LOCK_ha_data, &(wrap_table_share->LOCK_ha_data), MY_MUTEX_INIT_FAST); -# endif #endif share->wrap_table_share = wrap_table_share; } if (mysql_mutex_init(mrn_share_mutex_key, - &share->mutex, + &share->record_mutex, MY_MUTEX_INIT_FAST) != 0) { *error = HA_ERR_OUT_OF_MEM; @@ -953,7 +963,7 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) error_hash_insert: error_get_long_term_share: - mysql_mutex_destroy(&share->mutex); + mysql_mutex_destroy(&share->record_mutex); error_init_mutex: error_parse_table_param: mrn_free_share_alloc(share); @@ -973,14 +983,13 @@ int mrn_free_share(MRN_SHARE *share) plugin_unlock(NULL, share->plugin); mrn_free_share_alloc(share); thr_lock_delete(&share->lock); - mysql_mutex_destroy(&share->mutex); + mysql_mutex_destroy(&share->record_mutex); if (share->wrapper_mode) { #ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE mysql_mutex_destroy(&(share->wrap_table_share->LOCK_share)); #endif -#ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA mysql_mutex_destroy(&(share->wrap_table_share->LOCK_ha_data)); -#endif + free_root(&(share->wrap_table_share->mem_root), MYF(0)); } my_free(share); } @@ -1114,7 +1123,7 @@ st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create) if (slot_data == NULL) { slot_data = (st_mrn_slot_data*) malloc(sizeof(st_mrn_slot_data)); slot_data->last_insert_record_id = GRN_ID_NIL; - slot_data->first_alter_share = NULL; + slot_data->first_wrap_hton = NULL; slot_data->alter_create_info = NULL; slot_data->disable_keys_create_info = NULL; slot_data->alter_connect_string = NULL; @@ -1132,22 +1141,21 @@ st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create) DBUG_RETURN(slot_data); } -void mrn_clear_alter_share(THD *thd) +void mrn_clear_slot_data(THD *thd) { MRN_DBUG_ENTER_FUNCTION(); st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE); if (slot_data) { - if (slot_data->first_alter_share) { - st_mrn_alter_share *tmp_alter_share; - st_mrn_alter_share *alter_share = slot_data->first_alter_share; - while (alter_share) + if (slot_data->first_wrap_hton) { + st_mrn_wrap_hton *tmp_wrap_hton; + st_mrn_wrap_hton *wrap_hton = slot_data->first_wrap_hton; + while (wrap_hton) { - tmp_alter_share = alter_share->next; - mrn_free_tmp_table_share(alter_share->alter_share); - free(alter_share); - alter_share = tmp_alter_share; + tmp_wrap_hton = wrap_hton->next; + free(wrap_hton); + wrap_hton = tmp_wrap_hton; } - slot_data->first_alter_share = NULL; + slot_data->first_wrap_hton = NULL; } slot_data->alter_create_info = NULL; slot_data->disable_keys_create_info = NULL; diff --git a/storage/mroonga/mrn_table.hpp b/storage/mroonga/mrn_table.hpp index 9118455b53d..0066fc23f08 100644 --- a/storage/mroonga/mrn_table.hpp +++ b/storage/mroonga/mrn_table.hpp @@ -1,7 +1,7 @@ /* -*- c-basic-offset: 2 -*- */ /* Copyright(C) 2011-2013 Kentoku SHIBA - Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> + Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -43,7 +43,7 @@ typedef struct st_mroonga_share char *table_name; uint table_name_length; uint use_count; - mysql_mutex_t mutex; + mysql_mutex_t record_mutex; THR_LOCK lock; TABLE_SHARE *table_share; TABLE_SHARE *wrap_table_share; @@ -60,11 +60,11 @@ typedef struct st_mroonga_share plugin_ref plugin; handlerton *hton; char **index_table; - char **key_parser; + char **key_tokenizer; char **col_flags; char **col_type; uint *index_table_length; - uint *key_parser_length; + uint *key_tokenizer_length; uint *col_flags_length; uint *col_type_length; uint *wrap_key_nr; @@ -78,17 +78,17 @@ typedef struct st_mroonga_share bool disable_keys; } MRN_SHARE; -struct st_mrn_alter_share +struct st_mrn_wrap_hton { char path[FN_REFLEN + 1]; - TABLE_SHARE *alter_share; - st_mrn_alter_share *next; + handlerton *hton; + st_mrn_wrap_hton *next; }; struct st_mrn_slot_data { grn_id last_insert_record_id; - st_mrn_alter_share *first_alter_share; + st_mrn_wrap_hton *first_wrap_hton; HA_CREATE_INFO *alter_create_info; HA_CREATE_INFO *disable_keys_create_info; char *alter_connect_string; @@ -167,7 +167,7 @@ void mrn_free_tmp_table_share(TABLE_SHARE *table_share); KEY *mrn_create_key_info_for_table(MRN_SHARE *share, TABLE *table, int *error); void mrn_set_bitmap_by_key(MY_BITMAP *map, KEY *key_info); st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create); -void mrn_clear_alter_share(THD *thd); +void mrn_clear_slot_data(THD *thd); #ifdef __cplusplus } diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc new file mode 100644 index 00000000000..02c21ff32c6 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc @@ -0,0 +1,19 @@ +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--disable_query_log +let $libgroonga_embedded = `SELECT @@mroonga_libgroonga_embedded;`; +--enable_query_log diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc new file mode 100644 index 00000000000..414eb1702de --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc @@ -0,0 +1,22 @@ +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/check_libgroonga_embedded.inc + +if ($libgroonga_embedded) { + --source ../../include/mroonga/have_mroonga_deinit.inc + skip "This test requires plugin_register of Groonga. libgroonga embedded build doesn't support it."; +} diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_fulltext_index_comment.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc index e8c79936cc6..24c65a61dd9 100644 --- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_fulltext_index_comment.inc +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc @@ -1,4 +1,4 @@ -# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -14,12 +14,8 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---source ../../include/mroonga/check_version.inc +--source ../../include/mroonga/check_mariadb.inc -if ($version_55_or_later) { - let $fulltext_index_comment = 1; -} - -if (!$fulltext_index_comment) { - skip Fulltext index comment is available in version 5.5 or later; +if (!$mariadb) { + skip This test is for MariaDB; } diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc index 2ebec2df8c4..cd17adebfe9 100644 --- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc @@ -38,6 +38,9 @@ if (!$have_default_storage_engine_variable) { let have_default_tmp_storage_engine_variable=`SELECT 1 FROM information_schema.global_variables WHERE variable_name = "default_tmp_storage_engine"`; if ($have_default_tmp_storage_engine_variable) { let original_default_tmp_storage_engine=`SELECT variable_value FROM information_schema.global_variables WHERE variable_name = "default_tmp_storage_engine"`; + if (!$original_default_tmp_storage_engine) { + let original_default_tmp_storage_engine=NULL; + } set default_tmp_storage_engine=Mroonga; } diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_flags.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result index e441df32c92..e441df32c92 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_flags.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result new file mode 100644 index 00000000000..6f2a1870ac7 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result @@ -0,0 +1,17 @@ +CREATE TABLE tags ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY +) DEFAULT CHARSET=utf8; +ALTER TABLE tags ADD COLUMN name VARCHAR(64) FLAGS='COLUMN_VECTOR'; +SHOW CREATE TABLE tags; +Table Create Table +tags CREATE TABLE `tags` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(64) DEFAULT NULL `FLAGS`='COLUMN_VECTOR', + PRIMARY KEY (`id`) +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +SELECT mroonga_command("dump --dump_plugins no"); +mroonga_command("dump --dump_plugins no") +table_create tags TABLE_PAT_KEY UInt32 +column_create tags id COLUMN_SCALAR UInt32 +column_create tags name COLUMN_VECTOR ShortText +DROP TABLE tags; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result new file mode 100644 index 00000000000..0bd8985f2e8 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result @@ -0,0 +1,18 @@ +CREATE TABLE tags ( +id INT UNSIGNED PRIMARY KEY +) DEFAULT CHARSET=utf8; +CREATE TABLE bugs ( +id INT UNSIGNED PRIMARY KEY +) DEFAULT CHARSET=utf8; +ALTER TABLE bugs ADD COLUMN name VARCHAR(64) COMMENT 'groonga_type "tags"'; +SELECT mroonga_command("dump --dump_plugins no"); +mroonga_command("dump --dump_plugins no") +table_create tags TABLE_PAT_KEY UInt32 +column_create tags id COLUMN_SCALAR UInt32 + +table_create bugs TABLE_PAT_KEY UInt32 +column_create bugs id COLUMN_SCALAR UInt32 + +column_create bugs name COLUMN_SCALAR tags +DROP TABLE bugs; +DROP TABLE tags; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result new file mode 100644 index 00000000000..fe484372999 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result @@ -0,0 +1,26 @@ +CREATE TABLE tags ( +id INT UNSIGNED PRIMARY KEY +) DEFAULT CHARSET=utf8; +CREATE TABLE bugs ( +id INT UNSIGNED PRIMARY KEY +) DEFAULT CHARSET=utf8; +ALTER TABLE bugs ADD COLUMN name VARCHAR(64) GROONGA_TYPE='tags'; +SHOW CREATE TABLE bugs; +Table Create Table +bugs CREATE TABLE `bugs` ( + `id` int(10) unsigned NOT NULL, + `name` varchar(64) DEFAULT NULL `GROONGA_TYPE`='tags', + PRIMARY KEY (`id`), + CONSTRAINT `name` FOREIGN KEY (`name`) REFERENCES `test`.`tags` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +SELECT mroonga_command("dump --dump_plugins no"); +mroonga_command("dump --dump_plugins no") +table_create tags TABLE_PAT_KEY UInt32 +column_create tags id COLUMN_SCALAR UInt32 + +table_create bugs TABLE_PAT_KEY UInt32 +column_create bugs id COLUMN_SCALAR UInt32 + +column_create bugs name COLUMN_SCALAR tags +DROP TABLE bugs; +DROP TABLE tags; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_type.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result index b4c3044c7d5..b4c3044c7d5 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_type.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result index 21784decb88..65e608dddeb 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true SET NAMES utf8; CREATE TABLE memos ( diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result index 1c96236230b..60d302cc6a5 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true CREATE TABLE terms ( term VARCHAR(64) NOT NULL PRIMARY KEY, diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result new file mode 100644 index 00000000000..c4d73e2f57d --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result @@ -0,0 +1,23 @@ +DROP TABLE IF EXISTS timestamps; +CREATE TABLE timestamps ( +id INT PRIMARY KEY AUTO_INCREMENT, +create_dt DATETIME +) DEFAULT CHARSET UTF8; +SHOW CREATE TABLE timestamps; +Table Create Table +timestamps CREATE TABLE `timestamps` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `create_dt` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +SET sql_mode='STRICT_TRANS_TABLES'; +INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00"); +ERROR 22003: Out of range value for column 'create_dt' at row 1 +SET sql_mode=default; +SELECT * FROM timestamps; +id create_dt +INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00"); +SELECT * FROM timestamps; +id create_dt +2 2015-06-17 00:00:00 +DROP TABLE timestamps; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_vector.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_comment.result index af3c19e9bb0..af3c19e9bb0 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_vector.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_comment.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result new file mode 100644 index 00000000000..9e089e53f49 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result @@ -0,0 +1,17 @@ +CREATE TABLE bugs ( +id INT UNSIGNED PRIMARY KEY, +tags TEXT FLAGS='COLUMN_VECTOR' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE bugs; +Table Create Table +bugs CREATE TABLE `bugs` ( + `id` int(10) unsigned NOT NULL, + `tags` text `FLAGS`='COLUMN_VECTOR', + PRIMARY KEY (`id`) +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +SELECT mroonga_command("dump --dump_plugins no"); +mroonga_command("dump --dump_plugins no") +table_create bugs TABLE_PAT_KEY UInt32 +column_create bugs id COLUMN_SCALAR UInt32 +column_create bugs tags COLUMN_VECTOR LongText +DROP TABLE bugs; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result new file mode 100644 index 00000000000..5e5980ac62b --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result @@ -0,0 +1,18 @@ +CREATE TABLE tags ( +name VARCHAR(64) PRIMARY KEY +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +CREATE TABLE bugs ( +id INT UNSIGNED PRIMARY KEY, +tag VARCHAR(64) COMMENT 'groonga_type "tags"' +) DEFAULT CHARSET=utf8; +SELECT mroonga_command("dump --dump_plugins no"); +mroonga_command("dump --dump_plugins no") +table_create tags TABLE_PAT_KEY ShortText +column_create tags name COLUMN_SCALAR ShortText + +table_create bugs TABLE_PAT_KEY UInt32 +column_create bugs id COLUMN_SCALAR UInt32 + +column_create bugs tag COLUMN_SCALAR tags +DROP TABLE bugs; +DROP TABLE tags; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result new file mode 100644 index 00000000000..99dc30aaa02 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS bugs; +CREATE TABLE bugs ( +id INT UNSIGNED PRIMARY KEY, +tag VARCHAR(64) COMMENT 'groonga_type "Nonexistent"' +) DEFAULT CHARSET=utf8mb4; +ERROR HY000: unknown custom Groonga type name for <tag> column: <Nonexistent> diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result new file mode 100644 index 00000000000..24941f043c7 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result @@ -0,0 +1,26 @@ +CREATE TABLE tags ( +name VARCHAR(64) PRIMARY KEY +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +CREATE TABLE bugs ( +id INT UNSIGNED PRIMARY KEY, +tag VARCHAR(64) GROONGA_TYPE='tags' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE bugs; +Table Create Table +bugs CREATE TABLE `bugs` ( + `id` int(10) unsigned NOT NULL, + `tag` varchar(64) DEFAULT NULL `GROONGA_TYPE`='tags', + PRIMARY KEY (`id`), + CONSTRAINT `tag` FOREIGN KEY (`tag`) REFERENCES `test`.`tags` (`name`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +SELECT mroonga_command("dump --dump_plugins no"); +mroonga_command("dump --dump_plugins no") +table_create tags TABLE_PAT_KEY ShortText +column_create tags name COLUMN_SCALAR ShortText + +table_create bugs TABLE_PAT_KEY UInt32 +column_create bugs id COLUMN_SCALAR UInt32 + +column_create bugs tag COLUMN_SCALAR tags +DROP TABLE bugs; +DROP TABLE tags; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_reference_type.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_comment.result index dc3f39d286e..dc3f39d286e 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_reference_type.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_comment.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result new file mode 100644 index 00000000000..a66a2bd2185 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS bugs; +CREATE TABLE bugs ( +id INT UNSIGNED PRIMARY KEY, +tag VARCHAR(64) COMMENT 'type "Nonexistent"' +) DEFAULT CHARSET=utf8mb4; +ERROR HY000: unknown custom Groonga type name for <tag> column: <Nonexistent> diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result new file mode 100644 index 00000000000..828de3ebbad --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result @@ -0,0 +1,9 @@ +SET NAMES utf8; +CREATE TABLE memos ( +content VARCHAR(64) NOT NULL, +FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"' +) DEFAULT CHARSET=utf8; +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); +mroonga_command("dump --dump_plugins no --dump_schema no") +column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result index c9283db72bb..b5368b433e6 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result @@ -1,7 +1,7 @@ SET NAMES utf8; CREATE TABLE memos ( content VARCHAR(64) NOT NULL, -FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"' +FULLTEXT INDEX (content) COMMENT 'flags "NONE"' ) DEFAULT CHARSET=utf8; SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); mroonga_command("dump --dump_plugins no --dump_schema no") diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result new file mode 100644 index 00000000000..7e0d29a1e1f --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result @@ -0,0 +1,15 @@ +SET NAMES utf8; +CREATE TABLE memos ( +content VARCHAR(64) NOT NULL, +FULLTEXT INDEX (content) FLAGS='WITH_POSITION|WITH_WEIGHT' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; +Table Create Table +memos CREATE TABLE `memos` ( + `content` varchar(64) NOT NULL, + FULLTEXT KEY `content` (`content`) `FLAGS`='WITH_POSITION|WITH_WEIGHT' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); +mroonga_command("dump --dump_plugins no --dump_schema no") +column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result new file mode 100644 index 00000000000..c9283db72bb --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result @@ -0,0 +1,9 @@ +SET NAMES utf8; +CREATE TABLE memos ( +content VARCHAR(64) NOT NULL, +FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"' +) DEFAULT CHARSET=utf8; +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); +mroonga_command("dump --dump_plugins no --dump_schema no") +column_create memos-content index COLUMN_INDEX memos content +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_with_position_and_with_weight.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result index 853845d5c15..853845d5c15 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_with_position_and_with_weight.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_comment.result index e2d405a1e35..e2d405a1e35 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_comment.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_comment.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.result index 9d12e2d0e39..9d12e2d0e39 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_none.result index 52c6f055e88..52c6f055e88 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_none.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_parameter.result new file mode 100644 index 00000000000..d68de436c92 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_parameter.result @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS memos; +SET NAMES utf8; +CREATE TABLE memos ( +id INT NOT NULL PRIMARY KEY, +content TEXT NOT NULL, +FULLTEXT INDEX (content) NORMALIZER='NormalizerAuto' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; +Table Create Table +memos CREATE TABLE `memos` ( + `id` int(11) NOT NULL, + `content` text NOT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `content` (`content`) `NORMALIZER`='NormalizerAuto' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ"); +SELECT * FROM memos +WHERE MATCH (content) AGAINST ("+ã‚«ãƒãƒªãƒ¼" IN BOOLEAN MODE); +id content +1 1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔㌠+DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result new file mode 100644 index 00000000000..4088caf49d5 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result @@ -0,0 +1,31 @@ +DROP TABLE IF EXISTS diaries; +CREATE TABLE diaries ( +id int PRIMARY KEY AUTO_INCREMENT, +body text, +FULLTEXT INDEX body_index (body) +COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"' +) DEFAULT CHARSET utf8; +SHOW CREATE TABLE diaries; +Table Create Table +diaries CREATE TABLE `diaries` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `body` text, + PRIMARY KEY (`id`), + FULLTEXT KEY `body_index` (`body`) COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +INSERT INTO diaries (body) VALUES ("will start Groonga!"); +INSERT INTO diaries (body) VALUES ("starting Groonga..."); +INSERT INTO diaries (body) VALUES ("started Groonga."); +SELECT * FROM diaries; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +SELECT * FROM diaries +WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE) +ORDER BY id; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_default.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result index 6c04cae59f2..a18614d19fc 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_default.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result @@ -14,20 +14,20 @@ diaries CREATE TABLE `diaries` ( PRIMARY KEY (`id`), FULLTEXT KEY `body_index` (`body`) ) ENGINE=Mroonga DEFAULT CHARSET=utf8 -insert into diaries (body) values ("will start groonga!"); -insert into diaries (body) values ("starting groonga..."); -insert into diaries (body) values ("started groonga."); -insert into diaries (body) values ("finished groonga."); +insert into diaries (body) values ("will start Groonga!"); +insert into diaries (body) values ("starting Groonga..."); +insert into diaries (body) values ("started Groonga."); +insert into diaries (body) values ("finished Groonga."); select * from diaries; id body -1 will start groonga! -2 starting groonga... -3 started groonga. -4 finished groonga. -select * from diaries where match(body) against("start"); +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +4 finished Groonga. +select * from diaries where match(body) against("+start" IN BOOLEAN MODE) order by id; id body -1 will start groonga! -2 starting groonga... -3 started groonga. +1 will start Groonga! +2 starting Groonga... +3 started Groonga. drop table diaries; set global mroonga_default_parser=@mroonga_default_parser_backup; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_off.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result index 77765f61dc3..77765f61dc3 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_off.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result index 785c5d785b9..c730bafc8e3 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_multiple_token_filters.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true SET NAMES utf8; CREATE TABLE memos ( diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result index 9ce60054300..e0809eb0f4b 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_one_token_filter.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true SET NAMES utf8; CREATE TABLE memos ( diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result new file mode 100644 index 00000000000..df529282a91 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result @@ -0,0 +1,23 @@ +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") +true +SET NAMES utf8; +CREATE TABLE memos ( +content VARCHAR(64) NOT NULL, +FULLTEXT INDEX (content) TOKEN_FILTERS='TokenFilterStopWord,TokenFilterStopWord' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; +Table Create Table +memos CREATE TABLE `memos` ( + `content` varchar(64) NOT NULL, + FULLTEXT KEY `content` (`content`) `TOKEN_FILTERS`='TokenFilterStopWord,TokenFilterStopWord' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +SELECT mroonga_command("dump --dump_plugins no"); +mroonga_command("dump --dump_plugins no") +table_create memos TABLE_NO_KEY +column_create memos content COLUMN_SCALAR ShortText + +table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord + +column_create memos-content index COLUMN_INDEX|WITH_POSITION memos content +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result new file mode 100644 index 00000000000..5b8d0cd780e --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result @@ -0,0 +1,31 @@ +DROP TABLE IF EXISTS diaries; +CREATE TABLE diaries ( +id int PRIMARY KEY AUTO_INCREMENT, +body text, +FULLTEXT INDEX body_index (body) +COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"' +) DEFAULT CHARSET utf8; +SHOW CREATE TABLE diaries; +Table Create Table +diaries CREATE TABLE `diaries` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `body` text, + PRIMARY KEY (`id`), + FULLTEXT KEY `body_index` (`body`) COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +INSERT INTO diaries (body) VALUES ("will start Groonga!"); +INSERT INTO diaries (body) VALUES ("starting Groonga..."); +INSERT INTO diaries (body) VALUES ("started Groonga."); +SELECT * FROM diaries; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +SELECT * FROM diaries +WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE) +ORDER BY id; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result new file mode 100644 index 00000000000..9efa08bab53 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result @@ -0,0 +1,33 @@ +drop table if exists diaries; +set @mroonga_default_tokenizer_backup=@@mroonga_default_tokenizer; +set global mroonga_default_tokenizer=TokenBigramSplitSymbolAlphaDigit; +create table diaries ( +id int primary key auto_increment, +body text, +fulltext index body_index (body) +) default charset utf8; +show create table diaries; +Table Create Table +diaries CREATE TABLE `diaries` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `body` text, + PRIMARY KEY (`id`), + FULLTEXT KEY `body_index` (`body`) +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +insert into diaries (body) values ("will start Groonga!"); +insert into diaries (body) values ("starting Groonga..."); +insert into diaries (body) values ("started Groonga."); +insert into diaries (body) values ("finished Groonga."); +select * from diaries; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +4 finished Groonga. +select * from diaries where match(body) against("+start" IN BOOLEAN MODE) order by id; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +drop table diaries; +set global mroonga_default_tokenizer=@mroonga_default_tokenizer_backup; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result new file mode 100644 index 00000000000..780ac2faa3d --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result @@ -0,0 +1,42 @@ +DROP TABLE IF EXISTS variables; +CREATE TABLE variables ( +id INT PRIMARY KEY AUTO_INCREMENT, +name TEXT, +FULLTEXT INDEX (name) COMMENT 'tokenizer "off"' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE variables; +Table Create Table +variables CREATE TABLE `variables` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` text, + PRIMARY KEY (`id`), + FULLTEXT KEY `name` (`name`) COMMENT 'tokenizer "off"' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +INSERT INTO variables (name) VALUES ("mroonga_database_path_prefix"); +INSERT INTO variables (name) VALUES ("mroonga_default_tokenizer"); +INSERT INTO variables (name) VALUES ("mroonga_default_wrapper_engine"); +INSERT INTO variables (name) VALUES ("mroonga_dry_write"); +INSERT INTO variables (name) VALUES ("mroonga_enable_optimization"); +INSERT INTO variables (name) VALUES ("mroonga_libgroonga_version"); +INSERT INTO variables (name) VALUES ("mroonga_log_file"); +INSERT INTO variables (name) VALUES ("mroonga_log_level"); +INSERT INTO variables (name) VALUES ("mroonga_match_escalation_threshold"); +INSERT INTO variables (name) VALUES ("mroonga_version"); +SELECT * FROM variables; +id name +1 mroonga_database_path_prefix +2 mroonga_default_tokenizer +3 mroonga_default_wrapper_engine +4 mroonga_dry_write +5 mroonga_enable_optimization +6 mroonga_libgroonga_version +7 mroonga_log_file +8 mroonga_log_level +9 mroonga_match_escalation_threshold +10 mroonga_version +SELECT * FROM variables +WHERE MATCH (name) AGAINST ("mroonga_default*" IN BOOLEAN MODE); +id name +3 mroonga_default_wrapper_engine +2 mroonga_default_tokenizer +DROP TABLE variables; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result new file mode 100644 index 00000000000..67170925826 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result @@ -0,0 +1,30 @@ +DROP TABLE IF EXISTS diaries; +CREATE TABLE diaries ( +id int PRIMARY KEY AUTO_INCREMENT, +body text, +FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit' +) DEFAULT CHARSET utf8; +SHOW CREATE TABLE diaries; +Table Create Table +diaries CREATE TABLE `diaries` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `body` text, + PRIMARY KEY (`id`), + FULLTEXT KEY `body_index` (`body`) `TOKENIZER`='TokenBigramSplitSymbolAlphaDigit' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +INSERT INTO diaries (body) VALUES ("will start Groonga!"); +INSERT INTO diaries (body) VALUES ("starting Groonga..."); +INSERT INTO diaries (body) VALUES ("started Groonga."); +SELECT * FROM diaries; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +SELECT * FROM diaries +WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE) +ORDER BY id; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_default.result index dbf69362ee7..dbf69362ee7 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_default.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment_with_using_hash.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_hash.result index 5e4f4afa377..5e4f4afa377 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment_with_using_hash.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_hash.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result index de1946e9214..6308b33d4cf 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_multiple_token_filters.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true CREATE TABLE terms ( term VARCHAR(64) NOT NULL PRIMARY KEY, diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result index f3349980db1..2f4a90d4086 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_one_token_filter.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true CREATE TABLE terms ( term VARCHAR(64) NOT NULL PRIMARY KEY, diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_token_filters_skip.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_stop_word.result index 290f96df35d..bc21ed97502 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_token_filters_skip.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_stop_word.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true CREATE TABLE terms ( term VARCHAR(64) NOT NULL PRIMARY KEY, diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result index f45e8fd4fb6..0c81bf6c3ad 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result @@ -10,9 +10,10 @@ INSERT INTO memos VALUES ("Today is fine."); INSERT INTO memos VALUES ("Tomorrow will be fine."); INSERT INTO memos VALUES ("Yesterday was fine."); SELECT * FROM memos -WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE); +WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE) +ORDER BY content; content -Today is good day. Today is fine. +Today is good day. Tomorrow will be good day. DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result index 103866902c2..dfeb71f0d14 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result @@ -10,9 +10,10 @@ INSERT INTO memos VALUES ("Today is fine."); INSERT INTO memos VALUES ("Tomorrow will be fine."); INSERT INTO memos VALUES ("Yesterday was fine."); SELECT * FROM memos -WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE); +WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE) +ORDER BY content; content -Tomorrow will be good day. Today is fine. Tomorrow will be fine. +Tomorrow will be good day. DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result index fd52868b4bc..e72cf8d4052 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result @@ -10,9 +10,10 @@ INSERT INTO memos VALUES ("Today is fine."); INSERT INTO memos VALUES ("Tomorrow will be fine."); INSERT INTO memos VALUES ("Yesterday was fine."); SELECT * FROM memos -WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE); +WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE) +ORDER BY content; content Today is good day. -Tomorrow will be good day. Tomorrow will be fine. +Tomorrow will be good day. DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.result new file mode 100644 index 00000000000..7a30baab5a0 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.result @@ -0,0 +1,14 @@ +DROP TABLE IF EXISTS memos; +SET NAMES utf8; +CREATE TABLE memos ( +content TEXT, +FULLTEXT INDEX (content) +) DEFAULT CHARSET=utf8; +INSERT INTO memos VALUES ("Today is good day."); +INSERT INTO memos VALUES ("Tomorrow will be good day."); +INSERT INTO memos VALUES ("Today is fine."); +SELECT * FROM memos +WHERE MATCH (content) AGAINST ("*D+ today fi*" IN BOOLEAN MODE); +content +Today is fine. +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result index 2c1666369a5..b6d6febf0b3 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result @@ -18,21 +18,21 @@ c1 c2 c3 6 20 ka ki ku ke ko 7 20 aa ii uu ee oo 8 20 ka ki ku ke ko -select * from t1 where match(c3) against("uu"); +select * from t1 where match(c3) against("+uu" in boolean mode) order by c1; c1 c2 c3 1 10 aa ii uu ee oo 3 10 aa ii uu ee oo 5 20 aa ii uu ee oo 7 20 aa ii uu ee oo -select * from t1 where not match(c3) against("uu"); +select * from t1 where not match(c3) against("+uu" in boolean mode) order by c1; c1 c2 c3 2 10 ka ki ku ke ko 4 10 ka ki ku ke ko 6 20 ka ki ku ke ko 8 20 ka ki ku ke ko -select * from t1 where match(c3) against("dummy"); +select * from t1 where match(c3) against("+dummy" in boolean mode) order by c1; c1 c2 c3 -select * from t1 where not match(c3) against("dummy"); +select * from t1 where not match(c3) against("+dummy" in boolean mode) order by c1; c1 c2 c3 1 10 aa ii uu ee oo 2 10 ka ki ku ke ko @@ -42,26 +42,26 @@ c1 c2 c3 6 20 ka ki ku ke ko 7 20 aa ii uu ee oo 8 20 ka ki ku ke ko -select * from t1 where c1 = 4 and not match(c3) against("uu"); +select * from t1 where c1 = 4 and not match(c3) against("+uu" in boolean mode) order by c1; c1 c2 c3 4 10 ka ki ku ke ko -select * from t1 where c1 <= 4 and not match(c3) against("uu"); +select * from t1 where c1 <= 4 and not match(c3) against("+uu" in boolean mode) order by c1; c1 c2 c3 2 10 ka ki ku ke ko 4 10 ka ki ku ke ko -select * from t1 where c1 > 4 and not match(c3) against("uu"); +select * from t1 where c1 > 4 and not match(c3) against("+uu" in boolean mode) order by c1; c1 c2 c3 6 20 ka ki ku ke ko 8 20 ka ki ku ke ko -select * from t1 where c2 = 10 and not match(c3) against("uu"); +select * from t1 where c2 = 10 and not match(c3) against("+uu" in boolean mode) order by c1; c1 c2 c3 2 10 ka ki ku ke ko 4 10 ka ki ku ke ko -select * from t1 where c2 >= 15 and not match(c3) against("uu"); +select * from t1 where c2 >= 15 and not match(c3) against("+uu" in boolean mode) order by c1; c1 c2 c3 6 20 ka ki ku ke ko 8 20 ka ki ku ke ko -select * from t1 where c2 < 15 and not match(c3) against("uu"); +select * from t1 where c2 < 15 and not match(c3) against("+uu" in boolean mode) order by c1; c1 c2 c3 2 10 ka ki ku ke ko 4 10 ka ki ku ke ko diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_comment.result deleted file mode 100644 index f2abfe85dd6..00000000000 --- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_comment.result +++ /dev/null @@ -1,29 +0,0 @@ -drop table if exists diaries; -create table diaries ( -id int primary key auto_increment, -body text, -fulltext index body_index (body) -comment 'parser "TokenBigramSplitSymbolAlphaDigit"' -) default charset utf8; -show create table diaries; -Table Create Table -diaries CREATE TABLE `diaries` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `body` text, - PRIMARY KEY (`id`), - FULLTEXT KEY `body_index` (`body`) COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"' -) ENGINE=Mroonga DEFAULT CHARSET=utf8 -insert into diaries (body) values ("will start groonga!"); -insert into diaries (body) values ("starting groonga..."); -insert into diaries (body) values ("started groonga."); -select * from diaries; -id body -1 will start groonga! -2 starting groonga... -3 started groonga. -select * from diaries where match(body) against("start"); -id body -1 will start groonga! -2 starting groonga... -3 started groonga. -drop table diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.result new file mode 100644 index 00000000000..155faf85510 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.result @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS ranges; +CREATE TABLE ranges ( +id int PRIMARY KEY, +start datetime, +end datetime, +UNIQUE KEY range_key(start, end) +); +INSERT INTO ranges VALUES (1, "1990-00-00 00:00:00", "2012-10-05 23:59:59"); +Warnings: +Warning 1265 Data truncated for column 'start' at row 1 +SELECT * FROM ranges; +id start end +1 1990-01-01 00:00:00 2012-10-05 23:59:59 +DELETE FROM ranges WHERE id = 1; +INSERT INTO ranges VALUES (1, "1990-00-00 00:00:00", "2012-10-05 23:59:59"); +Warnings: +Warning 1265 Data truncated for column 'start' at row 1 +SELECT * FROM ranges; +id start end +1 1990-01-01 00:00:00 2012-10-05 23:59:59 +DROP TABLE ranges; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result b/storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result index 9cbe11c5574..b9aebee3f9e 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result @@ -31,7 +31,8 @@ SELECT v.id, v.video_id, v.description, NULL FROM videos_master AS v WHERE v.video_id = (video_id); SELECT *, MATCH(description) AGAINST("my") FROM videos_groonga -WHERE MATCH(description) AGAINST("my"); +WHERE MATCH(description) AGAINST("my") +ORDER BY id; id video_id description tags_unpack MATCH(description) AGAINST("my") 1 video-1 My Familly 209716 2 video-2 My Cat 209716 diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result index 2c6c1cbc7e8..e67f0fe4007 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result @@ -6,5 +6,5 @@ content text, FULLTEXT INDEX (content) ) DEFAULT CHARSET=utf8; REPLACE INTO diaries(content) VALUES("Hello"); -ERROR HY000: primary key is empty +Got one of the listed errors DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result b/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result index 0e33976eb17..104d1d51504 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result @@ -31,15 +31,18 @@ id year month day title content 1 2011 11 9 Hello 今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚ 2 2011 11 10 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠3 2011 11 11 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚ -SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE); +SELECT * FROM diaries +WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE) +ORDER BY id; id year month day title content 1 2011 11 9 Hello 今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚ 3 2011 11 11 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚ -2 2011 11 10 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠TRUNCATE TABLE diaries; SELECT * FROM diaries; id year month day title content -SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE); +SELECT * FROM diaries +WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE) +ORDER BY id; id year month day title content INSERT INTO diaries VALUES(1, 2011, 11, 11, "帰りé“", "ã¤ã‹ã‚ŒãŸãƒ¼"); INSERT INTO diaries VALUES(2, 2011, 12, 1, "ä¹…ã—ã¶ã‚Š", "天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚"); @@ -49,7 +52,9 @@ id year month day title content 1 2011 11 11 å¸°ã‚Šé“ ã¤ã‹ã‚ŒãŸãƒ¼ 2 2011 12 1 ä¹…ã—ã¶ã‚Š 天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚ 3 2011 12 2 åˆé›ª 今年ã¯ã˜ã‚ã¦ã®é›ªï¼ -SELECT * FROM diaries WHERE MATCH(content) AGAINST("悪ã„" IN BOOLEAN MODE); +SELECT * FROM diaries +WHERE MATCH(content) AGAINST("+悪ã„" IN BOOLEAN MODE) +ORDER BY id; id year month day title content 2 2011 12 1 ä¹…ã—ã¶ã‚Š 天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚ DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/suite.pm b/storage/mroonga/mysql-test/mroonga/storage/suite.pm index 6b345c0fd6f..528ccc5d693 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/suite.pm +++ b/storage/mroonga/mysql-test/mroonga/storage/suite.pm @@ -5,11 +5,6 @@ package My::Suite::Mroonga; return "No Mroonga engine" unless $ENV{HA_MROONGA_SO} or $::mysqld_variables{'mroonga'} eq "ON"; -# RECOMPILE_FOR_EMBEDDED also means that a plugin -# cannot be dynamically loaded into embedded -return "Not run for embedded server" if $::opt_embedded_server and - $ENV{HA_MROONGA_SO}; - sub is_default { 1 } my $groonga_normalizer_mysql_dir=$::basedir . '/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql'; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_flags.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test index 96c99612190..96c99612190 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_flags.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test new file mode 100644 index 00000000000..0c389ba3197 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test @@ -0,0 +1,41 @@ +# Copyright(C) 2014 Kenji Maruyama <mmmaru777@gmail.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source include/not_embedded.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +CREATE TABLE tags ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY +) DEFAULT CHARSET=utf8; + +ALTER TABLE tags ADD COLUMN name VARCHAR(64) FLAGS='COLUMN_VECTOR'; +SHOW CREATE TABLE tags; + +SELECT mroonga_command("dump --dump_plugins no"); + +DROP TABLE tags; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test new file mode 100644 index 00000000000..d77809c1a6c --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test @@ -0,0 +1,44 @@ +# Copyright(C) 2014 Kenji Maruyama <mmmaru777@gmail.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/not_embedded.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +CREATE TABLE tags ( + id INT UNSIGNED PRIMARY KEY +) DEFAULT CHARSET=utf8; + +CREATE TABLE bugs ( + id INT UNSIGNED PRIMARY KEY +) DEFAULT CHARSET=utf8; + +ALTER TABLE bugs ADD COLUMN name VARCHAR(64) COMMENT 'groonga_type "tags"'; + +SELECT mroonga_command("dump --dump_plugins no"); + +DROP TABLE bugs; +DROP TABLE tags; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test new file mode 100644 index 00000000000..a65eff4529f --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test @@ -0,0 +1,47 @@ +# Copyright(C) 2014 Kenji Maruyama <mmmaru777@gmail.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source ../../include/mroonga/have_version_56_or_later.inc +--source include/not_embedded.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +CREATE TABLE tags ( + id INT UNSIGNED PRIMARY KEY +) DEFAULT CHARSET=utf8; + +CREATE TABLE bugs ( + id INT UNSIGNED PRIMARY KEY +) DEFAULT CHARSET=utf8; + +ALTER TABLE bugs ADD COLUMN name VARCHAR(64) GROONGA_TYPE='tags'; +SHOW CREATE TABLE bugs; + +SELECT mroonga_command("dump --dump_plugins no"); + +DROP TABLE bugs; +DROP TABLE tags; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_type.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test index dd05765585d..dd05765585d 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_type.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test index 9c01dc27e3e..b2312997709 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -23,7 +24,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); SET NAMES utf8; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test index 7ec047818e3..ada266fff0c 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -23,7 +24,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); CREATE TABLE terms ( term VARCHAR(64) NOT NULL PRIMARY KEY, diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test new file mode 100644 index 00000000000..7736fc45b7b --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test @@ -0,0 +1,41 @@ +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS timestamps; +--enable_warnings + +CREATE TABLE timestamps ( + id INT PRIMARY KEY AUTO_INCREMENT, + create_dt DATETIME +) DEFAULT CHARSET UTF8; +SHOW CREATE TABLE timestamps; + +SET sql_mode='STRICT_TRANS_TABLES'; +--error ER_WARN_DATA_OUT_OF_RANGE +INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00"); +SET sql_mode=default; + +SELECT * FROM timestamps; + +INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00"); +SELECT * FROM timestamps; + +DROP TABLE timestamps; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_vector.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_comment.test index 2d5498c99c8..2d5498c99c8 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_vector.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_comment.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test new file mode 100644 index 00000000000..dbecd47dac6 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test @@ -0,0 +1,39 @@ +# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source include/not_embedded.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +CREATE TABLE bugs ( + id INT UNSIGNED PRIMARY KEY, + tags TEXT FLAGS='COLUMN_VECTOR' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE bugs; + +SELECT mroonga_command("dump --dump_plugins no"); + +DROP TABLE bugs; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test new file mode 100644 index 00000000000..aa4723b087c --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test @@ -0,0 +1,42 @@ +# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/not_embedded.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +CREATE TABLE tags ( + name VARCHAR(64) PRIMARY KEY +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +CREATE TABLE bugs ( + id INT UNSIGNED PRIMARY KEY, + tag VARCHAR(64) COMMENT 'groonga_type "tags"' +) DEFAULT CHARSET=utf8; + +SELECT mroonga_command("dump --dump_plugins no"); + +DROP TABLE bugs; +DROP TABLE tags; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test new file mode 100644 index 00000000000..56d81fad16c --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test @@ -0,0 +1,29 @@ +# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS bugs; +--enable_warnings + +--error ER_CANT_CREATE_TABLE +CREATE TABLE bugs ( + id INT UNSIGNED PRIMARY KEY, + tag VARCHAR(64) COMMENT 'groonga_type "Nonexistent"' +) DEFAULT CHARSET=utf8mb4; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test new file mode 100644 index 00000000000..325536af3d2 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test @@ -0,0 +1,45 @@ +# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source ../../include/mroonga/have_version_56_or_later.inc +--source include/not_embedded.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +CREATE TABLE tags ( + name VARCHAR(64) PRIMARY KEY +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +CREATE TABLE bugs ( + id INT UNSIGNED PRIMARY KEY, + tag VARCHAR(64) GROONGA_TYPE='tags' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE bugs; + +SELECT mroonga_command("dump --dump_plugins no"); + +DROP TABLE bugs; +DROP TABLE tags; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_reference_type.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_comment.test index 0a1340d24d1..0a1340d24d1 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_reference_type.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_comment.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test new file mode 100644 index 00000000000..2b9a58c887c --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test @@ -0,0 +1,29 @@ +# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS bugs; +--enable_warnings + +--error ER_CANT_CREATE_TABLE +CREATE TABLE bugs ( + id INT UNSIGNED PRIMARY KEY, + tag VARCHAR(64) COMMENT 'type "Nonexistent"' +) DEFAULT CHARSET=utf8mb4; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test new file mode 100644 index 00000000000..668a148edf9 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test @@ -0,0 +1,39 @@ +# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com> +# Copyright(C) 2015 Kouhei SUtou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SET NAMES utf8; + +CREATE TABLE memos ( + content VARCHAR(64) NOT NULL, + FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"' +) DEFAULT CHARSET=utf8; + +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test index 039c518e673..107b045c8fc 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test @@ -1,4 +1,5 @@ # Copyright(C) 2015 Naoya Murakami <naoya@createfield.com> +# Copyright(C) 2015 Kouhei SUtou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -27,7 +28,7 @@ SET NAMES utf8; CREATE TABLE memos ( content VARCHAR(64) NOT NULL, - FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"' + FULLTEXT INDEX (content) COMMENT 'flags "NONE"' ) DEFAULT CHARSET=utf8; SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test new file mode 100644 index 00000000000..14c65ad54c1 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test @@ -0,0 +1,41 @@ +# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com> +# Copyright(C) 2015 Kouhei SUtou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SET NAMES utf8; + +CREATE TABLE memos ( + content VARCHAR(64) NOT NULL, + FULLTEXT INDEX (content) FLAGS='WITH_POSITION|WITH_WEIGHT' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; + +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test new file mode 100644 index 00000000000..039c518e673 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test @@ -0,0 +1,38 @@ +# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SET NAMES utf8; + +CREATE TABLE memos ( + content VARCHAR(64) NOT NULL, + FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"' +) DEFAULT CHARSET=utf8; + +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_with_position_and_with_weight.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test index 9a67644d2c5..9a67644d2c5 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_with_position_and_with_weight.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test index 02e2cb9e81a..02e2cb9e81a 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_comment.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test index f28fb5b8695..f28fb5b8695 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test index ae4d4cb9f1b..ae4d4cb9f1b 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test new file mode 100644 index 00000000000..a42b30b72a1 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test @@ -0,0 +1,40 @@ +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS memos; +--enable_warnings + +SET NAMES utf8; + +CREATE TABLE memos ( + id INT NOT NULL PRIMARY KEY, + content TEXT NOT NULL, + FULLTEXT INDEX (content) NORMALIZER='NormalizerAuto' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; + +INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ"); + +SELECT * FROM memos + WHERE MATCH (content) AGAINST ("+ã‚«ãƒãƒªãƒ¼" IN BOOLEAN MODE); + +DROP TABLE memos; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test new file mode 100644 index 00000000000..1b728afa1c1 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test @@ -0,0 +1,42 @@ +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS diaries; +--enable_warnings + +CREATE TABLE diaries ( + id int PRIMARY KEY AUTO_INCREMENT, + body text, + FULLTEXT INDEX body_index (body) + COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"' +) DEFAULT CHARSET utf8; +SHOW CREATE TABLE diaries; + +INSERT INTO diaries (body) VALUES ("will start Groonga!"); +INSERT INTO diaries (body) VALUES ("starting Groonga..."); +INSERT INTO diaries (body) VALUES ("started Groonga."); + +SELECT * FROM diaries; +SELECT * FROM diaries + WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE) + ORDER BY id; + +DROP TABLE diaries; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_default.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test index 1e08cc46221..a1756ad268e 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_default.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # Copyright(C) 2014 Kentoku SHIBA # # This library is free software; you can redistribute it and/or @@ -29,12 +29,12 @@ create table diaries ( fulltext index body_index (body) ) default charset utf8; show create table diaries; -insert into diaries (body) values ("will start groonga!"); -insert into diaries (body) values ("starting groonga..."); -insert into diaries (body) values ("started groonga."); -insert into diaries (body) values ("finished groonga."); +insert into diaries (body) values ("will start Groonga!"); +insert into diaries (body) values ("starting Groonga..."); +insert into diaries (body) values ("started Groonga."); +insert into diaries (body) values ("finished Groonga."); select * from diaries; -select * from diaries where match(body) against("start"); +select * from diaries where match(body) against("+start" IN BOOLEAN MODE) order by id; drop table diaries; set global mroonga_default_parser=@mroonga_default_parser_backup; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_off.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test index 0dcf494c684..0869e2334b7 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_off.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test @@ -14,7 +14,6 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---source ../../include/mroonga/have_fulltext_index_comment.inc --source ../../include/mroonga/have_mroonga.inc --disable_warnings diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test index 18a2607fa0b..534ff998ff0 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_multiple_token_filters.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -23,7 +24,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); SET NAMES utf8; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test index 20df762d31b..77d886579ba 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_one_token_filter.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -23,7 +24,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); SET NAMES utf8; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test new file mode 100644 index 00000000000..d9458f4402d --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test @@ -0,0 +1,44 @@ +# Copyright(C) 2014 Naoya Murakami <naoya@createfield.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SELECT mroonga_command("plugin_register token_filters/stop_word"); + +SET NAMES utf8; + +CREATE TABLE memos ( + content VARCHAR(64) NOT NULL, + FULLTEXT INDEX (content) TOKEN_FILTERS='TokenFilterStopWord,TokenFilterStopWord' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; + +SELECT mroonga_command("dump --dump_plugins no"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test new file mode 100644 index 00000000000..4bf386a4c11 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test @@ -0,0 +1,42 @@ +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS diaries; +--enable_warnings + +CREATE TABLE diaries ( + id int PRIMARY KEY AUTO_INCREMENT, + body text, + FULLTEXT INDEX body_index (body) + COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"' +) DEFAULT CHARSET utf8; +SHOW CREATE TABLE diaries; + +INSERT INTO diaries (body) VALUES ("will start Groonga!"); +INSERT INTO diaries (body) VALUES ("starting Groonga..."); +INSERT INTO diaries (body) VALUES ("started Groonga."); + +SELECT * FROM diaries; +SELECT * FROM diaries + WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE) + ORDER BY id; + +DROP TABLE diaries; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test new file mode 100644 index 00000000000..069e06b4a84 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test @@ -0,0 +1,41 @@ +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2014 Kentoku SHIBA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +drop table if exists diaries; +--enable_warnings + +set @mroonga_default_tokenizer_backup=@@mroonga_default_tokenizer; +set global mroonga_default_tokenizer=TokenBigramSplitSymbolAlphaDigit; +create table diaries ( + id int primary key auto_increment, + body text, + fulltext index body_index (body) +) default charset utf8; +show create table diaries; +insert into diaries (body) values ("will start Groonga!"); +insert into diaries (body) values ("starting Groonga..."); +insert into diaries (body) values ("started Groonga."); +insert into diaries (body) values ("finished Groonga."); +select * from diaries; +select * from diaries where match(body) against("+start" IN BOOLEAN MODE) order by id; +drop table diaries; +set global mroonga_default_tokenizer=@mroonga_default_tokenizer_backup; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test new file mode 100644 index 00000000000..5aff5e3575b --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test @@ -0,0 +1,47 @@ +# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS variables; +--enable_warnings + +CREATE TABLE variables ( + id INT PRIMARY KEY AUTO_INCREMENT, + name TEXT, + FULLTEXT INDEX (name) COMMENT 'tokenizer "off"' +) DEFAULT CHARSET=utf8; +SHOW CREATE TABLE variables; + +INSERT INTO variables (name) VALUES ("mroonga_database_path_prefix"); +INSERT INTO variables (name) VALUES ("mroonga_default_tokenizer"); +INSERT INTO variables (name) VALUES ("mroonga_default_wrapper_engine"); +INSERT INTO variables (name) VALUES ("mroonga_dry_write"); +INSERT INTO variables (name) VALUES ("mroonga_enable_optimization"); +INSERT INTO variables (name) VALUES ("mroonga_libgroonga_version"); +INSERT INTO variables (name) VALUES ("mroonga_log_file"); +INSERT INTO variables (name) VALUES ("mroonga_log_level"); +INSERT INTO variables (name) VALUES ("mroonga_match_escalation_threshold"); +INSERT INTO variables (name) VALUES ("mroonga_version"); + +SELECT * FROM variables; +SELECT * FROM variables + WHERE MATCH (name) AGAINST ("mroonga_default*" IN BOOLEAN MODE); + +DROP TABLE variables; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test new file mode 100644 index 00000000000..d79eaefe3f6 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test @@ -0,0 +1,42 @@ +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS diaries; +--enable_warnings + +CREATE TABLE diaries ( + id int PRIMARY KEY AUTO_INCREMENT, + body text, + FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit' +) DEFAULT CHARSET utf8; +SHOW CREATE TABLE diaries; + +INSERT INTO diaries (body) VALUES ("will start Groonga!"); +INSERT INTO diaries (body) VALUES ("starting Groonga..."); +INSERT INTO diaries (body) VALUES ("started Groonga."); + +SELECT * FROM diaries; +SELECT * FROM diaries + WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE) + ORDER BY id; + +DROP TABLE diaries; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test index 1da8026f56d..1da8026f56d 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment_with_using_hash.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test index 14b9ea9ab87..14b9ea9ab87 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment_with_using_hash.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test index e4d7d8618fa..944838e2fe0 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_multiple_token_filters.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -23,7 +24,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); CREATE TABLE terms ( term VARCHAR(64) NOT NULL PRIMARY KEY, diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test index 905181175d0..701a4ae425b 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_one_token_filter.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -23,7 +24,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); CREATE TABLE terms ( term VARCHAR(64) NOT NULL PRIMARY KEY, diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_token_filters_skip.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test index b27fb5b70d6..b2e6be600f1 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_token_filters_skip.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -23,7 +24,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); CREATE TABLE terms ( term VARCHAR(64) NOT NULL PRIMARY KEY, diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test index 4d0f15b203a..66ff69d77e2 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com> # # This library is free software; you can redistribute it and/or @@ -34,7 +34,8 @@ INSERT INTO memos VALUES ("Tomorrow will be fine."); INSERT INTO memos VALUES ("Yesterday was fine."); SELECT * FROM memos - WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE); + WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE) + ORDER BY content; DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test index ed93b543869..1d91bdc7a56 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com> # # This library is free software; you can redistribute it and/or @@ -34,7 +34,8 @@ INSERT INTO memos VALUES ("Tomorrow will be fine."); INSERT INTO memos VALUES ("Yesterday was fine."); SELECT * FROM memos - WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE); + WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE) + ORDER BY content; DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test index 3a078c7eccb..63e5baeeb68 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com> # # This library is free software; you can redistribute it and/or @@ -34,7 +34,8 @@ INSERT INTO memos VALUES ("Tomorrow will be fine."); INSERT INTO memos VALUES ("Yesterday was fine."); SELECT * FROM memos - WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE); + WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE) + ORDER BY content; DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test new file mode 100644 index 00000000000..ded739d8e8b --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test @@ -0,0 +1,38 @@ +# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS memos; +--enable_warnings + +SET NAMES utf8; +CREATE TABLE memos ( + content TEXT, + FULLTEXT INDEX (content) +) DEFAULT CHARSET=utf8; + +INSERT INTO memos VALUES ("Today is good day."); +INSERT INTO memos VALUES ("Tomorrow will be good day."); +INSERT INTO memos VALUES ("Today is fine."); + +SELECT * FROM memos + WHERE MATCH (content) AGAINST ("*D+ today fi*" IN BOOLEAN MODE); + +DROP TABLE memos; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test index 7b4e62ba0a9..ffb49f2f396 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test @@ -1,4 +1,5 @@ # Copyright(C) 2010 Tetsuro IKEDA +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -31,16 +32,16 @@ insert into t1 values(6,20,"ka ki ku ke ko"); insert into t1 values(7,20,"aa ii uu ee oo"); insert into t1 values(8,20,"ka ki ku ke ko"); select * from t1; -select * from t1 where match(c3) against("uu"); -select * from t1 where not match(c3) against("uu"); -select * from t1 where match(c3) against("dummy"); -select * from t1 where not match(c3) against("dummy"); -select * from t1 where c1 = 4 and not match(c3) against("uu"); -select * from t1 where c1 <= 4 and not match(c3) against("uu"); -select * from t1 where c1 > 4 and not match(c3) against("uu"); -select * from t1 where c2 = 10 and not match(c3) against("uu"); -select * from t1 where c2 >= 15 and not match(c3) against("uu"); -select * from t1 where c2 < 15 and not match(c3) against("uu"); +select * from t1 where match(c3) against("+uu" in boolean mode) order by c1; +select * from t1 where not match(c3) against("+uu" in boolean mode) order by c1; +select * from t1 where match(c3) against("+dummy" in boolean mode) order by c1; +select * from t1 where not match(c3) against("+dummy" in boolean mode) order by c1; +select * from t1 where c1 = 4 and not match(c3) against("+uu" in boolean mode) order by c1; +select * from t1 where c1 <= 4 and not match(c3) against("+uu" in boolean mode) order by c1; +select * from t1 where c1 > 4 and not match(c3) against("+uu" in boolean mode) order by c1; +select * from t1 where c2 = 10 and not match(c3) against("+uu" in boolean mode) order by c1; +select * from t1 where c2 >= 15 and not match(c3) against("+uu" in boolean mode) order by c1; +select * from t1 where c2 < 15 and not match(c3) against("+uu" in boolean mode) order by c1; drop table t1; --source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test new file mode 100644 index 00000000000..2782fc15363 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test @@ -0,0 +1,39 @@ +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS ranges; +--enable_warnings + +CREATE TABLE ranges ( + id int PRIMARY KEY, + start datetime, + end datetime, + UNIQUE KEY range_key(start, end) +); + +INSERT INTO ranges VALUES (1, "1990-00-00 00:00:00", "2012-10-05 23:59:59"); +SELECT * FROM ranges; + +DELETE FROM ranges WHERE id = 1; +INSERT INTO ranges VALUES (1, "1990-00-00 00:00:00", "2012-10-05 23:59:59"); +SELECT * FROM ranges; + +DROP TABLE ranges; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test index 192a4976cbd..d7cd89cf78c 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test @@ -57,7 +57,8 @@ REPLACE INTO videos_groonga FROM videos_master AS v WHERE v.video_id = (video_id); SELECT *, MATCH(description) AGAINST("my") FROM videos_groonga - WHERE MATCH(description) AGAINST("my"); + WHERE MATCH(description) AGAINST("my") + ORDER BY id; DROP TABLE videos_master, videos_groonga; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test index a38c4953e67..5cbeab60fb0 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test @@ -27,7 +27,7 @@ CREATE TABLE diaries ( FULLTEXT INDEX (content) ) DEFAULT CHARSET=utf8; --- error ER_ERROR_ON_WRITE +-- error ER_ERROR_ON_WRITE, ER_NO_DEFAULT_FOR_FIELD REPLACE INTO diaries(content) VALUES("Hello"); DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test b/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test index 5833f77722a..dac32178011 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -38,17 +38,23 @@ INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚"); SELECT * FROM diaries; -SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE); +SELECT * FROM diaries + WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE) + ORDER BY id; TRUNCATE TABLE diaries; SELECT * FROM diaries; -SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE); +SELECT * FROM diaries + WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE) + ORDER BY id; INSERT INTO diaries VALUES(1, 2011, 11, 11, "帰りé“", "ã¤ã‹ã‚ŒãŸãƒ¼"); INSERT INTO diaries VALUES(2, 2011, 12, 1, "ä¹…ã—ã¶ã‚Š", "天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚"); INSERT INTO diaries VALUES(3, 2011, 12, 2, "åˆé›ª", "今年ã¯ã˜ã‚ã¦ã®é›ªï¼"); SELECT * FROM diaries; -SELECT * FROM diaries WHERE MATCH(content) AGAINST("悪ã„" IN BOOLEAN MODE); +SELECT * FROM diaries + WHERE MATCH(content) AGAINST("+悪ã„" IN BOOLEAN MODE) + ORDER BY id; DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test index 55a318b786a..9018bd75626 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test @@ -14,7 +14,6 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---source ../../include/mroonga/have_fulltext_index_comment.inc --source ../../include/mroonga/have_mroonga.inc --disable_warnings diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test index c459e50c0d7..49557069965 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test @@ -14,7 +14,6 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---source ../../include/mroonga/have_fulltext_index_comment.inc --source ../../include/mroonga/have_mroonga.inc --disable_warnings diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result new file mode 100644 index 00000000000..fb03bfe8d8d --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result @@ -0,0 +1,9 @@ +SET NAMES utf8; +CREATE TABLE memos ( +content VARCHAR(64) NOT NULL PRIMARY KEY, +FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"' +) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8; +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); +mroonga_command("dump --dump_plugins no --dump_schema no") +column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result new file mode 100644 index 00000000000..4a7107146ce --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result @@ -0,0 +1,9 @@ +SET NAMES utf8; +CREATE TABLE memos ( +content VARCHAR(64) NOT NULL PRIMARY KEY, +FULLTEXT INDEX (content) COMMENT 'flags "NONE"' +) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8; +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); +mroonga_command("dump --dump_plugins no --dump_schema no") +column_create memos-content index COLUMN_INDEX memos +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result new file mode 100644 index 00000000000..6e00526c736 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result @@ -0,0 +1,16 @@ +SET NAMES utf8; +CREATE TABLE memos ( +content VARCHAR(64) NOT NULL PRIMARY KEY, +FULLTEXT INDEX (content) FLAGS='WITH_POSITION|WITH_WEIGHT' +) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; +Table Create Table +memos CREATE TABLE `memos` ( + `content` varchar(64) NOT NULL, + PRIMARY KEY (`content`), + FULLTEXT KEY `content` (`content`) `FLAGS`='WITH_POSITION|WITH_WEIGHT' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"' +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); +mroonga_command("dump --dump_plugins no --dump_schema no") +column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_comment.result new file mode 100644 index 00000000000..1c9bf50fad9 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_comment.result @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS memos; +SET NAMES utf8; +CREATE TABLE memos ( +id INT NOT NULL PRIMARY KEY, +content TEXT NOT NULL, +FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"' +) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; +Table Create Table +memos CREATE TABLE `memos` ( + `id` int(11) NOT NULL, + `content` text NOT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `content` (`content`) COMMENT 'normalizer "NormalizerAuto"' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"' +INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ"); +SELECT * FROM memos +WHERE MATCH (content) AGAINST ("+ã‚«ãƒãƒªãƒ¼" IN BOOLEAN MODE); +id content +1 1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔㌠+DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index.result deleted file mode 100644 index ea992f827ca..00000000000 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index.result +++ /dev/null @@ -1,16 +0,0 @@ -DROP TABLE IF EXISTS diaries; -SET NAMES utf8; -CREATE TABLE diaries ( -day DATE PRIMARY KEY, -content VARCHAR(64) NOT NULL, -FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"' -) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んã 。"); -SELECT * FROM diaries -WHERE MATCH (content) AGAINST ("+ãµã‚‰ã¤ã" IN BOOLEAN MODE); -day content -SELECT * FROM diaries -WHERE MATCH (content) AGAINST ("+ブラック" IN BOOLEAN MODE); -day content -2013-04-23 ブラックコーヒーを飲んã 。 -DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_parameter.result new file mode 100644 index 00000000000..d3bc05a9b7d --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_parameter.result @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS memos; +SET NAMES utf8; +CREATE TABLE memos ( +id INT NOT NULL PRIMARY KEY, +content TEXT NOT NULL, +FULLTEXT INDEX (content) NORMALIZER='NormalizerAuto' +) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; +Table Create Table +memos CREATE TABLE `memos` ( + `id` int(11) NOT NULL, + `content` text NOT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `content` (`content`) `NORMALIZER`='NormalizerAuto' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"' +INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ"); +SELECT * FROM memos +WHERE MATCH (content) AGAINST ("+ã‚«ãƒãƒªãƒ¼" IN BOOLEAN MODE); +id content +1 1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔㌠+DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_parser_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result index d7b20a3714f..7ee07329f21 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_parser_comment.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result @@ -13,17 +13,17 @@ diaries CREATE TABLE `diaries` ( PRIMARY KEY (`id`), FULLTEXT KEY `body_index` (`body`) COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"' ) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"' -insert into diaries (body) values ("will start groonga!"); -insert into diaries (body) values ("starting groonga..."); -insert into diaries (body) values ("started groonga."); +insert into diaries (body) values ("will start Groonga!"); +insert into diaries (body) values ("starting Groonga..."); +insert into diaries (body) values ("started Groonga."); select * from diaries; id body -1 will start groonga! -2 starting groonga... -3 started groonga. -select * from diaries where match(body) against("start"); +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +select * from diaries where match(body) against("+start" in boolean mode) order by id; id body -1 will start groonga! -2 starting groonga... -3 started groonga. +1 will start Groonga! +2 starting Groonga... +3 started Groonga. drop table diaries; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result index 68319844df8..e1e32dccc37 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_multiple_token_filters.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true SET NAMES utf8; CREATE TABLE memos ( diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result index fa3012705ad..11ee04e2998 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_one_token_filter.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result @@ -1,5 +1,5 @@ -SELECT mroonga_command("register token_filters/stop_word"); -mroonga_command("register token_filters/stop_word") +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") true SET NAMES utf8; CREATE TABLE memos ( diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result new file mode 100644 index 00000000000..f6d6be1b643 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result @@ -0,0 +1,25 @@ +SELECT mroonga_command("plugin_register token_filters/stop_word"); +mroonga_command("plugin_register token_filters/stop_word") +true +SET NAMES utf8; +CREATE TABLE memos ( +id INT NOT NULL PRIMARY KEY, +content VARCHAR(64) NOT NULL, +FULLTEXT INDEX (content) TOKEN_FILTERS='TokenFilterStopWord,TokenFilterStopWord' +) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; +Table Create Table +memos CREATE TABLE `memos` ( + `id` int(11) NOT NULL, + `content` varchar(64) NOT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `content` (`content`) `TOKEN_FILTERS`='TokenFilterStopWord,TokenFilterStopWord' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"' +SELECT mroonga_command("dump --dump_plugins no"); +mroonga_command("dump --dump_plugins no") +table_create memos TABLE_HASH_KEY ShortText + +table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord + +column_create memos-content index COLUMN_INDEX|WITH_POSITION memos +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result new file mode 100644 index 00000000000..f6e15804f42 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result @@ -0,0 +1,29 @@ +drop table if exists diaries; +create table diaries ( +id int primary key auto_increment, +body text, +fulltext index body_index (body) +comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"' +) comment = 'engine "innodb"' default charset utf8; +show create table diaries; +Table Create Table +diaries CREATE TABLE `diaries` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `body` text, + PRIMARY KEY (`id`), + FULLTEXT KEY `body_index` (`body`) COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"' +insert into diaries (body) values ("will start Groonga!"); +insert into diaries (body) values ("starting Groonga..."); +insert into diaries (body) values ("started Groonga."); +select * from diaries; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +select * from diaries where match(body) against("+start" in boolean mode) order by id; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +drop table diaries; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result new file mode 100644 index 00000000000..ddec8fdadbe --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result @@ -0,0 +1,30 @@ +DROP TABLE IF EXISTS diaries; +CREATE TABLE diaries ( +id int PRIMARY KEY AUTO_INCREMENT, +body text, +FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit' +) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET utf8; +SHOW CREATE TABLE diaries; +Table Create Table +diaries CREATE TABLE `diaries` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `body` text, + PRIMARY KEY (`id`), + FULLTEXT KEY `body_index` (`body`) `TOKENIZER`='TokenBigramSplitSymbolAlphaDigit' +) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"' +INSERT INTO diaries (body) VALUES ("will start Groonga!"); +INSERT INTO diaries (body) VALUES ("starting Groonga..."); +INSERT INTO diaries (body) VALUES ("started Groonga."); +SELECT * FROM diaries; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +SELECT * FROM diaries +WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE) +ORDER BY id; +id body +1 will start Groonga! +2 starting Groonga... +3 started Groonga. +DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result index 14d30fac260..96d92e535d2 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result @@ -11,9 +11,10 @@ INSERT INTO memos VALUES (NULL, "Today is fine."); INSERT INTO memos VALUES (NULL, "Tomorrow will be fine."); INSERT INTO memos VALUES (NULL, "Yesterday was fine."); SELECT * FROM memos -WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE); +WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE) +ORDER BY id; id content 1 Today is good day. -3 Today is fine. 2 Tomorrow will be good day. +3 Today is fine. DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result index d367ba1d21f..ee8d851011f 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result @@ -11,7 +11,8 @@ INSERT INTO memos VALUES (NULL, "Today is fine."); INSERT INTO memos VALUES (NULL, "Tomorrow will be fine."); INSERT INTO memos VALUES (NULL, "Yesterday was fine."); SELECT * FROM memos -WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE); +WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE) +ORDER BY id; id content 2 Tomorrow will be good day. 3 Today is fine. diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result index 6bf48ab6556..bb94043256d 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result @@ -11,7 +11,8 @@ INSERT INTO memos VALUES (NULL, "Today is fine."); INSERT INTO memos VALUES (NULL, "Tomorrow will be fine."); INSERT INTO memos VALUES (NULL, "Yesterday was fine."); SELECT * FROM memos -WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE); +WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE) +ORDER BY id; id content 1 Today is good day. 2 Tomorrow will be good day. diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result index 03300e3e9ef..7391ee4ba8d 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result @@ -55,12 +55,12 @@ c1 c2 match(c2) against("ii") 3 aa ii ii ii oo 524289 select c1,c2,match(c2) against("ii") from t1 where match(c2) against("ii"); c1 c2 match(c2) against("ii") -1 aa ii uu ee oo 174763 3 aa ii ii ii oo 524289 5 ta ti ii ii to 349526 +1 aa ii uu ee oo 174763 select c1,c2,match(c2) against("ii") from t1 where match(c2) against("ii"); c1 c2 match(c2) against("ii") -1 aa ii uu ee oo 174763 3 aa ii ii ii oo 524289 5 ta ti ii ii to 349526 +1 aa ii uu ee oo 174763 drop table t1,t2; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result index 3809006038c..03cf96b55f8 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result @@ -4112,7 +4112,7 @@ insert into diaries values(4094, "2022-09-28"); insert into diaries values(4095, "2022-09-29"); commit; set autocommit=1; -select * from diaries where match(title) against("2022-09-0"); +select * from diaries where match(title) against("2022-09-0") order by id; id title 3824 2022-01-01 3825 2022-01-02 diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_matched_order.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_matched_order.result new file mode 100644 index 00000000000..def5db40cb9 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_matched_order.result @@ -0,0 +1,26 @@ +DROP TABLE IF EXISTS texts; +SET NAMES UTF8; +CREATE TABLE texts ( +id INT PRIMARY KEY, +matched TEXT, +not_matched TEXT, +FULLTEXT KEY (matched), +FULLTEXT KEY (not_matched) +) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"'; +INSERT INTO texts VALUES (1, 'Hello1', 'World1'); +INSERT INTO texts VALUES (2, 'Hello2', 'World2'); +INSERT INTO texts VALUES (3, 'Hello3', 'World3'); +SELECT id, +matched, +not_matched, +MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE), +MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) +FROM texts +WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) +ORDER BY MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE), +id; +id matched not_matched MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) +1 Hello1 World1 1 0 +2 Hello2 World2 1 0 +3 Hello3 World3 1 0 +DROP TABLE texts; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result new file mode 100644 index 00000000000..81ce556e745 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result @@ -0,0 +1,24 @@ +DROP TABLE IF EXISTS texts; +SET NAMES UTF8; +CREATE TABLE texts ( +id INT PRIMARY KEY, +matched TEXT, +not_matched TEXT, +FULLTEXT KEY (matched), +FULLTEXT KEY (not_matched) +) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"'; +INSERT INTO texts VALUES (1, 'Hello1', 'World1'); +INSERT INTO texts VALUES (2, 'Hello2', 'World2'); +INSERT INTO texts VALUES (3, 'Hello3', 'World3'); +SELECT id, +matched, +not_matched, +MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE), +MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) +FROM texts +WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE); +id matched not_matched MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) +1 Hello1 World1 1 0 +3 Hello3 World3 1 0 +2 Hello2 World2 1 0 +DROP TABLE texts; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_no_where_both_order.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_no_where_both_order.result new file mode 100644 index 00000000000..f619e467040 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_no_where_both_order.result @@ -0,0 +1,26 @@ +DROP TABLE IF EXISTS texts; +SET NAMES UTF8; +CREATE TABLE texts ( +id INT PRIMARY KEY, +matched TEXT, +not_matched TEXT, +FULLTEXT KEY (matched), +FULLTEXT KEY (not_matched) +) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"'; +INSERT INTO texts VALUES (1, 'Hello1', 'World1'); +INSERT INTO texts VALUES (2, 'Hello2', 'World2'); +INSERT INTO texts VALUES (3, 'Hello3', 'World3'); +SELECT id, +matched, +not_matched, +MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE), +MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) +FROM texts +ORDER BY MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE), +MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE), +id; +id matched not_matched MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) +1 Hello1 World1 1 0 +2 Hello2 World2 1 0 +3 Hello3 World3 1 0 +DROP TABLE texts; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result index de1b8d41906..860c8e548a8 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result @@ -36,17 +36,17 @@ c1 c2 c3 3 30 sa si su se so 4 40 ta ti tu te to 5 50 aa ii uu ee oo -select * from t1 where match(c3) against("su"); +select * from t1 where match(c3) against("su") order by c1; c1 c2 c3 3 30 sa si su se so -select * from t1 where match(c3) against("ii"); +select * from t1 where match(c3) against("ii") order by c1; c1 c2 c3 1 10 aa ii uu ee oo 5 50 aa ii uu ee oo -select * from t1 where match(c3) against("+su" in boolean mode); +select * from t1 where match(c3) against("+su" in boolean mode) order by c1; c1 c2 c3 3 30 sa si su se so -select * from t1 where match(c3) against("+ii" in boolean mode); +select * from t1 where match(c3) against("+ii" in boolean mode) order by c1; c1 c2 c3 1 10 aa ii uu ee oo 5 50 aa ii uu ee oo @@ -61,10 +61,10 @@ c1 c2 c3 1 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠ã‚ã‚ã‚ã‚ã‚ã‚ã‚ 2 ã„ã„ã„ã„ㄠ明日ã®å¯Œå£«å±±ã®å¤©æ°—ã¯åˆ†ã‹ã‚Šã¾ã›ã‚“ 3 dummy dummy -select * from t1 where match(c2) against("富士山"); +select * from t1 where match(c2) against("富士山") order by c1; c1 c2 c3 1 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠ã‚ã‚ã‚ã‚ã‚ã‚ã‚ -select * from t1 where match(c3) against("富士山"); +select * from t1 where match(c3) against("富士山") order by c1; c1 c2 c3 2 ã„ã„ã„ã„ㄠ明日ã®å¯Œå£«å±±ã®å¤©æ°—ã¯åˆ†ã‹ã‚Šã¾ã›ã‚“ drop table t1; @@ -124,14 +124,14 @@ c1 c2 match(c2) against("ii") 3 aa ii ii ii oo 524289 select c1,c2,match(c2) against("ii") from t1 where match(c2) against("ii"); c1 c2 match(c2) against("ii") -1 aa ii uu ee oo 174763 3 aa ii ii ii oo 524289 5 ta ti ii ii to 349526 +1 aa ii uu ee oo 174763 select c1,c2,match(c2) against("ii") from t1 where match(c2) against("ii"); c1 c2 match(c2) against("ii") -1 aa ii uu ee oo 174763 3 aa ii ii ii oo 524289 5 ta ti ii ii to 349526 +1 aa ii uu ee oo 174763 drop table t1,t2; create table t1 (c1 int primary key, c2 int, c3 text, fulltext index ft(c3)) COMMENT = 'engine "myisam"'; insert into t1 values(1,10,"aa ii uu ee oo"); @@ -152,7 +152,7 @@ c1 c2 c3 6 20 ka ki ku ke ko 7 20 aa ii uu ee oo 8 20 ka ki ku ke ko -select *,match(c3) against("uu") from t1 where match(c3) against("uu"); +select *,match(c3) against("uu") from t1 where match(c3) against("uu") order by c1; c1 c2 c3 match(c3) against("uu") 1 10 aa ii uu ee oo 131073 3 10 aa ii uu ee oo 131073 diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result index bbe23df3e0f..4646aad6a20 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result @@ -18,21 +18,21 @@ c1 c2 c3 6 20 ka ki ku ke ko 7 20 aa ii uu ee oo 8 20 ka ki ku ke ko -select *,match(c3) against("uu") from t1 where match(c3) against("uu"); +select *,match(c3) against("uu") from t1 where match(c3) against("uu") order by c1; c1 c2 c3 match(c3) against("uu") 1 10 aa ii uu ee oo 131073 3 10 aa ii uu ee oo 131073 5 20 aa ii uu ee oo 131073 7 20 aa ii uu ee oo 131073 -select * from t1 where not match(c3) against("uu"); +select * from t1 where not match(c3) against("uu") order by c1; c1 c2 c3 2 10 ka ki ku ke ko 4 10 ka ki ku ke ko 6 20 ka ki ku ke ko 8 20 ka ki ku ke ko -select *,match(c3) against("dummy") from t1 where match(c3) against("dummy"); +select *,match(c3) against("dummy") from t1 where match(c3) against("dummy") order by c1; c1 c2 c3 match(c3) against("dummy") -select * from t1 where not match(c3) against("dummy"); +select * from t1 where not match(c3) against("dummy") order by c1; c1 c2 c3 1 10 aa ii uu ee oo 2 10 ka ki ku ke ko @@ -42,26 +42,26 @@ c1 c2 c3 6 20 ka ki ku ke ko 7 20 aa ii uu ee oo 8 20 ka ki ku ke ko -select * from t1 where c1 = 4 and not match(c3) against("uu"); +select * from t1 where c1 = 4 and not match(c3) against("uu") order by c1; c1 c2 c3 4 10 ka ki ku ke ko -select * from t1 where c1 <= 4 and not match(c3) against("uu"); +select * from t1 where c1 <= 4 and not match(c3) against("uu") order by c1; c1 c2 c3 2 10 ka ki ku ke ko 4 10 ka ki ku ke ko -select * from t1 where c1 > 4 and not match(c3) against("uu"); +select * from t1 where c1 > 4 and not match(c3) against("uu") order by c1; c1 c2 c3 6 20 ka ki ku ke ko 8 20 ka ki ku ke ko -select * from t1 where c2 = 10 and not match(c3) against("uu"); +select * from t1 where c2 = 10 and not match(c3) against("uu") order by c1; c1 c2 c3 2 10 ka ki ku ke ko 4 10 ka ki ku ke ko -select * from t1 where c2 >= 15 and not match(c3) against("uu"); +select * from t1 where c2 >= 15 and not match(c3) against("uu") order by c1; c1 c2 c3 6 20 ka ki ku ke ko 8 20 ka ki ku ke ko -select * from t1 where c2 < 15 and not match(c3) against("uu"); +select * from t1 where c2 < 15 and not match(c3) against("uu") order by c1; c1 c2 c3 2 10 ka ki ku ke ko 4 10 ka ki ku ke ko diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result index 279ad8bf985..18d78d88c93 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result @@ -29,22 +29,6 @@ a b c SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE); a b c 2 bbbbb bcdef -SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE); -a b c -2 bbbbb bcdef SELECT a, b, c FROM ft WHERE MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE); a b c -SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE); -a b c MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) -2 bbbbb bcdef 1 0 -SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE); -a b c MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) -2 bbbbb bcdef 1 0 -SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), a; -a b c MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) -1 aaaaa abcde 0 0 -3 ccccc cdefg 0 0 -4 ddddd defgh 0 0 -5 eeeee efghi 0 0 -2 bbbbb bcdef 1 0 DROP TABLE ft; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result index 35b273d348f..d41231ddd33 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result @@ -31,15 +31,18 @@ id year month day title content 1 2011 11 9 Hello 今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚ 2 2011 11 10 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠3 2011 11 11 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚ -SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE); +SELECT * FROM diaries +WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE) +ORDER BY id; id year month day title content 1 2011 11 9 Hello 今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚ 3 2011 11 11 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚ -2 2011 11 10 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠TRUNCATE TABLE diaries; SELECT * FROM diaries; id year month day title content -SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE); +SELECT * FROM diaries +WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE) +ORDER BY id; id year month day title content INSERT INTO diaries VALUES(1, 2011, 11, 11, "帰りé“", "ã¤ã‹ã‚ŒãŸãƒ¼"); INSERT INTO diaries VALUES(2, 2011, 12, 1, "ä¹…ã—ã¶ã‚Š", "天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚"); @@ -49,7 +52,9 @@ id year month day title content 1 2011 11 11 å¸°ã‚Šé“ ã¤ã‹ã‚ŒãŸãƒ¼ 2 2011 12 1 ä¹…ã—ã¶ã‚Š 天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚ 3 2011 12 2 åˆé›ª 今年ã¯ã˜ã‚ã¦ã®é›ªï¼ -SELECT * FROM diaries WHERE MATCH(content) AGAINST("悪ã„" IN BOOLEAN MODE); +SELECT * FROM diaries +WHERE MATCH(content) AGAINST("+悪ã„" IN BOOLEAN MODE) +ORDER BY id; id year month day title content 2 2011 12 1 ä¹…ã—ã¶ã‚Š 天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚ DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm b/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm index b6e2d741674..528ccc5d693 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm +++ b/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm @@ -4,11 +4,6 @@ package My::Suite::Mroonga; return "No Mroonga engine" unless $ENV{HA_MROONGA_SO} or $::mysqld_variables{'mroonga'} eq "ON"; -# -# RECOMPILE_FOR_EMBEDDED also means that a plugin -# cannot be dynamically loaded into embedded -return "Not run for embedded server" if $::opt_embedded_server and - $ENV{HA_MROONGA_SO}; sub is_default { 1 } diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test index 70c176b5116..899f00320c9 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test @@ -15,7 +15,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source include/have_innodb.inc ---source ../../include/mroonga/have_fulltext_index_comment.inc --source ../../include/mroonga/have_mroonga.inc --disable_query_log diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test new file mode 100644 index 00000000000..0b2565f2fb5 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test @@ -0,0 +1,40 @@ +# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SET NAMES utf8; + +CREATE TABLE memos ( + content VARCHAR(64) NOT NULL PRIMARY KEY, + FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"' +) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8; + +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test new file mode 100644 index 00000000000..656a349c1be --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test @@ -0,0 +1,40 @@ +# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SET NAMES utf8; + +CREATE TABLE memos ( + content VARCHAR(64) NOT NULL PRIMARY KEY, + FULLTEXT INDEX (content) COMMENT 'flags "NONE"' +) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8; + +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test new file mode 100644 index 00000000000..6b1a4c8dec2 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test @@ -0,0 +1,42 @@ +# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SET NAMES utf8; + +CREATE TABLE memos ( + content VARCHAR(64) NOT NULL PRIMARY KEY, + FULLTEXT INDEX (content) FLAGS='WITH_POSITION|WITH_WEIGHT' +) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; + +SELECT mroonga_command("dump --dump_plugins no --dump_schema no"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test new file mode 100644 index 00000000000..3b84e5d1bce --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test @@ -0,0 +1,40 @@ +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS memos; +--enable_warnings + +SET NAMES utf8; + +CREATE TABLE memos ( + id INT NOT NULL PRIMARY KEY, + content TEXT NOT NULL, + FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"' +) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; + +INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ"); + +SELECT * FROM memos + WHERE MATCH (content) AGAINST ("+ã‚«ãƒãƒªãƒ¼" IN BOOLEAN MODE); + +DROP TABLE memos; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test new file mode 100644 index 00000000000..b8fe3eb6c7d --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test @@ -0,0 +1,41 @@ +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS memos; +--enable_warnings + +SET NAMES utf8; + +CREATE TABLE memos ( + id INT NOT NULL PRIMARY KEY, + content TEXT NOT NULL, + FULLTEXT INDEX (content) NORMALIZER='NormalizerAuto' +) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; + +INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ"); + +SELECT * FROM memos + WHERE MATCH (content) AGAINST ("+ã‚«ãƒãƒªãƒ¼" IN BOOLEAN MODE); + +DROP TABLE memos; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_parser_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test index fe80aae0804..05fc2fdcb9d 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_parser_comment.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -15,7 +15,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source include/have_innodb.inc ---source ../../include/mroonga/have_fulltext_index_comment.inc --source ../../include/mroonga/have_mroonga.inc --disable_warnings @@ -29,11 +28,11 @@ create table diaries ( comment 'parser "TokenBigramSplitSymbolAlphaDigit"' ) comment = 'engine "innodb"' default charset utf8; show create table diaries; -insert into diaries (body) values ("will start groonga!"); -insert into diaries (body) values ("starting groonga..."); -insert into diaries (body) values ("started groonga."); +insert into diaries (body) values ("will start Groonga!"); +insert into diaries (body) values ("starting Groonga..."); +insert into diaries (body) values ("started Groonga."); select * from diaries; -select * from diaries where match(body) against("start"); +select * from diaries where match(body) against("+start" in boolean mode) order by id; drop table diaries; --source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test index 9ff8e4448d9..472f26cda6e 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_multiple_token_filters.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test @@ -16,6 +16,7 @@ --source include/have_innodb.inc --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -24,7 +25,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); SET NAMES utf8; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test index eee08309f76..0d3c00e2c98 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_one_token_filter.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test @@ -16,6 +16,7 @@ --source include/have_innodb.inc --source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc --source ../../include/mroonga/load_mroonga_functions.inc --disable_query_log @@ -24,7 +25,7 @@ CREATE DATABASE test; USE test; --enable_query_log -SELECT mroonga_command("register token_filters/stop_word"); +SELECT mroonga_command("plugin_register token_filters/stop_word"); SET NAMES utf8; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test new file mode 100644 index 00000000000..9decafaf1e7 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test @@ -0,0 +1,46 @@ +# Copyright(C) 2014 Naoya Murakami <naoya@createfield.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mariadb.inc +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/have_groonga_plugin_register.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SELECT mroonga_command("plugin_register token_filters/stop_word"); + +SET NAMES utf8; + +CREATE TABLE memos ( + id INT NOT NULL PRIMARY KEY, + content VARCHAR(64) NOT NULL, + FULLTEXT INDEX (content) TOKEN_FILTERS='TokenFilterStopWord,TokenFilterStopWord' +) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8; +SHOW CREATE TABLE memos; + +SELECT mroonga_command("dump --dump_plugins no"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test index 24cc173485a..5053de07781 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_comment.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -14,7 +14,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---source ../../include/mroonga/have_fulltext_index_comment.inc +--source include/have_innodb.inc --source ../../include/mroonga/have_mroonga.inc --disable_warnings @@ -25,14 +25,14 @@ create table diaries ( id int primary key auto_increment, body text, fulltext index body_index (body) - comment 'parser "TokenBigramSplitSymbolAlphaDigit"' -) default charset utf8; + comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"' +) comment = 'engine "innodb"' default charset utf8; show create table diaries; -insert into diaries (body) values ("will start groonga!"); -insert into diaries (body) values ("starting groonga..."); -insert into diaries (body) values ("started groonga."); +insert into diaries (body) values ("will start Groonga!"); +insert into diaries (body) values ("starting Groonga..."); +insert into diaries (body) values ("started Groonga."); select * from diaries; -select * from diaries where match(body) against("start"); +select * from diaries where match(body) against("+start" in boolean mode) order by id; drop table diaries; --source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test index c4265ffd22e..7c688199314 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test @@ -1,4 +1,4 @@ -# Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -14,30 +14,30 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +--source ../../include/mroonga/have_mariadb.inc --source include/have_innodb.inc --source ../../include/mroonga/have_mroonga.inc ---source ../../include/mroonga/load_mroonga_functions.inc --disable_warnings DROP TABLE IF EXISTS diaries; --enable_warnings -SET NAMES utf8; - CREATE TABLE diaries ( - day DATE PRIMARY KEY, - content VARCHAR(64) NOT NULL, - FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"' -) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + id int PRIMARY KEY AUTO_INCREMENT, + body text, + FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit' +) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET utf8; +SHOW CREATE TABLE diaries; -INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んã 。"); +INSERT INTO diaries (body) VALUES ("will start Groonga!"); +INSERT INTO diaries (body) VALUES ("starting Groonga..."); +INSERT INTO diaries (body) VALUES ("started Groonga."); +SELECT * FROM diaries; SELECT * FROM diaries - WHERE MATCH (content) AGAINST ("+ãµã‚‰ã¤ã" IN BOOLEAN MODE); -SELECT * FROM diaries - WHERE MATCH (content) AGAINST ("+ブラック" IN BOOLEAN MODE); + WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE) + ORDER BY id; DROP TABLE diaries; ---source ../../include/mroonga/unload_mroonga_functions.inc --source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test index 6a89d7556ab..c561ac84c98 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -35,7 +35,8 @@ INSERT INTO memos VALUES (NULL, "Tomorrow will be fine."); INSERT INTO memos VALUES (NULL, "Yesterday was fine."); SELECT * FROM memos - WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE); + WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE) + ORDER BY id; DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test index 790d2f1c9a9..cc3c6cef5b8 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -35,7 +35,8 @@ INSERT INTO memos VALUES (NULL, "Tomorrow will be fine."); INSERT INTO memos VALUES (NULL, "Yesterday was fine."); SELECT * FROM memos - WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE); + WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE) + ORDER BY id; DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test index a45c414580d..7002db06461 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -35,7 +35,8 @@ INSERT INTO memos VALUES (NULL, "Tomorrow will be fine."); INSERT INTO memos VALUES (NULL, "Yesterday was fine."); SELECT * FROM memos - WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE); + WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE) + ORDER BY id; DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test index 6037ab61da0..26c784391ab 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test @@ -1,5 +1,5 @@ # Copyright(C) 2010 Tetsuro IKEDA -# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test index c12441f3c5a..442b4f248d9 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -4129,7 +4129,7 @@ insert into diaries values(4095, "2022-09-29"); commit; set autocommit=1; -select * from diaries where match(title) against("2022-09-0"); +select * from diaries where match(title) against("2022-09-0") order by id; drop table diaries; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test new file mode 100644 index 00000000000..2ed609d9fe2 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test @@ -0,0 +1,50 @@ +# Copyright(C) 2012 Kentoku SHIBA +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS texts; +--enable_warnings + +SET NAMES UTF8; +CREATE TABLE texts ( + id INT PRIMARY KEY, + matched TEXT, + not_matched TEXT, + FULLTEXT KEY (matched), + FULLTEXT KEY (not_matched) +) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"'; + +INSERT INTO texts VALUES (1, 'Hello1', 'World1'); +INSERT INTO texts VALUES (2, 'Hello2', 'World2'); +INSERT INTO texts VALUES (3, 'Hello3', 'World3'); + +SELECT id, + matched, + not_matched, + MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE), + MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) + FROM texts + WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) + ORDER BY MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE), + id; + +DROP TABLE texts; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test new file mode 100644 index 00000000000..968a763917d --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test @@ -0,0 +1,48 @@ +# Copyright(C) 2012 Kentoku SHIBA +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS texts; +--enable_warnings + +SET NAMES UTF8; +CREATE TABLE texts ( + id INT PRIMARY KEY, + matched TEXT, + not_matched TEXT, + FULLTEXT KEY (matched), + FULLTEXT KEY (not_matched) +) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"'; + +INSERT INTO texts VALUES (1, 'Hello1', 'World1'); +INSERT INTO texts VALUES (2, 'Hello2', 'World2'); +INSERT INTO texts VALUES (3, 'Hello3', 'World3'); + +SELECT id, + matched, + not_matched, + MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE), + MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) + FROM texts + WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE); + +DROP TABLE texts; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test new file mode 100644 index 00000000000..a0ae0ef8a2e --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test @@ -0,0 +1,50 @@ +# Copyright(C) 2012 Kentoku SHIBA +# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/have_innodb.inc +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS texts; +--enable_warnings + +SET NAMES UTF8; +CREATE TABLE texts ( + id INT PRIMARY KEY, + matched TEXT, + not_matched TEXT, + FULLTEXT KEY (matched), + FULLTEXT KEY (not_matched) +) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"'; + +INSERT INTO texts VALUES (1, 'Hello1', 'World1'); +INSERT INTO texts VALUES (2, 'Hello2', 'World2'); +INSERT INTO texts VALUES (3, 'Hello3', 'World3'); + +SELECT id, + matched, + not_matched, + MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE), + MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE) + FROM texts + ORDER BY MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE), + MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE), + id; + +DROP TABLE texts; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test index eda8a5f15ef..4b872eb054c 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test @@ -1,5 +1,5 @@ # Copyright(C) 2010 Tetsuro IKEDA -# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -38,10 +38,10 @@ insert into t1 values(3,30,"sa si su se so"); insert into t1 values(4,40,"ta ti tu te to"); insert into t1 values(5,50,"aa ii uu ee oo"); select * from t1; -select * from t1 where match(c3) against("su"); -select * from t1 where match(c3) against("ii"); -select * from t1 where match(c3) against("+su" in boolean mode); -select * from t1 where match(c3) against("+ii" in boolean mode); +select * from t1 where match(c3) against("su") order by c1; +select * from t1 where match(c3) against("ii") order by c1; +select * from t1 where match(c3) against("+su" in boolean mode) order by c1; +select * from t1 where match(c3) against("+ii" in boolean mode) order by c1; drop table t1; set names utf8; @@ -50,8 +50,8 @@ insert into t1 values(1, "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦","ã‚ã‚ã‚ã‚ insert into t1 values(2, "ã„ã„ã„ã„ã„","明日ã®å¯Œå£«å±±ã®å¤©æ°—ã¯åˆ†ã‹ã‚Šã¾ã›ã‚“"); insert into t1 values(3, "dummy", "dummy"); select * from t1; -select * from t1 where match(c2) against("富士山"); -select * from t1 where match(c3) against("富士山"); +select * from t1 where match(c2) against("富士山") order by c1; +select * from t1 where match(c3) against("富士山") order by c1; drop table t1; create table t1 (c1 int primary key, c2 varchar(100), fulltext index(c2)) default charset utf8 COMMENT = 'engine "myisam"'; @@ -87,7 +87,7 @@ insert into t1 values(6,20,"ka ki ku ke ko"); insert into t1 values(7,20,"aa ii uu ee oo"); insert into t1 values(8,20,"ka ki ku ke ko"); select * from t1; -select *,match(c3) against("uu") from t1 where match(c3) against("uu"); +select *,match(c3) against("uu") from t1 where match(c3) against("uu") order by c1; select * from t1 where not match(c3) against("uu"); select *,match(c3) against("dummy") from t1 where match(c3) against("dummy"); select * from t1 where not match(c3) against("dummy"); diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test index 6ce01598136..43fc4b2771a 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test @@ -1,5 +1,5 @@ # Copyright(C) 2010 Tetsuro IKEDA -# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -32,16 +32,16 @@ insert into t1 values(6,20,"ka ki ku ke ko"); insert into t1 values(7,20,"aa ii uu ee oo"); insert into t1 values(8,20,"ka ki ku ke ko"); select * from t1; -select *,match(c3) against("uu") from t1 where match(c3) against("uu"); -select * from t1 where not match(c3) against("uu"); -select *,match(c3) against("dummy") from t1 where match(c3) against("dummy"); -select * from t1 where not match(c3) against("dummy"); -select * from t1 where c1 = 4 and not match(c3) against("uu"); -select * from t1 where c1 <= 4 and not match(c3) against("uu"); -select * from t1 where c1 > 4 and not match(c3) against("uu"); -select * from t1 where c2 = 10 and not match(c3) against("uu"); -select * from t1 where c2 >= 15 and not match(c3) against("uu"); -select * from t1 where c2 < 15 and not match(c3) against("uu"); +select *,match(c3) against("uu") from t1 where match(c3) against("uu") order by c1; +select * from t1 where not match(c3) against("uu") order by c1; +select *,match(c3) against("dummy") from t1 where match(c3) against("dummy") order by c1; +select * from t1 where not match(c3) against("dummy") order by c1; +select * from t1 where c1 = 4 and not match(c3) against("uu") order by c1; +select * from t1 where c1 <= 4 and not match(c3) against("uu") order by c1; +select * from t1 where c1 > 4 and not match(c3) against("uu") order by c1; +select * from t1 where c2 = 10 and not match(c3) against("uu") order by c1; +select * from t1 where c2 >= 15 and not match(c3) against("uu") order by c1; +select * from t1 where c2 < 15 and not match(c3) against("uu") order by c1; drop table t1; --source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test index 5361b151661..4835f3dcd99 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test @@ -40,11 +40,7 @@ INSERT INTO ft VALUES(5,'eeeee','efghi'); SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE); SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE); -SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE); SELECT a, b, c FROM ft WHERE MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE); -SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE); -SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE); -SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), a; DROP TABLE ft; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test index 987fd284f74..8723a882ae9 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test @@ -1,4 +1,4 @@ -# Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com> +# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -39,17 +39,23 @@ INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚"); SELECT * FROM diaries; -SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE); +SELECT * FROM diaries + WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE) + ORDER BY id; TRUNCATE TABLE diaries; SELECT * FROM diaries; -SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE); +SELECT * FROM diaries + WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE) + ORDER BY id; INSERT INTO diaries VALUES(1, 2011, 11, 11, "帰りé“", "ã¤ã‹ã‚ŒãŸãƒ¼"); INSERT INTO diaries VALUES(2, 2011, 12, 1, "ä¹…ã—ã¶ã‚Š", "天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚"); INSERT INTO diaries VALUES(3, 2011, 12, 2, "åˆé›ª", "今年ã¯ã˜ã‚ã¦ã®é›ªï¼"); SELECT * FROM diaries; -SELECT * FROM diaries WHERE MATCH(content) AGAINST("悪ã„" IN BOOLEAN MODE); +SELECT * FROM diaries + WHERE MATCH(content) AGAINST("+悪ã„" IN BOOLEAN MODE) + ORDER BY id; DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test index 065b78d44a7..9704d2d3e53 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test @@ -15,7 +15,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source include/have_innodb.inc ---source ../../include/mroonga/have_fulltext_index_comment.inc --source ../../include/mroonga/have_mroonga.inc --disable_warnings diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test index b47dcef3967..c6967790b01 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test @@ -15,7 +15,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source include/have_innodb.inc ---source ../../include/mroonga/have_fulltext_index_comment.inc --source ../../include/mroonga/have_mroonga.inc --disable_warnings diff --git a/storage/mroonga/packages/apt/build-deb.sh b/storage/mroonga/packages/apt/build-deb.sh index 7db24068a7c..510886cb24f 100755 --- a/storage/mroonga/packages/apt/build-deb.sh +++ b/storage/mroonga/packages/apt/build-deb.sh @@ -27,8 +27,8 @@ case "${distribution}" in debian) component=main run cat <<EOF > /etc/apt/sources.list.d/groonga.list -deb http://packages.groonga.org/debian/ wheezy main -deb-src http://packages.groonga.org/debian/ wheezy main +deb http://packages.groonga.org/debian/ ${code_name} main +deb-src http://packages.groonga.org/debian/ ${code_name} main EOF if ! grep --quiet security /etc/apt/sources.list; then run cat <<EOF > /etc/apt/sources.list.d/security.list @@ -75,4 +75,4 @@ run cd - package_initial=$(echo "${PACKAGE}" | sed -e 's/\(.\).*/\1/') pool_dir="/vagrant/repositories/${distribution}/pool/${code_name}/${component}/${package_initial}/${PACKAGE}" run mkdir -p "${pool_dir}/" -run cp *.tar.gz *.diff.gz *.dsc *.deb "${pool_dir}/" +run cp *.tar.* *.diff.gz *.dsc *.deb "${pool_dir}/" diff --git a/storage/mroonga/packages/debian/changelog b/storage/mroonga/packages/debian/changelog index d3025d96100..366edca7b4e 100644 --- a/storage/mroonga/packages/debian/changelog +++ b/storage/mroonga/packages/debian/changelog @@ -1,3 +1,15 @@ +mroonga (5.04-1) unstable; urgency=low + + * New upstream release. + + -- Masafumi Yokoyama <myokoym@gmail.com> Mon, 29 Jun 2015 00:00:00 +0900 + +mroonga (5.03-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro <hayashi@clear-code.com> Fri, 29 May 2015 00:00:00 +0900 + mroonga (5.02-1) unstable; urgency=low * New upstream release. diff --git a/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in index ca48e59aaec..04d1c41f2cc 100644 --- a/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in +++ b/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in @@ -154,6 +154,12 @@ fi %doc mysql-mroonga-doc/* %changelog +* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1 +- new upstream release. + +* Fri May 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.03-1 +- new upstream release. + * Wed Apr 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.02-1 - new upstream release. diff --git a/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in index 1fc641b9bca..e20e1b32162 100644 --- a/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in +++ b/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in @@ -163,6 +163,12 @@ fi %doc mysql-mroonga-doc/* %changelog +* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1 +- new upstream release. + +* Fri May 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.03-1 +- new upstream release. + * Wed Apr 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.02-1 - new upstream release. diff --git a/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in index 53759e0c778..f3233d17afe 100644 --- a/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in +++ b/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in @@ -1,14 +1,14 @@ %{!?centos_ver:%define centos_ver 6} %if %{centos_ver} == 7 -%define mysql_version_default 5.6.24 -%define mysql_release_default 3 +%define mysql_version_default 5.6.25 +%define mysql_release_default 2 %define mysql_dist_default el7 %define mysql_download_base_url_default http://repo.mysql.com/yum/mysql-5.6-community/el/7/SRPMS %define mysql_spec_file_default mysql.spec %else -%define mysql_version_default 5.6.24 -%define mysql_release_default 3 +%define mysql_version_default 5.6.25 +%define mysql_release_default 2 %define mysql_dist_default el6 %define mysql_download_base_url_default http://repo.mysql.com/yum/mysql-5.6-community/el/6/SRPMS %define mysql_spec_file_default mysql.spec @@ -77,7 +77,10 @@ if [ ! -d ${mysql_source} ]; then --define 'optflags -O0' \ ../../SPECS/%{mysql_spec_file} fi -%configure --disable-static --with-mysql-source=${mysql_source} \ +%configure \ + --disable-static \ + --with-mysql-source=${mysql_source} \ + --enable-fast-mutexes \ %{?mroonga_configure_options} make %{?_smp_mflags} @@ -91,6 +94,13 @@ mv $RPM_BUILD_ROOT%{_datadir}/doc/mroonga/ mysql-mroonga-doc/ rm -rf $RPM_BUILD_ROOT %post +if ! /sbin/service mysqld status > /dev/null; then + /sbin/service mysqld start + stop_after_installation=1 +else + stop_after_installation=0 +fi + mysql_command=`which mysql` password_option="" $mysql_command -u root -e "quit" @@ -129,7 +139,18 @@ eval $command || \ (echo "run the following command to register Mroonga:"; \ echo " $command") +if [ "$stop_after_installation" = "1" ]; then + /sbin/service mysqld stop +fi + %preun +if ! /sbin/service mysqld status > /dev/null; then + /sbin/service mysqld start + stop_after_uninstallation=1 +else + stop_after_uninstallation=0 +fi + uninstall_sql=%{_datadir}/mroonga/uninstall.sql mysql_command=`which mysql` if $mysql_command -u root -e "quit"; then @@ -145,6 +166,10 @@ if [ "$1" = 0 ]; then echo " $command") fi +if [ "$stop_after_uninstallation" = "1" ]; then + /sbin/service mysqld stop +fi + %files %defattr(-,root,root,-) %{_libdir}/mysql/plugin/ @@ -158,6 +183,15 @@ fi %doc mysql-mroonga-doc/* %changelog +* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1 +- new upstream release. + +* Thu Jun 02 2015 Masafumi Yokoyama <yokoyama@clear-code.com> - 5.03-2 +- build against MySQL 5.6.25. + +* Fri May 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.03-1 +- new upstream release. + * Wed Apr 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.02-1 - new upstream release. diff --git a/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in index f0306cace24..cf1947e2676 100644 --- a/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in +++ b/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in @@ -1,7 +1,7 @@ %{!?centos_ver:%define centos_ver 6} -%define mysql_version_default 5.6.23 -%define mysql_release_default rel72.1 +%define mysql_version_default 5.6.24 +%define mysql_release_default rel72.2 %define mysql_dist_default %{?dist} %define mysql_download_base_url_default http://repo.percona.com/centos/%{centos_ver}/SRPMS %define mysql_spec_file_default percona-server.spec @@ -85,6 +85,13 @@ mv $RPM_BUILD_ROOT%{_datadir}/doc/mroonga/ mysql-mroonga-doc/ rm -rf $RPM_BUILD_ROOT %post +if ! /sbin/service mysql status > /dev/null; then + /sbin/service mysql start + stop_after_installation=1 +else + stop_after_installation=0 +fi + mysql_command=`which mysql` password_option="" $mysql_command -u root -e "quit" @@ -123,7 +130,18 @@ eval $command || \ (echo "run the following command to register Mroonga:"; \ echo " $command") +if [ "$stop_after_installation" = "1" ]; then + /sbin/service mysql stop +fi + %preun +if ! /sbin/service mysql status > /dev/null; then + /sbin/service mysql start + stop_after_uninstallation=1 +else + stop_after_uninstallation=0 +fi + uninstall_sql=%{_datadir}/mroonga/uninstall.sql mysql_command=`which mysql` if $mysql_command -u root -e "quit"; then @@ -139,6 +157,10 @@ if [ "$1" = 0 ]; then echo " $command") fi +if [ "$stop_after_uninstallation" = "1" ]; then + /sbin/service mysql stop +fi + %files %defattr(-,root,root,-) %{_libdir}/mysql/plugin/ diff --git a/storage/mroonga/packages/source/Makefile.am b/storage/mroonga/packages/source/Makefile.am index 0f242c4e038..143f5d0387e 100644 --- a/storage/mroonga/packages/source/Makefile.am +++ b/storage/mroonga/packages/source/Makefile.am @@ -1,17 +1,17 @@ MROONGA_BASE = $(PACKAGE)-$(VERSION) MROONGA_TAR_GZ = $(MROONGA_BASE).tar.gz -GROONGA_VERSION = 5.0.3 +GROONGA_VERSION = 5.0.5 GROONGA_BASE = groonga-$(GROONGA_VERSION) GROONGA_TAR_GZ = $(GROONGA_BASE).tar.gz -GROONGA_NORMALIZER_MYSQL_VERSION = 1.0.9 +GROONGA_NORMALIZER_MYSQL_VERSION = 1.1.0 GROONGA_NORMALIZER_MYSQL_BASE = \ groonga-normalizer-mysql-$(GROONGA_NORMALIZER_MYSQL_VERSION) GROONGA_NORMALIZER_MYSQL_TAR_GZ = \ $(GROONGA_NORMALIZER_MYSQL_BASE).tar.gz -MARIADB_VERSION = 10.0.17 +MARIADB_VERSION = 10.0.20 MARIADB_BASE = mariadb-$(MARIADB_VERSION) MARIADB_TAR_GZ = $(MARIADB_BASE).tar.gz diff --git a/storage/mroonga/packages/ubuntu/upload.rb b/storage/mroonga/packages/ubuntu/upload.rb index 79331a06c8d..8743520b5ac 100755 --- a/storage/mroonga/packages/ubuntu/upload.rb +++ b/storage/mroonga/packages/ubuntu/upload.rb @@ -127,8 +127,8 @@ allow_unsigned_uploads = 0 case code_name when "vivid" run_command("sed", - "-i", "-e", "s,5\.5,5\.6,g", - "debian/rules") + "-i", "-e", "s,5\\.5,5.6,g", + "debian/rules") end run_command("sed", "-i", "-e", "s,MYSQL_VERSION,#{@mysql_version[code_name]},", diff --git a/storage/mroonga/packages/yum/sign-rpm.sh b/storage/mroonga/packages/yum/sign-rpm.sh index b3a45afe7f5..27ec5711010 100755 --- a/storage/mroonga/packages/yum/sign-rpm.sh +++ b/storage/mroonga/packages/yum/sign-rpm.sh @@ -24,7 +24,7 @@ run() unsigned_rpms() { while read rpm; do - rpm --checksig "$rpm" | grep -v 'gpg OK' | cut -d":" -f1 + rpm --checksig "$rpm" | grep -v 'gpg OK' | grep -v 'MISSING KEYS' | cut -d":" -f1 done } diff --git a/storage/mroonga/plugin_version b/storage/mroonga/plugin_version index 341d0b550fd..48c32b26a12 100644 --- a/storage/mroonga/plugin_version +++ b/storage/mroonga/plugin_version @@ -1 +1 @@ -5.2
\ No newline at end of file +5.4
\ No newline at end of file diff --git a/storage/mroonga/tools/travis/before_script.sh b/storage/mroonga/tools/travis/before_script.sh index 7d4d7dcec5f..1b3ba158675 100755 --- a/storage/mroonga/tools/travis/before_script.sh +++ b/storage/mroonga/tools/travis/before_script.sh @@ -20,9 +20,26 @@ set -e if [ "${MROONGA_BUNDLED}" = "yes" ]; then - cmake_args=(-DCMAKE_BUILD_TYPE=Debug) + cmake_args=(-DCMAKE_BUILD_TYPE=Debug -DWITH_UNIT_TESTS=FALSE) + cmake_args=("${cmake_args[@]}" -DWITH_EMBEDDED_SERVER=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_ARCHIVE=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_BLACKHOLE=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_CASSANDRA=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_CONNECT=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_CSV=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_EXAMPLE=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_FEDERATED=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_FEDERATEDX=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_HEAP=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_MYISAMMRG=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_OQGRAPH=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_SEQUENCE=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_SPHINX=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_SPIDER=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_TEST_SQL_DISCOVERY=TRUE) + cmake_args=("${cmake_args[@]}" -DWITHOUT_TOKUDB=TRUE) if [ "${MROONGA_TEST_EMBEDDED}" = "yes" ]; then - cmake_args=("${cmake_args[@]}" "-DWITH_EMBEDDED_SERVER=TRUE") + cmake_args=("${cmake_args[@]}" -DWITH_EMBEDDED_SERVER=TRUE) fi cmake . "${cmake_args[@]}" else @@ -31,6 +48,10 @@ else if [ -d /opt/mysql/ ]; then PATH=$(echo /opt/mysql/server-*/bin/):$PATH fi - ./configure \ - --with-mysql-source=$PWD/vendor/mysql + configure_args=("--with-mysql-source=$PWD/vendor/mysql") + if [ "${MYSQL_VERSION}" = "mysql-5.6.25" ]; then + configure_args=("${configure_args[@]}" --enable-fast-mutexes) + fi + ./configure "${configure_args[@]}" + cat "$(mysql_config --include | sed -e 's/-I//g')/my_config.h" fi diff --git a/storage/mroonga/tools/travis/script.sh b/storage/mroonga/tools/travis/script.sh index 6ea5c86068b..d8dd188f1f2 100755 --- a/storage/mroonga/tools/travis/script.sh +++ b/storage/mroonga/tools/travis/script.sh @@ -32,7 +32,11 @@ else fi n_processors="$(grep '^processor' /proc/cpuinfo | wc -l)" -max_n_processors=8 +if [ "${MROONGA_BUNDLED}" = "yes" ]; then + max_n_processors=2 +else + max_n_processors=4 +fi if (( $n_processors > $max_n_processors )); then n_processors=$max_n_processors fi @@ -98,6 +102,14 @@ run_sql_test() fi if [ "${MROONGA_BUNDLED}" = "yes" ]; then + # Plugins aren't supported. + cd ${mroonga_dir}/mysql-test/mroonga/storage + rm -rf alter_table/add_index/token_filters/ + rm -rf alter_table/t/change_token_filter.test + rm -rf create/table/token_filters/ + rm -rf fulltext/token_filters/ + cd - + ${mroonga_dir}/test/run-sql-test.sh \ "${test_args[@]}" \ --parallel="${n_processors}" diff --git a/storage/mroonga/vendor/groonga/CMakeLists.txt b/storage/mroonga/vendor/groonga/CMakeLists.txt index f1ca174ed50..ebe7f6b7fe5 100644 --- a/storage/mroonga/vendor/groonga/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/CMakeLists.txt @@ -168,7 +168,7 @@ macro(check_build_flag flag) check_cxxflag(${flag}) endmacro() -if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX) +if(CMAKE_COMPILER_IS_GNUCXX) check_build_flag("-Wall") check_build_flag("-Wextra") check_build_flag("-Wno-unused-but-set-variable") @@ -185,7 +185,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX) check_cflag("-Wdeclaration-after-statement") check_cflag("-Wbad-function-cast") check_build_flag("-Wcast-align") - check_build_flag("-Wredundant-decls") + # check_build_flag("-Wredundant-decls") check_build_flag("-Wwrite-strings") check_cxxflag("-fexceptions") check_cxxflag("-fimplicit-templates") @@ -201,7 +201,7 @@ endif() option(GRN_WITH_DEBUG "enable debug build." OFF) if(GRN_WITH_DEBUG) - if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX) + if(CMAKE_COMPILER_IS_GNUCXX) set(GRN_C_COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS} -g3 -O0") set(GRN_CXX_COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS} -g3 -O0") endif() @@ -210,6 +210,9 @@ endif() add_definitions( -DHAVE_CONFIG_H ) +if(GRN_EMBED) + add_definitions(-DGRN_EMBEDDED) +endif() if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX) set(_GNU_SOURCE TRUE) @@ -556,6 +559,9 @@ endif() add_definitions(-DONIG_EXTERN=extern) add_subdirectory(vendor) +if(GRN_EMBED) + add_subdirectory(plugins) +endif() add_subdirectory(lib) if(NOT GRN_EMBED) add_subdirectory(src) diff --git a/storage/mroonga/vendor/groonga/base_version b/storage/mroonga/vendor/groonga/base_version index 26611488b0a..25b08bbc78f 100644 --- a/storage/mroonga/vendor/groonga/base_version +++ b/storage/mroonga/vendor/groonga/base_version @@ -1 +1 @@ -5.0.3
\ No newline at end of file +5.0.5
\ No newline at end of file diff --git a/storage/mroonga/vendor/groonga/bindings/php/groonga.c b/storage/mroonga/vendor/groonga/bindings/php/groonga.c index b92cc1a2385..a04bb9cd42f 100644 --- a/storage/mroonga/vendor/groonga/bindings/php/groonga.c +++ b/storage/mroonga/vendor/groonga/bindings/php/groonga.c @@ -101,6 +101,9 @@ PHP_FUNCTION(grn_ctx_init) long flags = 0; grn_rc rc; + if (ctx == NULL) { + RETURN_FALSE; // unable to allocate memory for ctx + } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) { return; diff --git a/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 b/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 index 2a7e0f03acc..9a30ca8fc9c 100644 --- a/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 +++ b/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 @@ -5,14 +5,10 @@ AC_CHECK_HEADERS(dlfcn.h) AC_CHECK_HEADERS(errno.h) AC_CHECK_HEADERS(execinfo.h) AC_CHECK_HEADERS(inttypes.h) -AC_CHECK_HEADERS(io.h) AC_CHECK_HEADERS(netdb.h) -AC_CHECK_HEADERS(netinet/in.h) -AC_CHECK_HEADERS(netinet/tcp.h) AC_CHECK_HEADERS(signal.h) AC_CHECK_HEADERS(stdarg.h) AC_CHECK_HEADERS(stdint.h) -AC_CHECK_HEADERS(stdlib.h) AC_CHECK_HEADERS(string.h) AC_CHECK_HEADERS(strings.h) AC_CHECK_HEADERS(sys/mman.h) @@ -21,7 +17,6 @@ AC_CHECK_HEADERS(sys/resource.h) AC_CHECK_HEADERS(sys/socket.h) AC_CHECK_HEADERS(sys/sysctl.h) AC_CHECK_HEADERS(sys/time.h) -AC_CHECK_HEADERS(sys/types.h) AC_CHECK_HEADERS(sys/wait.h) AC_CHECK_HEADERS(time.h) AC_CHECK_HEADERS(ucontext.h) diff --git a/storage/mroonga/vendor/groonga/config.h.cmake b/storage/mroonga/vendor/groonga/config.h.cmake index cd8e4f6cc2d..8e3bdaf216b 100644 --- a/storage/mroonga/vendor/groonga/config.h.cmake +++ b/storage/mroonga/vendor/groonga/config.h.cmake @@ -14,7 +14,7 @@ #define PACKAGE_URL "${PACKAGE_URL}" #define PACKAGE_VERSION "${VERSION}" -/* groonga related constants */ +/* Groonga related constants */ #define GRN_CONFIG_PATH "${GRN_CONFIG_PATH}" #define GRN_LOG_PATH "${GRN_LOG_PATH}" #define GRN_VERSION "${GRN_VERSION}" @@ -98,17 +98,13 @@ #cmakedefine HAVE_ERRNO_H #cmakedefine HAVE_EXECINFO_H #cmakedefine HAVE_INTTYPES_H -#cmakedefine HAVE_IO_H #cmakedefine HAVE_LINUX_FUTEX_H #cmakedefine HAVE_MEMORY_H #cmakedefine HAVE_NETDB_H -#cmakedefine HAVE_NETINET_IN_H -#cmakedefine HAVE_NETINET_TCP_H #cmakedefine HAVE_PTHREAD_H #cmakedefine HAVE_SIGNAL_H #cmakedefine HAVE_STDARG_H #cmakedefine HAVE_STDINT_H -#cmakedefine HAVE_STDLIB_H #cmakedefine HAVE_STRINGS_H #cmakedefine HAVE_STRING_H #cmakedefine HAVE_SYS_MMAN_H @@ -120,7 +116,6 @@ #cmakedefine HAVE_SYS_SYSCALL_H #cmakedefine HAVE_SYS_SYSCTL_H #cmakedefine HAVE_SYS_TIME_H -#cmakedefine HAVE_SYS_TYPES_H #cmakedefine HAVE_SYS_WAIT_H #cmakedefine HAVE_TIME_H #cmakedefine HAVE_UCONTEXT_H diff --git a/storage/mroonga/vendor/groonga/configure.ac b/storage/mroonga/vendor/groonga/configure.ac index 17f3abcc2ed..dad29c78f4c 100644 --- a/storage/mroonga/vendor/groonga/configure.ac +++ b/storage/mroonga/vendor/groonga/configure.ac @@ -169,7 +169,7 @@ if test "$GCC" = "yes"; then if test "$CLANG" = "no"; then CHECK_BUILD_FLAG([-Wcast-align]) fi - CHECK_BUILD_FLAG([-Wredundant-decls]) +# CHECK_BUILD_FLAG([-Wredundant-decls]) # CHECK_BUILD_FLAG([-Wunsafe-loop-optimizations]) # CHECK_BUILD_FLAG([-Wunreachable-code]) # CHECK_BUILD_FLAG([-Wswitch-enum]) @@ -1508,6 +1508,8 @@ AM_CONDITIONAL(WITH_SHARED_ONIGMO, test "$enable_shared_onigmo" = "yes") # TODO: Support using system Onigmo instead of bundled Onigmo. AC_DEFINE(GRN_WITH_ONIGMO, [1], [Use Onigmo.]) +GRN_WITH_ONIGMO="yes" +AC_SUBST(GRN_WITH_ONIGMO) AC_CONFIG_SUBDIRS([vendor/onigmo]) ONIGMO_CFLAGS="-I\$(top_srcdir)/vendor/onigmo-source" diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb index 664b12c2148..b795e25a50b 100755 --- a/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb +++ b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb @@ -1,47 +1,23 @@ #!/usr/bin/env ruby -# -*- coding: utf-8 -*- -$KCODE = 'u' +require "English" +require "nkf" +require "json" -require 'English' -require 'kconv' - -class String - def to_json - a = split(//).map {|char| - case char - when '"' then '\\"' - when '\\' then '\\\\' - when "\b" then '\b' - when "\f" then '\f' - when "\n" then '\n' - when "\r" then '' - when "\t" then '\t' - else char - end - } - "\"#{a.join('')}\"" - end -end - -class Array - def to_json - '[' + map {|element| - element.to_json - }.join(',') + ']' - end -end - -puts <<END +print(<<HEADER.chomp) column_create item_dictionary edict_desc COLUMN_SCALAR ShortText column_create bigram item_dictionary_edict_desc COLUMN_INDEX|WITH_POSITION item_dictionary edict_desc load --table item_dictionary -[["_key","edict_desc","kana"], -END +[ +["_key","edict_desc","kana"] +HEADER + +loop do + raw_line = gets + break if raw_line.nil? -while !STDIN.eof? - line = Kconv.toutf8(gets) - key, body = line.strip.split('/', 2) + line = raw_line.encode("UTF-8", "EUC-JP") + key, body = line.strip.split("/", 2) key = key.strip if /\s*\[(.+)\]\z/ =~ key key = $PREMATCH @@ -51,6 +27,8 @@ while !STDIN.eof? else kana = NKF.nkf("-Ww --katakana", key) end - puts [key, body, kana].to_json + puts(",") + puts([key, body, kana].to_json) end -puts ']' +puts +puts("]") diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb index 0d10cfd1085..c9d9a593b11 100755 --- a/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb +++ b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb @@ -1,46 +1,33 @@ #!/usr/bin/env ruby -# -*- coding: utf-8 -*- -$KCODE = 'u' +require "json" -require 'kconv' - -class String - def to_json - a = split(//).map {|char| - case char - when '"' then '\\"' - when '\\' then '\\\\' - when "\b" then '\b' - when "\f" then '\f' - when "\n" then '\n' - when "\r" then '' - when "\t" then '\t' - else char - end - } - "\"#{a.join('')}\"" - end -end - -class Array - def to_json - '[' + map {|element| - element.to_json - }.join(',') + ']' - end -end - -puts <<END +print(<<HEADER.chomp) column_create item_dictionary gene95_desc COLUMN_SCALAR ShortText column_create bigram item_dictionary_gene95_desc COLUMN_INDEX|WITH_POSITION item_dictionary gene95_desc load --table item_dictionary -[["_key","gene95_desc"], -END +[ +["_key","gene95_desc"] +HEADER -while !STDIN.eof? - key = Kconv.toutf8(gets.strip) - body = Kconv.toutf8(gets.strip) - puts [key, body].to_json +loop do + raw_key = gets + break if raw_key.nil? + raw_body = gets + + key = nil + body = nil + begin + key = raw_key.encode("UTF-8", "Windows-31J").strip + body = raw_body.encode("UTF-8", "Windows-31J").strip + rescue EncodingError + $stderr.puts("Ignore:") + $stderr.puts(" key: <#{raw_key}>") + $stderr.puts(" body: <#{raw_body}>") + next + end + puts(",") + print([key, body].to_json) end -puts ']' +puts +puts("]") diff --git a/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in b/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in index 380495bb391..73b8867eafa 100644 --- a/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in +++ b/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in @@ -25,4 +25,6 @@ export GROONGA_HTTPD_DEBUG="@grn_debug@" export GROONGA_HTTPD_WITH_PCRE="@GRN_WITH_PCRE@" export GROONGA_HTTPD_PCRE_CFLAGS="@PCRE_CFLAGS@" export GROONGA_HTTPD_PCRE_LIBS_ONLY_L="@PCRE_LIBS_ONLY_L@" +export GROONGA_HTTPD_WITH_ONIGMO="@GRN_WITH_ONIGMO@" +export GROONGA_HTTPD_ONIGMO_IN_TREE_LINK_PATH="@abs_top_builddir@/vendor/onigmo-source/.libs" export GROONGA_HTTPD_WITH_ZLIB="@GRN_WITH_ZLIB@" diff --git a/storage/mroonga/vendor/groonga/include/groonga/command.h b/storage/mroonga/vendor/groonga/include/groonga/command.h index 101956a04f9..ac5270e9798 100644 --- a/storage/mroonga/vendor/groonga/include/groonga/command.h +++ b/storage/mroonga/vendor/groonga/include/groonga/command.h @@ -43,6 +43,8 @@ GRN_PLUGIN_EXPORT grn_obj *grn_command_input_get(grn_ctx *ctx, GRN_PLUGIN_EXPORT grn_obj *grn_command_input_at(grn_ctx *ctx, grn_command_input *input, unsigned int offset); +GRN_PLUGIN_EXPORT grn_obj *grn_command_input_get_arguments(grn_ctx *ctx, + grn_command_input *input); typedef void grn_command_run_func(grn_ctx *ctx, grn_obj *command, diff --git a/storage/mroonga/vendor/groonga/include/groonga/groonga.h b/storage/mroonga/vendor/groonga/include/groonga/groonga.h index 6f2aae79c01..14b21bda05c 100644 --- a/storage/mroonga/vendor/groonga/include/groonga/groonga.h +++ b/storage/mroonga/vendor/groonga/include/groonga/groonga.h @@ -907,6 +907,8 @@ GRN_API grn_rc grn_obj_lock(grn_ctx *ctx, grn_obj *obj, grn_id id, int timeout); GRN_API grn_rc grn_obj_unlock(grn_ctx *ctx, grn_obj *obj, grn_id id); GRN_API grn_rc grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj); GRN_API unsigned int grn_obj_is_locked(grn_ctx *ctx, grn_obj *obj); +GRN_API grn_rc grn_obj_flush(grn_ctx *ctx, grn_obj *obj); +GRN_API grn_rc grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj); GRN_API int grn_obj_defrag(grn_ctx *ctx, grn_obj *obj, int threshold); GRN_API grn_obj *grn_obj_db(grn_ctx *ctx, grn_obj *obj); diff --git a/storage/mroonga/vendor/groonga/include/groonga/plugin.h b/storage/mroonga/vendor/groonga/include/groonga/plugin.h index bbd8923e5d6..98ca6961407 100644 --- a/storage/mroonga/vendor/groonga/include/groonga/plugin.h +++ b/storage/mroonga/vendor/groonga/include/groonga/plugin.h @@ -55,6 +55,11 @@ GRN_PLUGIN_EXPORT grn_rc GRN_PLUGIN_INIT(grn_ctx *ctx); GRN_PLUGIN_EXPORT grn_rc GRN_PLUGIN_REGISTER(grn_ctx *ctx); GRN_PLUGIN_EXPORT grn_rc GRN_PLUGIN_FIN(grn_ctx *ctx); +#define GRN_PLUGIN_DECLARE_FUNCTIONS(tag) \ + extern grn_rc GRN_PLUGIN_IMPL_NAME_TAGGED(init, tag)(grn_ctx *ctx); \ + extern grn_rc GRN_PLUGIN_IMPL_NAME_TAGGED(register, tag)(grn_ctx *ctx); \ + extern grn_rc GRN_PLUGIN_IMPL_NAME_TAGGED(fin, tag)(grn_ctx *ctx) + /* Don't call these functions directly. Use GRN_PLUGIN_MALLOC(), GRN_PLUGIN_REALLOC() and GRN_PLUGIN_FREE() instead. diff --git a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt index 8959f883ca3..45b2c923635 100644 --- a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt @@ -36,7 +36,7 @@ string(REGEX REPLACE "([^;]+)" "mrb/\\1" set_source_files_properties(${LIBGROONGA_SOURCES} ${LIBGRNMRB_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") -set_source_files_properties(dat.cpp ${LIBGRNDAT_SOURCES} +set_source_files_properties(dat.cpp egn.cpp ${LIBGRNDAT_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS}") @@ -67,9 +67,14 @@ set(GRN_ALL_LIBRARIES ${MRUBY_LIBS} ${ONIGMO_LIBS}) if(GRN_EMBED) + set(GRN_EMBEDDED_PLUGIN_LIBRARIES "") + if(GRN_WITH_MECAB) + list(APPEND GRN_EMBEDDED_PLUGIN_LIBRARIES mecab_tokenizer) + endif() target_link_libraries(libgroonga ${GRN_ALL_LIBRARIES} - ${STDCPP_LIBS}) + ${STDCPP_LIBS} + ${GRN_EMBEDDED_PLUGIN_LIBRARIES}) else() target_link_libraries(libgroonga ${GRN_ALL_LIBRARIES}) diff --git a/storage/mroonga/vendor/groonga/lib/com.c b/storage/mroonga/vendor/groonga/lib/com.c index eb1cacfd4c1..a7450ec31f0 100644 --- a/storage/mroonga/vendor/groonga/lib/com.c +++ b/storage/mroonga/vendor/groonga/lib/com.c @@ -22,20 +22,17 @@ #include "grn_ctx_impl.h" #ifdef WIN32 -# include <ws2tcpip.h> +# include <ws2tcpip.h> #else -# ifdef HAVE_SYS_SOCKET_H -# include <sys/socket.h> -# endif /* HAVE_SYS_SOCKET_H */ -# ifdef HAVE_NETINET_IN_H -# include <netinet/in.h> -# endif /* HAVE_NETINET_IN_H */ -# ifdef HAVE_NETINET_TCP_H -# include <netinet/tcp.h> -# endif /* HAVE_NETINET_TCP_H */ -# ifdef HAVE_SIGNAL_H -# include <signal.h> -# endif /* HAVE_SIGNAL_H */ +# ifdef HAVE_SYS_SOCKET_H +# include <sys/socket.h> +# endif /* HAVE_SYS_SOCKET_H */ +# include <netinet/in.h> +# include <netinet/tcp.h> +# ifdef HAVE_SIGNAL_H +# include <signal.h> +# endif /* HAVE_SIGNAL_H */ +# include <sys/uio.h> #endif /* WIN32 */ #include "grn_ctx.h" @@ -736,13 +733,11 @@ grn_com_send(grn_ctx *ctx, grn_com *cs, #else /* WIN32 */ struct iovec msg_iov[2]; struct msghdr msg; + memset(&msg, 0, sizeof(struct msghdr)); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = msg_iov; msg.msg_iovlen = 2; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; msg_iov[0].iov_base = header; msg_iov[0].iov_len = sizeof(grn_com_header); msg_iov[1].iov_base = (char *)body; diff --git a/storage/mroonga/vendor/groonga/lib/command.c b/storage/mroonga/vendor/groonga/lib/command.c index e4be0d1ff92..282d15b6a0e 100644 --- a/storage/mroonga/vendor/groonga/lib/command.c +++ b/storage/mroonga/vendor/groonga/lib/command.c @@ -129,6 +129,14 @@ grn_command_input_at(grn_ctx *ctx, GRN_API_RETURN(argument); } +grn_obj * +grn_command_input_get_arguments(grn_ctx *ctx, + grn_command_input *input) +{ + GRN_API_ENTER; + GRN_API_RETURN((grn_obj *)(input->arguments)); +} + grn_rc grn_command_register(grn_ctx *ctx, const char *command_name, diff --git a/storage/mroonga/vendor/groonga/lib/ctx.c b/storage/mroonga/vendor/groonga/lib/ctx.c index 85878036dc2..92caba561eb 100644 --- a/storage/mroonga/vendor/groonga/lib/ctx.c +++ b/storage/mroonga/vendor/groonga/lib/ctx.c @@ -21,22 +21,24 @@ #include "grn_request_canceler.h" #include "grn_tokenizers.h" #include "grn_ctx_impl.h" +#include "grn_ii.h" #include "grn_pat.h" +#include "grn_proc.h" #include "grn_plugin.h" #include "grn_snip.h" #include "grn_output.h" #include "grn_normalizer.h" +#include "grn_mrb.h" #include "grn_ctx_impl_mrb.h" #include "grn_logger.h" #include <stdio.h> #include <stdarg.h> #include <time.h> -#ifdef HAVE_NETINET_IN_H -# include <netinet/in.h> -#endif /* HAVE_NETINET_IN_H */ #ifdef WIN32 # include <share.h> +#else /* WIN32 */ +# include <netinet/in.h> #endif /* WIN32 */ #if defined(HAVE__LOCALTIME64_S) && defined(__GNUC__) @@ -74,6 +76,30 @@ int grn_lock_timeout = GRN_LOCK_TIMEOUT; int grn_uyield_count = 0; #endif +static grn_bool grn_ctx_per_db = GRN_FALSE; + +static void +grn_init_from_env(void) +{ + { + char grn_ctx_per_db_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_CTX_PER_DB", + grn_ctx_per_db_env, + GRN_ENV_BUFFER_SIZE); + if (grn_ctx_per_db_env[0] && strcmp(grn_ctx_per_db_env, "yes") == 0) { + grn_ctx_per_db = GRN_TRUE; + } + } + + grn_mrb_init_from_env(); + grn_ctx_impl_mrb_init_from_env(); + grn_io_init_from_env(); + grn_ii_init_from_env(); + grn_db_init_from_env(); + grn_proc_init_from_env(); + grn_plugin_init_from_env(); +} + void grn_sleep(uint32_t seconds) { @@ -621,14 +647,8 @@ grn_ctx_init_internal(grn_ctx *ctx, int flags) // if (ctx->stat != GRN_CTX_FIN) { return GRN_INVALID_ARGUMENT; } ERRCLR(ctx); ctx->flags = flags; - { - char grn_ctx_per_db_env[GRN_ENV_BUFFER_SIZE]; - grn_getenv("GRN_CTX_PER_DB", - grn_ctx_per_db_env, - GRN_ENV_BUFFER_SIZE); - if (grn_ctx_per_db_env[0] && strcmp(grn_ctx_per_db_env, "yes") == 0) { - ctx->flags |= GRN_CTX_PER_DB; - } + if (grn_ctx_per_db) { + ctx->flags |= GRN_CTX_PER_DB; } if (ERRP(ctx, GRN_ERROR)) { return ctx->rc; } ctx->stat = GRN_CTX_INITED; @@ -821,6 +841,7 @@ grn_init(void) { grn_rc rc; grn_ctx *ctx = &grn_gctx; + grn_init_from_env(); grn_logger_init(); grn_query_logger_init(); CRITICAL_SECTION_INIT(grn_glock); @@ -898,12 +919,8 @@ grn_init(void) return rc; } grn_ctx_impl_init(ctx); - if ((rc = grn_io_init())) { - GRN_LOG(ctx, GRN_LOG_ALERT, "io initialize failed (%d)", rc); - return rc; - } if ((rc = grn_plugins_init())) { - GRN_LOG(ctx, GRN_LOG_ALERT, "plugins initialize failed (%d)", rc); + GRN_LOG(ctx, GRN_LOG_ALERT, "grn_plugins_init failed (%d)", rc); return rc; } if ((rc = grn_normalizer_init())) { @@ -1018,7 +1035,6 @@ grn_fin(void) grn_tokenizers_fin(); grn_normalizer_fin(); grn_plugins_fin(); - grn_io_fin(); grn_ctx_fin(ctx); grn_com_fin(); GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_fin (%d)", alloc_count); @@ -1535,7 +1551,6 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags) goto exit; } else { grn_obj *expr = NULL; - if (comment_command_p(str, str_len)) { goto output; }; if (ctx->impl->qe_next) { grn_obj *val; expr = ctx->impl->qe_next; @@ -1546,6 +1561,7 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags) } grn_expr_exec(ctx, expr, 0); } else { + if (comment_command_p(str, str_len)) { goto output; }; ctx->impl->mime_type = "application/json"; ctx->impl->output_type = GRN_CONTENT_JSON; grn_timeval_now(ctx, &ctx->impl->tv); @@ -2382,9 +2398,8 @@ grn_calloc_default(grn_ctx *ctx, size_t size, const char* file, int line, const grn_alloc_info_add(res, file, line, func); } else { if (!(res = calloc(size, 1))) { - MERR("calloc fail (%" GRN_FMT_LLU ")=%p (%s:%d) <%" GRN_FMT_LLU ">", - (unsigned long long int)size, res, file, line, - (unsigned long long int)alloc_count); + MERR("calloc fail (%" GRN_FMT_SIZE ")=%p (%s:%d) <%d>", + size, res, file, line, alloc_count); } else { GRN_ADD_ALLOC_COUNT(1); grn_alloc_info_add(res, file, line, func); diff --git a/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c index 4c1a2a3b4f9..39a1aa17b86 100644 --- a/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c +++ b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c @@ -18,9 +18,9 @@ #include "grn_ctx_impl.h" -#ifdef GRN_WITH_MRUBY -# include <string.h> +#include <string.h> +#ifdef GRN_WITH_MRUBY # include "grn_ctx_impl_mrb.h" # include "grn_mrb.h" @@ -40,6 +40,10 @@ # include "mrb/mrb_hash_table.h" # include "mrb/mrb_patricia_trie.h" # include "mrb/mrb_double_array_trie.h" +# include "mrb/mrb_table_group_flags.h" +# include "mrb/mrb_table_group_result.h" +# include "mrb/mrb_table_sort_flags.h" +# include "mrb/mrb_table_sort_key.h" # include "mrb/mrb_column.h" # include "mrb/mrb_fixed_size_column.h" # include "mrb/mrb_variable_size_column.h" @@ -60,6 +64,23 @@ # include <mruby/variable.h> #endif /* GRN_WITH_MRUBY */ +static grn_bool grn_ctx_impl_mrb_mruby_enabled = GRN_TRUE; + +void +grn_ctx_impl_mrb_init_from_env(void) +{ + { + char grn_mruby_enabled_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_MRUBY_ENABLED", + grn_mruby_enabled_env, + GRN_ENV_BUFFER_SIZE); + if (grn_mruby_enabled_env[0] && + strcmp(grn_mruby_enabled_env, "no") == 0) { + grn_ctx_impl_mrb_mruby_enabled = GRN_FALSE; + } + } +} + #ifdef GRN_WITH_MRUBY static mrb_value mrb_kernel_load(mrb_state *mrb, mrb_value self) @@ -125,6 +146,10 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx) grn_mrb_hash_table_init(ctx); grn_mrb_patricia_trie_init(ctx); grn_mrb_double_array_trie_init(ctx); + grn_mrb_table_group_flags_init(ctx); + grn_mrb_table_group_result_init(ctx); + grn_mrb_table_sort_flags_init(ctx); + grn_mrb_table_sort_key_init(ctx); grn_mrb_column_init(ctx); grn_mrb_fixed_size_column_init(ctx); grn_mrb_variable_size_column_init(ctx); @@ -147,11 +172,7 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx) void grn_ctx_impl_mrb_init(grn_ctx *ctx) { - char grn_mruby_enabled[GRN_ENV_BUFFER_SIZE]; - grn_getenv("GRN_MRUBY_ENABLED", - grn_mruby_enabled, - GRN_ENV_BUFFER_SIZE); - if (grn_mruby_enabled[0] && strcmp(grn_mruby_enabled, "no") == 0) { + if (!grn_ctx_impl_mrb_mruby_enabled) { ctx->impl->mrb.state = NULL; ctx->impl->mrb.base_directory[0] = '\0'; ctx->impl->mrb.module = NULL; @@ -162,7 +183,6 @@ grn_ctx_impl_mrb_init(grn_ctx *ctx) ctx->impl->mrb.groonga.operator_class = NULL; } else { mrb_state *mrb; - mrb = mrb_open(); ctx->impl->mrb.state = mrb; ctx->impl->mrb.base_directory[0] = '\0'; diff --git a/storage/mroonga/vendor/groonga/lib/dat.cpp b/storage/mroonga/vendor/groonga/lib/dat.cpp index 60588d55710..51a84da2af9 100644 --- a/storage/mroonga/vendor/groonga/lib/dat.cpp +++ b/storage/mroonga/vendor/groonga/lib/dat.cpp @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2011-2014 Brazil +/* Copyright(C) 2011-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -1112,4 +1112,34 @@ grn_dat_repair(grn_ctx *ctx, grn_dat *dat) return GRN_SUCCESS; } +grn_rc +grn_dat_flush(grn_ctx *ctx, grn_dat *dat) +{ + if (!dat->io) { + return GRN_SUCCESS; + } + + grn_rc rc = grn_io_flush(ctx, dat->io); + if (rc != GRN_SUCCESS) { + return rc; + } + + if (dat->trie) { + grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie); + try { + trie->flush(); + } catch (const grn::dat::Exception &ex) { + const grn_rc error_code = grn_dat_translate_error_code(ex.code()); + if (error_code == GRN_INPUT_OUTPUT_ERROR) { + SERR("grn::dat::Trie::flush failed"); + } else { + ERR(error_code, "grn::dat::Trie::flush failed"); + } + return error_code; + } + } + + return GRN_SUCCESS; +} + } // extern "C" diff --git a/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp b/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp index 3643a806292..7a9879aa369 100644 --- a/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp +++ b/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2011 Brazil +/* Copyright(C) 2011-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -123,6 +123,15 @@ void FileImpl::swap(FileImpl *rhs) { std::swap(addr_, rhs->addr_); } +void FileImpl::flush() { + if (!addr_) { + return; + } + + BOOL succeeded = ::FlushViewOfFile(addr_, size_); + GRN_DAT_THROW_IF(IO_ERROR, !succeeded); +} + void FileImpl::create_(const char *path, UInt64 size) { if ((path != NULL) && (path[0] != '\0')) { file_ = ::CreateFileA(path, GRN_IO_FILE_CREATE_MODE, @@ -193,6 +202,15 @@ void FileImpl::swap(FileImpl *rhs) { std::swap(length_, rhs->length_); } +void FileImpl::flush() { + if (!addr_) { + return; + } + + int result = ::msync(addr_, length_, MS_SYNC); + GRN_DAT_THROW_IF(IO_ERROR, result != 0); +} + void FileImpl::create_(const char *path, UInt64 size) { GRN_DAT_THROW_IF(PARAM_ERROR, size > static_cast<UInt64>(std::numeric_limits< ::off_t>::max())); diff --git a/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp b/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp index f4e0543635a..245dbfc2ae7 100644 --- a/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp +++ b/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2011-2012 Brazil +/* Copyright(C) 2011-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -45,6 +45,8 @@ class FileImpl { void swap(FileImpl *rhs); + void flush(); + private: void *ptr_; UInt64 size_; diff --git a/storage/mroonga/vendor/groonga/lib/dat/file.cpp b/storage/mroonga/vendor/groonga/lib/dat/file.cpp index 57bfcb9ece6..82d6159ed09 100644 --- a/storage/mroonga/vendor/groonga/lib/dat/file.cpp +++ b/storage/mroonga/vendor/groonga/lib/dat/file.cpp @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2011 Brazil +/* Copyright(C) 2011-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -63,5 +63,11 @@ void File::swap(File *rhs) { rhs->impl_ = temp; } +void File::flush() { + if (impl_) { + impl_->flush(); + } +} + } // namespace dat } // namespace grn diff --git a/storage/mroonga/vendor/groonga/lib/dat/file.hpp b/storage/mroonga/vendor/groonga/lib/dat/file.hpp index c2be8d86da3..e7dda0e025e 100644 --- a/storage/mroonga/vendor/groonga/lib/dat/file.hpp +++ b/storage/mroonga/vendor/groonga/lib/dat/file.hpp @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2011 Brazil +/* Copyright(C) 2011-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -46,6 +46,8 @@ class GRN_DAT_API File { void swap(File *rhs); + void flush(); + private: FileImpl *impl_; diff --git a/storage/mroonga/vendor/groonga/lib/dat/trie.cpp b/storage/mroonga/vendor/groonga/lib/dat/trie.cpp index 82c8c273286..2f9e79bac56 100644 --- a/storage/mroonga/vendor/groonga/lib/dat/trie.cpp +++ b/storage/mroonga/vendor/groonga/lib/dat/trie.cpp @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2011 Brazil +/* Copyright(C) 2011-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -168,6 +168,10 @@ void Trie::swap(Trie *trie) { key_buf_.swap(&trie->key_buf_); } +void Trie::flush() { + file_.flush(); +} + void Trie::create_file(const char *file_name, UInt64 file_size, UInt32 max_num_keys, diff --git a/storage/mroonga/vendor/groonga/lib/dat/trie.hpp b/storage/mroonga/vendor/groonga/lib/dat/trie.hpp index 6bd307bb70e..8a272bb7940 100644 --- a/storage/mroonga/vendor/groonga/lib/dat/trie.hpp +++ b/storage/mroonga/vendor/groonga/lib/dat/trie.hpp @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2011 Brazil +/* Copyright(C) 2011-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -189,6 +189,8 @@ class GRN_DAT_API Trie { header_->set_status_flags(status_flags() & ~CHANGING_MASK); } + void flush(); + private: File file_; Header *header_; diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c index 357df82e314..e213812d926 100644 --- a/storage/mroonga/vendor/groonga/lib/db.c +++ b/storage/mroonga/vendor/groonga/lib/db.c @@ -85,6 +85,33 @@ inline static void grn_obj_get_range_info(grn_ctx *ctx, grn_obj *obj, grn_id *range_id, grn_obj_flags *range_flags); + +static char grn_db_key[GRN_ENV_BUFFER_SIZE]; +static uint64_t grn_index_sparsity = 10; + +void +grn_db_init_from_env(void) +{ + grn_getenv("GRN_DB_KEY", + grn_db_key, + GRN_ENV_BUFFER_SIZE); + + { + char grn_index_sparsity_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_INDEX_SPARSITY", + grn_index_sparsity_env, + GRN_ENV_BUFFER_SIZE); + if (grn_index_sparsity_env[0]) { + uint64_t sparsity; + errno = 0; + sparsity = strtoull(grn_index_sparsity_env, NULL, 0); + if (errno == 0) { + grn_index_sparsity = sparsity; + } + } + } +} + inline static void gen_pathname(const char *path, char *buffer, int fno) { @@ -155,15 +182,11 @@ grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg) if ((s = GRN_MALLOC(sizeof(grn_db)))) { grn_bool use_default_db_key = GRN_TRUE; grn_bool use_pat_as_db_keys = GRN_FALSE; - char grn_db_key_env[GRN_ENV_BUFFER_SIZE]; - grn_getenv("GRN_DB_KEY", - grn_db_key_env, - GRN_ENV_BUFFER_SIZE); - if (grn_db_key_env[0]) { - if (!strcmp(grn_db_key_env, "pat")) { + if (grn_db_key[0]) { + if (!strcmp(grn_db_key, "pat")) { use_default_db_key = GRN_FALSE; use_pat_as_db_keys = GRN_TRUE; - } else if (!strcmp(grn_db_key_env, "dat")) { + } else if (!strcmp(grn_db_key, "dat")) { use_default_db_key = GRN_FALSE; } } @@ -245,6 +268,10 @@ grn_db_open(grn_ctx *ctx, const char *path) break; default : s->keys = NULL; + if (ctx->rc == GRN_SUCCESS) { + ERR(GRN_INVALID_ARGUMENT, + "[db][open] invalid keys table's type: %#x", type); + } break; } if (s->keys) { @@ -870,6 +897,7 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name, path = buffer; } else { ERR(GRN_INVALID_ARGUMENT, "path not assigned for persistent table"); + grn_obj_delete_by_id(ctx, db, id, GRN_TRUE); return NULL; } } else { @@ -878,10 +906,12 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name, } else { if (path) { ERR(GRN_INVALID_ARGUMENT, "path assigned for temporary table"); + grn_obj_delete_by_id(ctx, db, id, GRN_TRUE); return NULL; } if (GRN_DB_PERSISTENT_P(db) && name && name_size) { ERR(GRN_INVALID_ARGUMENT, "name assigned for temporary table"); + grn_obj_delete_by_id(ctx, db, id, GRN_TRUE); return NULL; } } @@ -2758,6 +2788,181 @@ grn_table_next(grn_ctx *ctx, grn_obj *table, grn_id id) GRN_API_RETURN(r); } +static grn_rc +grn_accessor_resolve_one_index_column(grn_ctx *ctx, grn_accessor *accessor, + grn_obj *current_res, grn_obj **next_res, + grn_search_optarg *optarg) +{ + grn_rc rc = GRN_SUCCESS; + grn_obj *column = NULL; + grn_id next_res_domain_id = GRN_ID_NIL; + + { + grn_obj *index; + grn_obj source_ids; + unsigned int i, n_ids; + + index = accessor->obj; + next_res_domain_id = index->header.domain; + + GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR); + grn_obj_get_info(ctx, index, GRN_INFO_SOURCE, &source_ids); + n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id); + for (i = 0; i < n_ids; i++) { + grn_id source_id; + grn_obj *source; + + source_id = GRN_UINT32_VALUE_AT(&source_ids, i); + source = grn_ctx_at(ctx, source_id); + if (DB_OBJ(source)->range == next_res_domain_id) { + column = source; + break; + } + grn_obj_unlink(ctx, source); + } + + if (!column) { + return GRN_INVALID_ARGUMENT; + } + } + + { + grn_rc rc; + grn_obj *next_res_domain = grn_ctx_at(ctx, next_res_domain_id); + *next_res = grn_table_create(ctx, NULL, 0, NULL, + GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, + next_res_domain, NULL); + rc = ctx->rc; + grn_obj_unlink(ctx, next_res_domain); + if (!*next_res) { + return rc; + } + } + + { + grn_obj_flags column_value_flags = 0; + grn_obj column_value; + grn_ii_posting add_posting; + grn_id *tid; + grn_rset_recinfo *recinfo; + + if (column->header.type == GRN_COLUMN_VAR_SIZE) { + column_value_flags |= GRN_OBJ_VECTOR; + } + GRN_VALUE_FIX_SIZE_INIT(&column_value, + column_value_flags, + next_res_domain_id); + + add_posting.sid = 0; + add_posting.pos = 0; + add_posting.weight = 0; + + GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, { + int i; + int n_elements; + + add_posting.weight = recinfo->score - 1; + + GRN_BULK_REWIND(&column_value); + grn_obj_get_value(ctx, column, *tid, &column_value); + + n_elements = GRN_BULK_VSIZE(&column_value) / sizeof(grn_id); + for (i = 0; i < n_elements; i++) { + add_posting.rid = GRN_RECORD_VALUE_AT(&column_value, i); + rc = grn_ii_posting_add(ctx, + &add_posting, + (grn_hash *)*next_res, + GRN_OP_OR); + if (rc != GRN_SUCCESS) { + break; + } + } + if (rc != GRN_SUCCESS) { + break; + } + }); + + GRN_OBJ_FIN(ctx, &column_value); + } + + if (rc != GRN_SUCCESS) { + grn_obj_unlink(ctx, *next_res); + } + + return rc; +} + +static grn_rc +grn_accessor_resolve_one_data_column(grn_ctx *ctx, grn_accessor *accessor, + grn_obj *current_res, grn_obj **next_res, + grn_search_optarg *optarg) +{ + grn_rc rc = GRN_SUCCESS; + grn_obj *index = NULL; + grn_operator index_op = GRN_OP_MATCH; + grn_id next_res_domain_id = GRN_ID_NIL; + + if (grn_column_index(ctx, accessor->obj, index_op, &index, 1, NULL) == 0) { + return GRN_INVALID_ARGUMENT; + } + next_res_domain_id = DB_OBJ(index)->range; + + { + grn_rc rc; + grn_obj *next_res_domain = grn_ctx_at(ctx, next_res_domain_id); + *next_res = grn_table_create(ctx, NULL, 0, NULL, + GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, + next_res_domain, NULL); + rc = ctx->rc; + grn_obj_unlink(ctx, next_res_domain); + if (!*next_res) { + return rc; + } + } + + { + grn_id *tid; + grn_rset_recinfo *recinfo; + + GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, { + grn_ii *ii = (grn_ii *)index; + grn_ii_cursor *ii_cursor; + grn_ii_posting *posting; + + ii_cursor = grn_ii_cursor_open(ctx, ii, *tid, + GRN_ID_NIL, GRN_ID_MAX, + ii->n_elements, + 0); + if (!ii_cursor) { + continue; + } + + while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) { + grn_ii_posting add_posting = *posting; + add_posting.weight += recinfo->score - 1; + rc = grn_ii_posting_add(ctx, + &add_posting, + (grn_hash *)*next_res, + GRN_OP_OR); + if (rc != GRN_SUCCESS) { + break; + } + } + grn_ii_cursor_close(ctx, ii_cursor); + + if (rc != GRN_SUCCESS) { + break; + } + }); + } + + if (rc != GRN_SUCCESS) { + grn_obj_unlink(ctx, *next_res); + } + + return rc; +} + grn_rc grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep, grn_obj *base_res, grn_obj **res, @@ -2780,69 +2985,28 @@ grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep, } for (i = n_accessors; i > 0; i--) { - grn_obj *index; - grn_operator index_op = GRN_OP_MATCH; + grn_obj *next_res = NULL; a = (grn_accessor *)GRN_PTR_VALUE_AT(&accessor_stack, i - 1); - if (grn_column_index(ctx, a->obj, index_op, &index, 1, NULL) == 0) { - rc = GRN_INVALID_ARGUMENT; - break; + if (a->obj->header.type == GRN_COLUMN_INDEX) { + rc = grn_accessor_resolve_one_index_column(ctx, a, + current_res, &next_res, + optarg); + } else { + rc = grn_accessor_resolve_one_data_column(ctx, a, + current_res, &next_res, + optarg); } - { - grn_id *tid; - grn_obj *next_res; - grn_rset_recinfo *recinfo; - { - grn_obj *range = grn_ctx_at(ctx, DB_OBJ(index)->range); - next_res = grn_table_create(ctx, NULL, 0, NULL, - GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, - range, NULL); - rc = ctx->rc; - grn_obj_unlink(ctx, range); - if (!next_res) { - if (current_res != base_res) { - grn_obj_unlink(ctx, current_res); - } - break; - } - } - GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, { - grn_ii *ii = (grn_ii *)index; - grn_ii_cursor *ii_cursor; - grn_ii_posting *posting; - - ii_cursor = grn_ii_cursor_open(ctx, ii, *tid, - GRN_ID_NIL, GRN_ID_MAX, - ii->n_elements, - 0); - if (!ii_cursor) { - continue; - } - - while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) { - grn_ii_posting add_posting = *posting; - add_posting.weight += recinfo->score - 1; - grn_ii_posting_add(ctx, - &add_posting, - (grn_hash *)next_res, - GRN_OP_OR); - } - grn_ii_cursor_close(ctx, ii_cursor); + if (current_res != base_res) { + grn_obj_unlink(ctx, current_res); + } - if (rc != GRN_SUCCESS) { - break; - } - }); - if (current_res != base_res) { - grn_obj_unlink(ctx, current_res); - } - if (rc != GRN_SUCCESS) { - grn_obj_unlink(ctx, next_res); - break; - } - current_res = next_res; + if (rc != GRN_SUCCESS) { + break; } + + current_res = next_res; } if (rc == GRN_SUCCESS && current_res != base_res) { @@ -6846,7 +7010,7 @@ grn_obj_get_value(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value) } switch (value->header.type) { case GRN_VOID : - GRN_TEXT_INIT(value, 0); + grn_obj_reinit(ctx, value, GRN_DB_TEXT, 0); break; case GRN_BULK : case GRN_VECTOR : @@ -7225,18 +7389,7 @@ build_index(grn_ctx *ctx, grn_obj *obj) } } if (use_grn_ii_build) { - uint64_t sparsity = 10; - char grn_index_sparsity_env[GRN_ENV_BUFFER_SIZE]; - grn_getenv("GRN_INDEX_SPARSITY", - grn_index_sparsity_env, - GRN_ENV_BUFFER_SIZE); - if (grn_index_sparsity_env[0]) { - uint64_t v; - errno = 0; - v = strtoull(grn_index_sparsity_env, NULL, 0); - if (!errno) { sparsity = v; } - } - grn_ii_build(ctx, ii, sparsity); + grn_ii_build(ctx, ii, grn_index_sparsity); } else { grn_table_cursor *tc; if ((tc = grn_table_cursor_open(ctx, target, NULL, 0, NULL, 0, @@ -9528,6 +9681,7 @@ grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj) case GRN_TABLE_DAT_KEY: case GRN_TABLE_NO_KEY: grn_obj_clear_lock(ctx, tbl); + break; } } else { if (ctx->rc != GRN_SUCCESS) { @@ -9580,6 +9734,132 @@ grn_obj_is_locked(grn_ctx *ctx, grn_obj *obj) GRN_API_RETURN(res); } +grn_rc +grn_obj_flush(grn_ctx *ctx, grn_obj *obj) +{ + grn_rc rc = GRN_SUCCESS; + GRN_API_ENTER; + switch (obj->header.type) { + case GRN_DB : + { + grn_db *db = (grn_db *)obj; + rc = grn_obj_flush(ctx, db->keys); + if (rc == GRN_SUCCESS) { + rc = grn_obj_flush(ctx, (grn_obj *)(db->specs)); + } + } + break; + case GRN_TABLE_DAT_KEY : + rc = grn_dat_flush(ctx, (grn_dat *)obj); + break; + case GRN_COLUMN_INDEX : + rc = grn_ii_flush(ctx, (grn_ii *)obj); + break; + default : + rc = grn_io_flush(ctx, grn_obj_io(obj)); + break; + } + GRN_API_RETURN(rc); +} + +grn_rc +grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj) +{ + grn_rc rc = GRN_SUCCESS; + + GRN_API_ENTER; + switch (obj->header.type) { + case GRN_DB : + { + grn_table_cursor *cursor; + grn_id id; + + cursor = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, 0, -1, 0); + if (!cursor) { + GRN_API_RETURN(ctx->rc); + } + + while ((id = grn_table_cursor_next_inline(ctx, cursor)) != GRN_ID_NIL) { + grn_obj *table = grn_ctx_at(ctx, id); + rc = GRN_SUCCESS; + if (table) { + switch (table->header.type) { + case GRN_TABLE_HASH_KEY : + case GRN_TABLE_PAT_KEY: + case GRN_TABLE_DAT_KEY: + case GRN_TABLE_NO_KEY: + rc = grn_obj_flush_recursive(ctx, table); + break; + } + } else { + if (ctx->rc != GRN_SUCCESS) { + ERRCLR(ctx); + } + } + if (rc != GRN_SUCCESS) { + break; + } + } + grn_table_cursor_close(ctx, cursor); + } + if (rc == GRN_SUCCESS) { + rc = grn_obj_flush(ctx, obj); + } + break; + case GRN_TABLE_NO_KEY : + case GRN_TABLE_HASH_KEY : + case GRN_TABLE_PAT_KEY : + case GRN_TABLE_DAT_KEY : + { + grn_hash *columns; + columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, + GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY); + if (!columns) { + GRN_API_RETURN(ctx->rc); + } + + if (grn_table_columns(ctx, obj, "", 0, (grn_obj *)columns) > 0) { + grn_id *key; + GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, { + grn_obj *column = grn_ctx_at(ctx, *key); + if (column) { + rc = grn_obj_flush(ctx, column); + if (rc != GRN_SUCCESS) { + break; + } + } + }); + } + grn_hash_close(ctx, columns); + } + + if (rc == GRN_SUCCESS) { + rc = grn_obj_flush(ctx, obj); + } + break; + case GRN_COLUMN_FIX_SIZE : + case GRN_COLUMN_VAR_SIZE : + case GRN_COLUMN_INDEX : + rc = grn_obj_flush(ctx, obj); + break; + default : + { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, obj); + ERR(GRN_INVALID_ARGUMENT, + "[flush] object must be DB, table or column: <%.*s>", + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + rc = ctx->rc; + GRN_OBJ_FIN(ctx, &inspected); + } + break; + } + + GRN_API_RETURN(rc); +} + grn_obj * grn_obj_db(grn_ctx *ctx, grn_obj *obj) { @@ -11181,6 +11461,11 @@ grn_table_sort_key_from_str(grn_ctx *ctx, const char *str, unsigned int str_size const char *p = str; const char **tokbuf; grn_table_sort_key *keys = NULL, *k = NULL; + + if (str_size == 0) { + return NULL; + } + if ((keys = grn_table_sort_key_from_str_geo(ctx, str, str_size, table, nkeys))) { return keys; } diff --git a/storage/mroonga/vendor/groonga/lib/egn.cpp b/storage/mroonga/vendor/groonga/lib/egn.cpp new file mode 100644 index 00000000000..c7e7357fffb --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/egn.cpp @@ -0,0 +1,3245 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef GRN_WITH_EGN + +#include "grn_egn.hpp" + +#include <cctype> +#include <cstdio> +#include <limits> +#include <memory> +#include <string> + +#include <iostream> // for debug! + +#include "grn_ctx_impl.h" +#include "grn_db.h" +#include "grn_output.h" +#include "grn_str.h" + +// TODO: Error handling. + +namespace { + +enum { GRN_EGN_MAX_BATCH_SIZE = 1024 }; + +bool grn_egn_is_table_cursor(grn_obj *obj) { + if (!obj) { + return false; + } + switch (obj->header.type) { + case GRN_CURSOR_TABLE_PAT_KEY: + case GRN_CURSOR_TABLE_DAT_KEY: + case GRN_CURSOR_TABLE_HASH_KEY: + case GRN_CURSOR_TABLE_NO_KEY: { + return true; + } + default: { + return false; + } + } +} + +bool grn_egn_is_table(grn_obj *obj) { + if (!obj) { + return false; + } + switch (obj->header.type) { + case GRN_TABLE_HASH_KEY: + case GRN_TABLE_PAT_KEY: + case GRN_TABLE_DAT_KEY: + case GRN_TABLE_NO_KEY: { + return true; + } + default: { + return false; + } + } +} + +} // namespace + +namespace grn { +namespace egn { + +// -- TableCursor -- + +// TableCursor is a wrapper for grn_table_cursor: +// - GRN_CURSOR_PAT_KEY +// - GRN_CURSOR_DAT_KEY +// - GRN_CURSOR_HASH_KEY +// - GRN_CURSOR_NO_KEY +class TableCursor : public Cursor { + public: + ~TableCursor() { + grn_table_cursor_close(ctx_, cursor_); + } + + static grn_rc open(grn_ctx *ctx, grn_obj *cursor, Score default_score, + Cursor **wrapper) { + if (!ctx || !grn_egn_is_table_cursor(cursor) || !wrapper) { + return GRN_INVALID_ARGUMENT; + } + TableCursor *new_wrapper = + new (std::nothrow) TableCursor(ctx, cursor, default_score); + if (!new_wrapper) { + return GRN_NO_MEMORY_AVAILABLE; + } + *wrapper = new_wrapper; + return GRN_SUCCESS; + } + + grn_rc read(Record *records, size_t size, size_t *count); + + private: + grn_ctx *ctx_; + grn_obj *cursor_; + Score default_score_; + + TableCursor(grn_ctx *ctx, grn_obj *cursor, Score default_score) + : Cursor(), ctx_(ctx), cursor_(cursor), default_score_(default_score) {} +}; + +grn_rc TableCursor::read(Record *records, size_t size, size_t *count) { + if ((!records && (size != 0)) || !count) { + return GRN_INVALID_ARGUMENT; + } + switch (cursor_->header.type) { + case GRN_CURSOR_TABLE_PAT_KEY: { + for (size_t i = 0; i < size; ++i) { + grn_id id = grn_pat_cursor_next( + ctx_, reinterpret_cast<grn_pat_cursor *>(cursor_)); + if (id == GRN_ID_NIL) { + *count = i; + return GRN_SUCCESS; + } + records[i].id = id; + records[i].score = default_score_; + } + break; + } + case GRN_CURSOR_TABLE_DAT_KEY: { + for (size_t i = 0; i < size; ++i) { + grn_id id = grn_dat_cursor_next( + ctx_, reinterpret_cast<grn_dat_cursor *>(cursor_)); + if (id == GRN_ID_NIL) { + *count = i; + return GRN_SUCCESS; + } + records[i].id = id; + records[i].score = default_score_; + } + break; + } + case GRN_CURSOR_TABLE_HASH_KEY: { + for (size_t i = 0; i < size; ++i) { + grn_id id = grn_hash_cursor_next( + ctx_, reinterpret_cast<grn_hash_cursor *>(cursor_)); + if (id == GRN_ID_NIL) { + *count = i; + return GRN_SUCCESS; + } + records[i].id = id; + records[i].score = default_score_; + } + break; + } + case GRN_CURSOR_TABLE_NO_KEY: { + for (size_t i = 0; i < size; ++i) { + grn_id id = grn_array_cursor_next( + ctx_, reinterpret_cast<grn_array_cursor *>(cursor_)); + if (id == GRN_ID_NIL) { + *count = i; + return GRN_SUCCESS; + } + records[i].id = id; + records[i].score = default_score_; + } + break; + } + default: { + return GRN_UNKNOWN_ERROR; + } + } + *count = size; + return GRN_SUCCESS; +} + +// -- Cursor -- + +grn_rc Cursor::open_table_cursor( + grn_ctx *ctx, grn_obj *table, Cursor **cursor) { + if (!ctx || !grn_egn_is_table(table) || !cursor) { + return GRN_INVALID_ARGUMENT; + } + grn_table_cursor *table_cursor = grn_table_cursor_open( + ctx, table, NULL, 0, NULL, 0, 0, -1, + GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_ID); + if (!table_cursor) { + return ctx->rc; + } + grn_rc rc = TableCursor::open(ctx, table_cursor, 0.0, cursor); + if (rc != GRN_SUCCESS) { + grn_table_cursor_close(ctx, table_cursor); + } + return rc; +} + +grn_rc Cursor::read(Record *records, size_t size, size_t *count) { + if ((!records && (size != 0)) || !count) { + return GRN_INVALID_ARGUMENT; + } + *count = 0; + return GRN_SUCCESS; +} + +// -- ExpressionNode -- + +class ExpressionNode { + public: + ExpressionNode() {} + virtual ~ExpressionNode() {} + + virtual ExpressionNodeType type() const = 0; + virtual DataType data_type() const = 0; + + virtual grn_rc filter(Record *input, size_t input_size, + Record *output, size_t *output_size) { + return GRN_OPERATION_NOT_SUPPORTED; + } + virtual grn_rc adjust(Record *records, size_t num_records) { + return GRN_OPERATION_NOT_SUPPORTED; + } +}; + +// -- TypedNode<T> -- + +template <typename T> +class TypedNode : public ExpressionNode { + public: + TypedNode() : ExpressionNode() {} + virtual ~TypedNode() {} + + DataType data_type() const { + return T::data_type(); + } + + virtual grn_rc evaluate( + const Record *records, size_t num_records, T *results) = 0; +}; + +// -- TypedNode<Bool> -- + +template <> +class TypedNode<Bool> : public ExpressionNode { + public: + TypedNode() : ExpressionNode(), values_for_filter_() {} + virtual ~TypedNode() {} + + DataType data_type() const { + return Bool::data_type(); + } + + virtual grn_rc filter(Record *input, size_t input_size, + Record *output, size_t *output_size); + + virtual grn_rc evaluate( + const Record *records, size_t num_records, Bool *results) = 0; + + private: + std::vector<Bool> values_for_filter_; +}; + +grn_rc TypedNode<Bool>::filter(Record *input, size_t input_size, + Record *output, size_t *output_size) { + if (values_for_filter_.size() < input_size) { + values_for_filter_.resize(input_size); + } + grn_rc rc = evaluate(input, input_size, &*values_for_filter_.begin()); + if (rc != GRN_SUCCESS) { + return rc; + } + size_t count = 0; + for (size_t i = 0; i < input_size; ++i) { + if (values_for_filter_[i].raw) { + output[count] = input[i]; + ++count; + } + } + *output_size = count; + return GRN_SUCCESS; +} + +// -- TypedNode<Float> -- + +template <> +class TypedNode<Float> : public ExpressionNode { + public: + TypedNode() : ExpressionNode(), values_for_adjust_() {} + virtual ~TypedNode() {} + + DataType data_type() const { + return Float::data_type(); + } + + virtual grn_rc adjust(Record *records, size_t num_records); + + virtual grn_rc evaluate( + const Record *records, size_t num_records, Float *results) = 0; + + private: + std::vector<Float> values_for_adjust_; +}; + +grn_rc TypedNode<Float>::adjust(Record *records, size_t num_records) { + if (values_for_adjust_.size() < num_records) { + values_for_adjust_.resize(num_records); + } + grn_rc rc = evaluate(records, num_records, &*values_for_adjust_.begin()); + if (rc != GRN_SUCCESS) { + return rc; + } + for (size_t i = 0; i < num_records; ++i) { + records[i].score = values_for_adjust_[i].raw; + } + return GRN_SUCCESS; +} + +// -- IDNode -- + +class IDNode : public TypedNode<Int> { + public: + ~IDNode() {} + + static grn_rc open(ExpressionNode **node) { + ExpressionNode *new_node = new (std::nothrow) IDNode(); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_ID_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, Int *results) { + for (size_t i = 0; i < num_records; ++i) { + results[i] = Int(records[i].id); + } + return GRN_SUCCESS; + } + + private: + IDNode() : TypedNode<Int>() {} +}; + +// -- ScoreNode -- + +class ScoreNode : public TypedNode<Float> { + public: + ~ScoreNode() {} + + static grn_rc open(ExpressionNode **node) { + ExpressionNode *new_node = new (std::nothrow) ScoreNode(); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_SCORE_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, Float *results) { + for (size_t i = 0; i < num_records; ++i) { + results[i] = Float(records[i].score); + } + return GRN_SUCCESS; + } + + private: + ScoreNode() : TypedNode<Float>() {} +}; + +// -- ConstantNode<T> -- + +template <typename T> +class ConstantNode : public TypedNode<T> { + public: + ~ConstantNode() {} + + static grn_rc open(const T &value, ExpressionNode **node) { + ConstantNode *new_node = new (std::nothrow) ConstantNode(value); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_CONSTANT_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, T *results) { + for (size_t i = 0; i < num_records; ++i) { + results[i] = value_; + } + return GRN_SUCCESS; + } + + private: + T value_; + + explicit ConstantNode(const T &value) : TypedNode<T>(), value_(value) {} +}; + +// -- ConstantNode<Bool> -- + +template <> +class ConstantNode<Bool> : public TypedNode<Bool> { + public: + ~ConstantNode() {} + + static grn_rc open(Bool value, ExpressionNode **node) { + ConstantNode *new_node = new (std::nothrow) ConstantNode(value); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_CONSTANT_NODE; + } + + grn_rc filter(Record *input, size_t input_size, + Record *output, size_t *output_size); + + grn_rc evaluate( + const Record *records, size_t num_records, Bool *results) { + for (size_t i = 0; i < num_records; ++i) { + results[i] = value_; + } + return GRN_SUCCESS; + } + + private: + Bool value_; + + explicit ConstantNode(Bool value) : TypedNode<Bool>(), value_(value) {} +}; + +grn_rc ConstantNode<Bool>::filter( + Record *input, size_t input_size, + Record *output, size_t *output_size) { + if (value_.raw == GRN_TRUE) { + // The I/O areas are the same and there is no need to copy records. + if (input != output) { + for (size_t i = 0; i < input_size; ++i) { + output[i] = input[i]; + } + } + *output_size = input_size; + } else { + *output_size = 0; + } + return GRN_SUCCESS; +} + +// -- ConstantNode<Float> -- + +template <> +class ConstantNode<Float> : public TypedNode<Float> { + public: + ~ConstantNode() {} + + static grn_rc open(Float value, ExpressionNode **node) { + ConstantNode *new_node = new (std::nothrow) ConstantNode(value); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_CONSTANT_NODE; + } + + grn_rc adjust(Record *records, size_t num_records) { + for (size_t i = 0; i < num_records; ++i) { + records[i].score = value_.raw; + } + return GRN_SUCCESS; + } + + grn_rc evaluate( + const Record *records, size_t num_records, Float *results) { + for (size_t i = 0; i < num_records; ++i) { + results[i] = value_; + } + return GRN_SUCCESS; + } + + private: + Float value_; + + explicit ConstantNode(Float value) : TypedNode<Float>(), value_(value) {} +}; + +// -- ConstantNode<Text> -- + +template <> +class ConstantNode<Text> : public TypedNode<Text> { + public: + ~ConstantNode() {} + + static grn_rc open(const Text &value, ExpressionNode **node) { + ConstantNode *new_node = new (std::nothrow) ConstantNode(value); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + try { + new_node->value_buf_.resize(value.raw.size); + } catch (const std::bad_alloc &) { + delete new_node; + return GRN_NO_MEMORY_AVAILABLE; + } + std::memcpy(&*new_node->value_buf_.begin(), value.raw.ptr, value.raw.size); + new_node->value_.raw.ptr = &*new_node->value_buf_.begin(); + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_CONSTANT_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, Text *results) { + for (size_t i = 0; i < num_records; ++i) { + results[i] = value_; + } + return GRN_SUCCESS; + } + + private: + Text value_; + std::vector<char> value_buf_; + + explicit ConstantNode(const Text &value) + : TypedNode<Text>(), value_(value), value_buf_() {} +}; + +// -- ColumnNode -- + +template <typename T> +class ColumnNode : public TypedNode<T> { + public: + ~ColumnNode() {} + + static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) { + ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_COLUMN_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, T *results) { + // TODO + return GRN_OPERATION_NOT_SUPPORTED; + } + + private: + grn_ctx *ctx_; + grn_obj *column_; + + ColumnNode(grn_ctx *ctx, grn_obj *column) + : TypedNode<T>(), ctx_(ctx), column_(column) {} +}; + +// -- ColumnNode<Bool> -- + +template <> +class ColumnNode<Bool> : public TypedNode<Bool> { + public: + ~ColumnNode() {} + + static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) { + ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_COLUMN_NODE; + } + + grn_rc filter( + Record *input, size_t input_size, + Record *output, size_t *output_size); + + grn_rc evaluate( + const Record *records, size_t num_records, Bool *results); + + private: + grn_ctx *ctx_; + grn_obj *column_; + + ColumnNode(grn_ctx *ctx, grn_obj *column) + : TypedNode<Bool>(), ctx_(ctx), column_(column) {} +}; + +grn_rc ColumnNode<Bool>::filter( + Record *input, size_t input_size, + Record *output, size_t *output_size) { + grn_obj value; + GRN_BOOL_INIT(&value, 0); + size_t count = 0; + for (size_t i = 0; i < input_size; ++i) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, input[i].id, &value); + if (ctx_->rc != GRN_SUCCESS) { + return ctx_->rc; + } + if (GRN_BOOL_VALUE(&value) == GRN_TRUE) { + output[count] = input[i]; + ++count; + } + } + GRN_OBJ_FIN(ctx_, &value); + *output_size = count; + return GRN_SUCCESS; +} + +grn_rc ColumnNode<Bool>::evaluate( + const Record *records, size_t num_records, Bool *results) { + grn_obj value; + GRN_BOOL_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + if (ctx_->rc != GRN_SUCCESS) { + return ctx_->rc; + } + results[i] = Bool(GRN_BOOL_VALUE(&value) == GRN_TRUE); + } + GRN_OBJ_FIN(ctx_, &value); + return GRN_SUCCESS; +} + +// -- ColumnNode<Int> -- + +template <> +class ColumnNode<Int> : public TypedNode<Int> { + public: + ~ColumnNode() {} + + static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) { + ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_COLUMN_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, Int *results); + + private: + grn_ctx *ctx_; + grn_obj *column_; + + ColumnNode(grn_ctx *ctx, grn_obj *column) + : TypedNode<Int>(), ctx_(ctx), column_(column) {} +}; + +grn_rc ColumnNode<Int>::evaluate( + const Record *records, size_t num_records, Int *results) { + grn_id range = grn_obj_get_range(ctx_, column_); + grn_obj value; + switch (range) { + case GRN_DB_INT8: { + GRN_INT8_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Int(GRN_INT8_VALUE(&value)); + } + break; + } + case GRN_DB_INT16: { + GRN_INT16_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Int(GRN_INT16_VALUE(&value)); + } + break; + } + case GRN_DB_INT32: { + GRN_INT32_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Int(GRN_INT32_VALUE(&value)); + } + break; + } + case GRN_DB_INT64: { + GRN_INT64_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Int(GRN_INT64_VALUE(&value)); + } + break; + } + case GRN_DB_UINT8: { + GRN_UINT8_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Int(GRN_UINT8_VALUE(&value)); + } + break; + } + case GRN_DB_UINT16: { + GRN_UINT16_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Int(GRN_UINT16_VALUE(&value)); + } + break; + } + case GRN_DB_UINT32: { + GRN_UINT32_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Int(GRN_UINT32_VALUE(&value)); + } + break; + } + case GRN_DB_UINT64: { + GRN_UINT64_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + // FIXME: Type conversion from UInt64 to Int may lose the content. + results[i] = Int(GRN_UINT64_VALUE(&value)); + } + break; + } + } + GRN_OBJ_FIN(ctx_, &value); + return GRN_SUCCESS; +} + +// -- ColumnNode<Float> -- + +template <> +class ColumnNode<Float> : public TypedNode<Float> { + public: + ~ColumnNode() {} + + static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) { + ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_COLUMN_NODE; + } + + grn_rc adjust(Record *records, size_t num_records); + + grn_rc evaluate( + const Record *records, size_t num_records, Float *results); + + private: + grn_ctx *ctx_; + grn_obj *column_; + + ColumnNode(grn_ctx *ctx, grn_obj *column) + : TypedNode<Float>(), ctx_(ctx), column_(column) {} +}; + +grn_rc ColumnNode<Float>::adjust(Record *records, size_t num_records) { + grn_obj value; + GRN_FLOAT_INIT(&value, 0); + for (size_t i = 0; i < num_records; ++i) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + records[i].score = GRN_FLOAT_VALUE(&value); + } + GRN_OBJ_FIN(ctx_, &value); + return GRN_SUCCESS; +} + +grn_rc ColumnNode<Float>::evaluate( + const Record *records, size_t num_records, Float *results) { + grn_obj value; + GRN_FLOAT_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Float(GRN_FLOAT_VALUE(&value)); + } + GRN_OBJ_FIN(ctx_, &value); + return GRN_SUCCESS; +} + +// -- ColumnNode<Time> -- + +template <> +class ColumnNode<Time> : public TypedNode<Time> { + public: + ~ColumnNode() {} + + static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) { + ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_COLUMN_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, Time *results); + + private: + grn_ctx *ctx_; + grn_obj *column_; + + ColumnNode(grn_ctx *ctx, grn_obj *column) + : TypedNode<Time>(), ctx_(ctx), column_(column) {} +}; + +grn_rc ColumnNode<Time>::evaluate( + const Record *records, size_t num_records, Time *results) { + grn_obj value; + GRN_TIME_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + results[i] = Time(GRN_TIME_VALUE(&value)); + } + GRN_OBJ_FIN(ctx_, &value); + return GRN_SUCCESS; +} + +// -- ColumnNode<Text> -- + +template <> +class ColumnNode<Text> : public TypedNode<Text> { + public: + ~ColumnNode() { + GRN_OBJ_FIN(ctx_, &buf_); + } + + static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) { + ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_COLUMN_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, Text *results); + + private: + grn_ctx *ctx_; + grn_obj *column_; + grn_obj buf_; + + ColumnNode(grn_ctx *ctx, grn_obj *column) + : TypedNode<Text>(), ctx_(ctx), column_(column), buf_() { + GRN_TEXT_INIT(&buf_, 0); + } +}; + +grn_rc ColumnNode<Text>::evaluate( + const Record *records, size_t num_records, Text *results) { + GRN_BULK_REWIND(&buf_); + size_t offset = 0; + for (size_t i = 0; i < num_records; i++) { + grn_obj_get_value(ctx_, column_, records[i].id, &buf_); + if (ctx_->rc != GRN_SUCCESS) { + return ctx_->rc; + } + size_t next_offset = GRN_TEXT_LEN(&buf_); + results[i].raw.size = next_offset - offset; + offset = next_offset; + } + char *ptr = GRN_TEXT_VALUE(&buf_); + for (size_t i = 0; i < num_records; i++) { + results[i].raw.ptr = ptr; + ptr += results[i].raw.size; + } + return GRN_SUCCESS; +} + +// -- ColumnNode<GeoPoint> -- + +template <> +class ColumnNode<GeoPoint> : public TypedNode<GeoPoint> { + public: + ~ColumnNode() {} + + static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) { + ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + ExpressionNodeType type() const { + return GRN_EGN_COLUMN_NODE; + } + + grn_rc evaluate( + const Record *records, size_t num_records, GeoPoint *results); + + private: + grn_ctx *ctx_; + grn_obj *column_; + + ColumnNode(grn_ctx *ctx, grn_obj *column) + : TypedNode<GeoPoint>(), ctx_(ctx), column_(column) {} +}; + +grn_rc ColumnNode<GeoPoint>::evaluate( + const Record *records, size_t num_records, GeoPoint *results) { + grn_obj value; + GRN_WGS84_GEO_POINT_INIT(&value, 0); + for (size_t i = 0; i < num_records; i++) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx_, column_, records[i].id, &value); + GRN_GEO_POINT_VALUE( + &value, results[i].raw.latitude, results[i].raw.longitude); + } + GRN_OBJ_FIN(ctx_, &value); + return GRN_SUCCESS; +} + +// -- OperatorNode -- + +template <typename T> +class OperatorNode : public TypedNode<T> { + public: + OperatorNode() : TypedNode<T>() {} + virtual ~OperatorNode() {} + + ExpressionNodeType type() const { + return GRN_EGN_OPERATOR_NODE; + } +}; + +template <typename T> +grn_rc operator_node_fill_arg_values( + const Record *records, size_t num_records, + TypedNode<T> *arg, std::vector<T> *arg_values) { + size_t old_size = arg_values->size(); + if (old_size < num_records) try { + arg_values->resize(num_records); + } catch (const std::bad_alloc &) { + return GRN_NO_MEMORY_AVAILABLE; + } + switch (arg->type()) { + case GRN_EGN_CONSTANT_NODE: { + if (old_size < num_records) { + return arg->evaluate(records + old_size, num_records - old_size, + &*arg_values->begin() + old_size); + } + return GRN_SUCCESS; + } + default: { + return arg->evaluate(records, num_records, &*arg_values->begin()); + } + } +} + +// --- UnaryNode --- + +template <typename T, typename U> +class UnaryNode : public OperatorNode<T> { + public: + explicit UnaryNode(ExpressionNode *arg) + : OperatorNode<T>(), arg_(static_cast<TypedNode<U> *>(arg)), + arg_values_() {} + virtual ~UnaryNode() { + delete arg_; + } + + protected: + TypedNode<U> *arg_; + std::vector<U> arg_values_; + + grn_rc fill_arg_values(const Record *records, size_t num_records) { + return operator_node_fill_arg_values( + records, num_records, arg_, &arg_values_); + } +}; + +// ---- LogicalNotNode ---- + +class LogicalNotNode : public UnaryNode<Bool, Bool> { + public: + ~LogicalNotNode() {} + + static grn_rc open(ExpressionNode *arg, ExpressionNode **node) { + LogicalNotNode *new_node = new (std::nothrow) LogicalNotNode(arg); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + grn_rc filter( + Record *input, size_t input_size, + Record *output, size_t *output_size); + + grn_rc evaluate( + const Record *records, size_t num_records, Bool *results); + + private: + std::vector<Record> temp_records_; + + explicit LogicalNotNode(ExpressionNode *arg) + : UnaryNode<Bool, Bool>(arg), temp_records_() {} +}; + +grn_rc LogicalNotNode::filter( + Record *input, size_t input_size, + Record *output, size_t *output_size) { + if (temp_records_.size() <= input_size) { + try { + temp_records_.resize(input_size + 1); + temp_records_[input_size].id = GRN_ID_NIL; + } catch (const std::bad_alloc &) { + return GRN_NO_MEMORY_AVAILABLE; + } + } + size_t temp_size; + grn_rc rc = + arg_->filter(input, input_size, &*temp_records_.begin(), &temp_size); + if (rc != GRN_SUCCESS) { + return rc; + } + if (temp_size == 0) { + *output_size = 0; + return GRN_SUCCESS; + } + + size_t count = 0; + for (size_t i = 0; i < input_size; ++i) { + if (input[i].id != temp_records_[i - count].id) { + output[count] = input[i]; + ++count; + } + } + *output_size = count; + return GRN_SUCCESS; +} + +grn_rc LogicalNotNode::evaluate( + const Record *records, size_t num_records, Bool *results) { + grn_rc rc = arg_->evaluate(records, num_records, results); + if (rc == GRN_SUCCESS) { + for (size_t i = 0; i < num_records; ++i) { + results[i] = Bool(results[i].raw != GRN_TRUE); + } + } + return rc; +} + +// --- BinaryNode --- + +template <typename T, typename U, typename V> +class BinaryNode : public OperatorNode<T> { + public: + BinaryNode(ExpressionNode *arg1, ExpressionNode *arg2) + : OperatorNode<T>(), + arg1_(static_cast<TypedNode<U> *>(arg1)), + arg2_(static_cast<TypedNode<V> *>(arg2)), + arg1_values_(), arg2_values_() {} + virtual ~BinaryNode() { + delete arg1_; + delete arg2_; + } + + protected: + TypedNode<U> *arg1_; + TypedNode<V> *arg2_; + std::vector<U> arg1_values_; + std::vector<V> arg2_values_; + + grn_rc fill_arg1_values(const Record *records, size_t num_records) { + return operator_node_fill_arg_values( + records, num_records, arg1_, &arg1_values_); + } + grn_rc fill_arg2_values(const Record *records, size_t num_records) { + return operator_node_fill_arg_values( + records, num_records, arg2_, &arg2_values_); + } +}; + +// ---- LogicalAndNode ---- + +class LogicalAndNode : public BinaryNode<Bool, Bool, Bool> { + public: + ~LogicalAndNode() {} + + static grn_rc open( + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + LogicalAndNode *new_node = new (std::nothrow) LogicalAndNode(arg1, arg2); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + grn_rc filter( + Record *input, size_t input_size, + Record *output, size_t *output_size) { + grn_rc rc = arg1_->filter(input, input_size, output, output_size); + if (rc == GRN_SUCCESS) { + rc = arg2_->filter(output, *output_size, output, output_size); + } + return rc; + } + + grn_rc evaluate( + const Record *records, size_t num_records, Bool *results); + + private: + std::vector<Record> temp_records_; + + LogicalAndNode(ExpressionNode *arg1, ExpressionNode *arg2) + : BinaryNode<Bool, Bool, Bool>(arg1, arg2), temp_records_() {} +}; + +grn_rc LogicalAndNode::evaluate( + const Record *records, size_t num_records, Bool *results) { + // Evaluate "arg1" for all the records. + // Then, evaluate "arg2" for non-false records. + grn_rc rc = arg1_->evaluate(records, num_records, results); + if (rc != GRN_SUCCESS) { + return rc; + } + if (temp_records_.size() < num_records) try { + temp_records_.resize(num_records); + } catch (const std::bad_alloc &) { + return GRN_NO_MEMORY_AVAILABLE; + } + size_t count = 0; + for (size_t i = 0; i < num_records; ++i) { + if (results[i].raw == GRN_TRUE) { + temp_records_[count] = records[i]; + ++count; + } + } + if (count == 0) { + // Nothing to do. + return GRN_SUCCESS; + } + rc = fill_arg2_values(&*temp_records_.begin(), count); + if (rc != GRN_SUCCESS) { + return rc; + } + + // Merge the evaluation results. + count = 0; + for (size_t i = 0; i < num_records; ++i) { + if (results[i].raw == GRN_TRUE) { + results[i] = arg2_values_[count]; + ++count; + } + } + return GRN_SUCCESS; +} + +// ---- LogicalOrNode ---- + +class LogicalOrNode : public BinaryNode<Bool, Bool, Bool> { + public: + ~LogicalOrNode() {} + + static grn_rc open( + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + LogicalOrNode *new_node = new (std::nothrow) LogicalOrNode(arg1, arg2); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; + } + + grn_rc filter( + Record *input, size_t input_size, + Record *output, size_t *output_size); + + grn_rc evaluate( + const Record *records, size_t num_records, Bool *results); + + private: + std::vector<Record> temp_records_; + + LogicalOrNode(ExpressionNode *arg1, ExpressionNode *arg2) + : BinaryNode<Bool, Bool, Bool>(arg1, arg2), temp_records_() {} +}; + +grn_rc LogicalOrNode::filter( + Record *input, size_t input_size, + Record *output, size_t *output_size) { + // Evaluate "arg1" for all the records. + // Then, evaluate "arg2" for non-true records. + grn_rc rc = fill_arg1_values(input, input_size); + if (rc != GRN_SUCCESS) { + return rc; + } + if (temp_records_.size() < input_size) try { + temp_records_.resize(input_size); + } catch (const std::bad_alloc &) { + return GRN_NO_MEMORY_AVAILABLE; + } + size_t count = 0; + for (size_t i = 0; i < input_size; ++i) { + if (arg1_values_[i].raw == GRN_FALSE) { + temp_records_[count] = input[i]; + ++count; + } + } + if (count == 0) { + if (input != output) { + for (size_t i = 0; i < input_size; ++i) { + output[i] = input[i]; + } + } + *output_size = input_size; + return GRN_SUCCESS; + } + rc = fill_arg2_values(&*temp_records_.begin(), count); + if (rc != GRN_SUCCESS) { + return rc; + } + + // Merge the evaluation results. + count = 0; + size_t output_count = 0; + for (size_t i = 0; i < input_size; ++i) { + if (arg1_values_[i].raw == GRN_TRUE) { + output[output_count] = input[i]; + ++output_count; + } else { + if (arg2_values_[count].raw == GRN_TRUE) { + output[output_count] = input[i]; + ++output_count; + } + ++count; + } + } + *output_size = output_count; + return GRN_SUCCESS; +} + +grn_rc LogicalOrNode::evaluate( + const Record *records, size_t num_records, Bool *results) { + // Evaluate "arg1" for all the records. + // Then, evaluate "arg2" for non-true records. + grn_rc rc = arg1_->evaluate(records, num_records, results); + if (rc != GRN_SUCCESS) { + return rc; + } + if (temp_records_.size() < num_records) try { + temp_records_.resize(num_records); + } catch (const std::bad_alloc &) { + return GRN_NO_MEMORY_AVAILABLE; + } + size_t count = 0; + for (size_t i = 0; i < num_records; ++i) { + if (results[i].raw == GRN_FALSE) { + temp_records_[count] = records[i]; + ++count; + } + } + if (count == 0) { + // Nothing to do. + return GRN_SUCCESS; + } + rc = fill_arg2_values(&*temp_records_.begin(), count); + if (rc != GRN_SUCCESS) { + return rc; + } + + // Merge the evaluation results. + count = 0; + for (size_t i = 0; i < num_records; ++i) { + if (results[i].raw == GRN_FALSE) { + results[i] = arg2_values_[count]; + ++count; + } + } + return GRN_SUCCESS; +} + +// -- GenericBinaryNode -- + +template <typename T, + typename U = typename T::Value, + typename V = typename T::Arg1, + typename W = typename T::Arg2> +class GenericBinaryNode : public BinaryNode<U, V, W> { + public: + GenericBinaryNode(ExpressionNode *arg1, ExpressionNode *arg2) + : BinaryNode<U, V, W>(arg1, arg2), operator_() {} + ~GenericBinaryNode() {} + + grn_rc evaluate( + const Record *records, size_t num_records, Bool *results); + + private: + T operator_; +}; + +template <typename T, typename U, typename V, typename W> +grn_rc GenericBinaryNode<T, U, V, W>::evaluate( + const Record *records, size_t num_records, Bool *results) { + grn_rc rc = this->fill_arg1_values(records, num_records); + if (rc != GRN_SUCCESS) { + return rc; + } + rc = this->fill_arg2_values(records, num_records); + if (rc != GRN_SUCCESS) { + return rc; + } + for (size_t i = 0; i < num_records; ++i) { + results[i] = operator_(this->arg1_values_[i], this->arg2_values_[i]); + } + return GRN_SUCCESS; +} + +template <typename T, typename V, typename W> +class GenericBinaryNode<T, Bool, V, W> : public BinaryNode<Bool, V, W> { + public: + GenericBinaryNode(ExpressionNode *arg1, ExpressionNode *arg2) + : BinaryNode<Bool, V, W>(arg1, arg2), operator_() {} + ~GenericBinaryNode() {} + + grn_rc filter( + Record *input, size_t input_size, + Record *output, size_t *output_size); + + grn_rc evaluate( + const Record *records, size_t num_records, Bool *results); + + private: + T operator_; +}; + +template <typename T, typename V, typename W> +grn_rc GenericBinaryNode<T, Bool, V, W>::filter( + Record *input, size_t input_size, + Record *output, size_t *output_size) { + grn_rc rc = this->fill_arg1_values(input, input_size); + if (rc != GRN_SUCCESS) { + return rc; + } + rc = this->fill_arg2_values(input, input_size); + if (rc != GRN_SUCCESS) { + return rc; + } + size_t count = 0; + for (size_t i = 0; i < input_size; ++i) { + if (operator_(this->arg1_values_[i], this->arg2_values_[i]).raw == + GRN_TRUE) { + output[count] = input[i]; + ++count; + } + } + *output_size = count; + return GRN_SUCCESS; +} + +template <typename T, typename V, typename W> +grn_rc GenericBinaryNode<T, Bool, V, W>::evaluate( + const Record *records, size_t num_records, Bool *results) { + grn_rc rc = this->fill_arg1_values(records, num_records); + if (rc != GRN_SUCCESS) { + return rc; + } + rc = this->fill_arg2_values(records, num_records); + if (rc != GRN_SUCCESS) { + return rc; + } + for (size_t i = 0; i < num_records; ++i) { + results[i] = operator_(this->arg1_values_[i], this->arg2_values_[i]); + } + return GRN_SUCCESS; +} + +// ----- EqualNode ----- + +template <typename T> +struct EqualOperator { + typedef Bool Value; + typedef T Arg1; + typedef T Arg2; + Value operator()(const Arg1 &arg1, const Arg2 &arg2) const { + return Bool(arg1 == arg2); + } +}; + +template <typename T> +grn_rc equal_node_open(EqualOperator<T> op, + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + GenericBinaryNode<EqualOperator<T> > *new_node = + new (std::nothrow) GenericBinaryNode<EqualOperator<T> >(arg1, arg2); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; +} + +// ----- NotEqualNode ----- + +template <typename T> +struct NotEqualOperator { + typedef Bool Value; + typedef T Arg1; + typedef T Arg2; + Value operator()(const Arg1 &arg1, const Arg2 &arg2) const { + return Bool(arg1 != arg2); + } +}; + +template <typename T> +grn_rc not_equal_node_open(NotEqualOperator<T> op, + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + GenericBinaryNode<NotEqualOperator<T> > *new_node = + new (std::nothrow) GenericBinaryNode<NotEqualOperator<T> >(arg1, arg2); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; +} + +// ----- LessNode ----- + +template <typename T> +struct LessOperator { + typedef Bool Value; + typedef T Arg1; + typedef T Arg2; + Value operator()(const Arg1 &arg1, const Arg2 &arg2) const { + return Bool(arg1 < arg2); + } +}; + +template <typename T> +grn_rc less_node_open(LessOperator<T> op, + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + GenericBinaryNode<LessOperator<T> > *new_node = + new (std::nothrow) GenericBinaryNode<LessOperator<T> >(arg1, arg2); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; +} + +// ----- LessEqualNode ----- + +template <typename T> +struct LessEqualOperator { + typedef Bool Value; + typedef T Arg1; + typedef T Arg2; + Value operator()(const Arg1 &arg1, const Arg2 &arg2) const { + return Bool(arg1 < arg2); + } +}; + +template <typename T> +grn_rc less_equal_node_open(LessEqualOperator<T> op, + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + GenericBinaryNode<LessEqualOperator<T> > *new_node = + new (std::nothrow) GenericBinaryNode<LessEqualOperator<T> >(arg1, arg2); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; +} + +// ----- GreaterNode ----- + +template <typename T> +struct GreaterOperator { + typedef Bool Value; + typedef T Arg1; + typedef T Arg2; + Value operator()(const Arg1 &arg1, const Arg2 &arg2) const { + return Bool(arg1 < arg2); + } +}; + +template <typename T> +grn_rc greater_node_open(GreaterOperator<T> op, + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + GenericBinaryNode<GreaterOperator<T> > *new_node = + new (std::nothrow) GenericBinaryNode<GreaterOperator<T> >(arg1, arg2); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; +} + +// ----- GreaterEqualNode ----- + +template <typename T> +struct GreaterEqualOperator { + typedef Bool Value; + typedef T Arg1; + typedef T Arg2; + Value operator()(const Arg1 &arg1, const Arg2 &arg2) const { + return Bool(arg1 < arg2); + } +}; + +template <typename T> +grn_rc greater_equal_node_open(GreaterEqualOperator<T> op, + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + GenericBinaryNode<GreaterEqualOperator<T> > *new_node = + new (std::nothrow) GenericBinaryNode<GreaterEqualOperator<T> >(arg1, arg2); + if (!new_node) { + return GRN_NO_MEMORY_AVAILABLE; + } + *node = new_node; + return GRN_SUCCESS; +} + +// -- ExpressionToken -- + +enum ExpressionTokenType { + DUMMY_TOKEN, + CONSTANT_TOKEN, + NAME_TOKEN, + UNARY_OPERATOR_TOKEN, + BINARY_OPERATOR_TOKEN, + DEREFERENCE_TOKEN, + BRACKET_TOKEN +}; + +enum ExpressionBracketType { + LEFT_ROUND_BRACKET, + RIGHT_ROUND_BRACKET, + LEFT_SQUARE_BRACKET, + RIGHT_SQUARE_BRACKET +}; + +// TODO: std::string should not be used. +class ExpressionToken { + public: + ExpressionToken() : string_(), type_(DUMMY_TOKEN), dummy_(0), priority_(0) {} + ExpressionToken(const std::string &string, ExpressionTokenType token_type) + : string_(string), type_(token_type), dummy_(0), priority_(0) {} + ExpressionToken(const std::string &string, + ExpressionBracketType bracket_type) + : string_(string), type_(BRACKET_TOKEN), bracket_type_(bracket_type), + priority_(0) {} + ExpressionToken(const std::string &string, OperatorType operator_type) + : string_(string), type_(get_operator_token_type(operator_type)), + operator_type_(operator_type), + priority_(get_operator_priority(operator_type)) {} + + const std::string &string() const { + return string_; + } + ExpressionTokenType type() const { + return type_; + } + ExpressionBracketType bracket_type() const { + return bracket_type_; + } + OperatorType operator_type() const { + return operator_type_; + } + int priority() const { + return priority_; + } + + private: + std::string string_; + ExpressionTokenType type_; + union { + int dummy_; + ExpressionBracketType bracket_type_; + OperatorType operator_type_; + }; + int priority_; + + static ExpressionTokenType get_operator_token_type( + OperatorType operator_type); + static int get_operator_priority(OperatorType operator_type); +}; + +ExpressionTokenType ExpressionToken::get_operator_token_type( + OperatorType operator_type) { + switch (operator_type) { + case GRN_OP_NOT: { + return UNARY_OPERATOR_TOKEN; + } + case GRN_OP_AND: + case GRN_OP_OR: + case GRN_OP_EQUAL: + case GRN_OP_NOT_EQUAL: + case GRN_OP_LESS: + case GRN_OP_LESS_EQUAL: + case GRN_OP_GREATER: + case GRN_OP_GREATER_EQUAL: { + return BINARY_OPERATOR_TOKEN; + } + default: { + // TODO: ERROR_TOKEN or something should be used...? + // Or, default should be removed? + return DUMMY_TOKEN; + } + } +} + +int ExpressionToken::get_operator_priority( + OperatorType operator_type) { + switch (operator_type) { + case GRN_OP_NOT: { +// case GRN_OP_BITWISE_NOT: +// case GRN_OP_POSITIVE: +// case GRN_OP_NEGATIVE: +// case GRN_OP_TO_INT: +// case GRN_OP_TO_FLOAT: { + return 3; + } + case GRN_OP_AND: { + return 13; + } + case GRN_OP_OR: { + return 14; + } + case GRN_OP_EQUAL: + case GRN_OP_NOT_EQUAL: { + return 9; + } + case GRN_OP_LESS: + case GRN_OP_LESS_EQUAL: + case GRN_OP_GREATER: + case GRN_OP_GREATER_EQUAL: { + return 8; + } +// case GRN_OP_BITWISE_AND: { +// return 10; +// } +// case GRN_OP_BITWISE_OR: { +// return 12; +// } +// case GRN_OP_BITWISE_XOR: { +// return 11; +// } +// case GRN_OP_PLUS: +// case GRN_OP_MINUS: { +// return 6; +// } +// case GRN_OP_MULTIPLICATION: +// case GRN_OP_DIVISION: +// case GRN_OP_MODULUS: { +// return 5; +// } +// case GRN_OP_STARTS_WITH: +// case GRN_OP_ENDS_WITH: +// case GRN_OP_CONTAINS: { +// return 7; +// } +// case GRN_OP_SUBSCRIPT: { +// return 2; +// } + default: { + return 100; + } + } +} + +// -- ExpressionParser -- + +class ExpressionParser { + public: + static grn_rc parse(grn_ctx *ctx, grn_obj *table, + const char *query, size_t query_size, Expression **expression); + + private: + grn_ctx *ctx_; + grn_obj *table_; + std::vector<ExpressionToken> tokens_; + std::vector<ExpressionToken> stack_; + Expression *expression_; + + ExpressionParser(grn_ctx *ctx, grn_obj *table) + : ctx_(ctx), table_(table), tokens_(), stack_(), expression_(NULL) {} + ~ExpressionParser() { + delete expression_; + } + + grn_rc tokenize(const char *query, size_t query_size); + grn_rc compose(); + grn_rc push_token(const ExpressionToken &token); +}; + +grn_rc ExpressionParser::parse(grn_ctx *ctx, grn_obj *table, + const char *query, size_t query_size, Expression **expression) { + ExpressionParser *parser = new (std::nothrow) ExpressionParser(ctx, table); + if (!parser) { + return GRN_NO_MEMORY_AVAILABLE; + } + grn_rc rc = parser->tokenize(query, query_size); + if (rc == GRN_SUCCESS) { + rc = parser->compose(); + if (rc == GRN_SUCCESS) { + *expression = parser->expression_; + parser->expression_ = NULL; + } + } + delete parser; + return rc; +} + +grn_rc ExpressionParser::tokenize(const char *query, size_t query_size) { + const char *rest = query; + size_t rest_size = query_size; + while (rest_size != 0) { + // Ignore white-space characters. + size_t pos; + for (pos = 0; pos < rest_size; ++pos) { + if (!std::isspace(static_cast<uint8_t>(rest[pos]))) { + break; + } + } + rest += pos; + rest_size -= pos; + switch (rest[0]) { + case '!': { + if ((rest_size >= 2) && (rest[1] == '=')) { + tokens_.push_back(ExpressionToken("!=", GRN_OP_NOT_EQUAL)); + rest += 2; + rest_size -= 2; + } else { + tokens_.push_back(ExpressionToken("!", GRN_OP_NOT)); + ++rest; + --rest_size; + } + break; + } +// case '~': { +// tokens_.push_back(ExpressionToken("~", GRN_OP_BITWISE_NOT)); +// rest = rest.substring(1); +// break; +// } + case '=': { + if ((rest_size >= 2) && (rest[1] == '=')) { + tokens_.push_back(ExpressionToken("==", GRN_OP_EQUAL)); + rest += 2; + rest_size -= 2; + } else { + return GRN_INVALID_ARGUMENT; + } + break; + } + case '<': { + if ((rest_size >= 2) && (rest[1] == '=')) { + tokens_.push_back(ExpressionToken("<=", GRN_OP_LESS_EQUAL)); + rest += 2; + rest_size -= 2; + } else { + tokens_.push_back(ExpressionToken("<", GRN_OP_LESS)); + ++rest; + --rest_size; + } + break; + } + case '>': { + if ((rest_size >= 2) && (rest[1] == '=')) { + tokens_.push_back(ExpressionToken(">=", GRN_OP_GREATER_EQUAL)); + rest += 2; + rest_size -= 2; + } else { + tokens_.push_back(ExpressionToken(">", GRN_OP_GREATER)); + ++rest; + --rest_size; + } + break; + } + case '&': { + if ((rest_size >= 2) && (rest[1] == '&')) { + tokens_.push_back(ExpressionToken("&&", GRN_OP_AND)); + rest += 2; + rest_size -= 2; + } else { +// tokens_.push_back(ExpressionToken("&", GRN_OP_BITWISE_AND)); +// ++rest; +// --rest_size; + return GRN_INVALID_ARGUMENT; + } + break; + } + case '|': { + if ((rest_size >= 2) && (rest[1] == '|')) { + tokens_.push_back(ExpressionToken("||", GRN_OP_OR)); + rest += 2; + rest_size -= 2; + } else { +// tokens_.push_back(ExpressionToken("|", GRN_OP_BITWISE_OR)); +// ++rest; +// --rest_size; + return GRN_INVALID_ARGUMENT; + } + break; + } +// case '^': { +// tokens_.push_back(ExpressionToken("^", GRN_OP_BITWISE_XOR)); +// rest = rest.substring(1); +// break; +// } +// case '+': { +// tokens_.push_back(ExpressionToken("+", GRN_OP_PLUS)); +// rest = rest.substring(1); +// break; +// } +// case '-': { +// tokens_.push_back(ExpressionToken("-", GRN_OP_MINUS)); +// rest = rest.substring(1); +// break; +// } +// case '*': { +// tokens_.push_back(ExpressionToken("*", GRN_OP_MULTIPLICATION)); +// rest = rest.substring(1); +// break; +// } +// case '/': { +// tokens_.push_back(ExpressionToken("/", GRN_OP_DIVISION)); +// rest = rest.substring(1); +// break; +// } +// case '%': { +// tokens_.push_back(ExpressionToken("%", GRN_OP_MODULUS)); +// rest = rest.substring(1); +// break; +// } +// case '@': { +// if ((rest_size >= 2) && (rest[1] == '^')) { +// tokens_.push_back(ExpressionToken("@^", GRN_OP_STARTS_WITH)); +// rest = rest.substring(2); +// } else if ((rest_size >= 2) && (rest[1] == '$')) { +// tokens_.push_back(ExpressionToken("@$", GRN_OP_ENDS_WITH)); +// rest = rest.substring(2); +// } else { +// tokens_.push_back(ExpressionToken("@", GRN_OP_CONTAINS)); +// rest = rest.substring(1); +// } +// break; +// } +// case '.': { +// tokens_.push_back(ExpressionToken(".", DEREFERENCE_TOKEN)); +// rest = rest.substring(1); +// break; +// } + case '(': { + tokens_.push_back(ExpressionToken("(", LEFT_ROUND_BRACKET)); + ++rest; + --rest_size; + break; + } + case ')': { + tokens_.push_back(ExpressionToken(")", RIGHT_ROUND_BRACKET)); + ++rest; + --rest_size; + break; + } +// case '[': { +// tokens_.push_back(ExpressionToken("[", LEFT_SQUARE_BRACKET)); +// rest = rest.substring(1); +// break; +// } +// case ']': { +// tokens_.push_back(ExpressionToken("]", RIGHT_SQUARE_BRACKET)); +// rest = rest.substring(1); +// break; +// } + case '"': { + for (pos = 1; pos < rest_size; ++pos) { + if (rest[pos] == '\\') { + if (pos == rest_size) { + break; + } + ++pos; + } else if (rest[pos] == '"') { + break; + } + } + if (pos == rest_size) { + return GRN_INVALID_ARGUMENT; + } + tokens_.push_back( + ExpressionToken(std::string(rest + 1, pos - 1), CONSTANT_TOKEN)); + rest += pos + 1; + rest_size -= pos + 1; + break; + } + case '0' ... '9': { + // TODO: Improve this. + for (pos = 1; pos < rest_size; ++pos) { + if (!std::isdigit(static_cast<uint8_t>(rest[pos]))) { + break; + } + } + tokens_.push_back( + ExpressionToken(std::string(rest, pos), CONSTANT_TOKEN)); + rest += pos; + rest_size -= pos; + break; + } + case '_': + case 'A' ... 'Z': + case 'a' ... 'z': { + // TODO: Improve this. + for (pos = 1; pos < rest_size; ++pos) { + if ((rest[pos] != '_') && (!std::isalnum(rest[pos]))) { + break; + } + } + std::string token(rest, pos); + if ((token == "true") || (token == "false")) { + tokens_.push_back(ExpressionToken(token, CONSTANT_TOKEN)); + } else { + tokens_.push_back(ExpressionToken(token, NAME_TOKEN)); + } + rest += pos; + rest_size -= pos; + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + } + return GRN_SUCCESS; +} + +grn_rc ExpressionParser::compose() { + if (tokens_.size() == 0) { + return GRN_INVALID_ARGUMENT; + } + expression_ = new (std::nothrow) Expression(ctx_, table_); + grn_rc rc = push_token(ExpressionToken("(", LEFT_ROUND_BRACKET)); + if (rc == GRN_SUCCESS) { + for (size_t i = 0; i < tokens_.size(); ++i) { + rc = push_token(tokens_[i]); + if (rc != GRN_SUCCESS) { + break; + } + } + if (rc == GRN_SUCCESS) { + rc = push_token(ExpressionToken(")", RIGHT_ROUND_BRACKET)); + } + } + return rc; +} + +grn_rc ExpressionParser::push_token(const ExpressionToken &token) { + grn_rc rc = GRN_SUCCESS; + switch (token.type()) { + case DUMMY_TOKEN: { + if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) { + return GRN_INVALID_ARGUMENT; + } + stack_.push_back(token); + break; + } + case CONSTANT_TOKEN: { + grn_obj obj; + const std::string string = token.string(); + if (std::isdigit(static_cast<uint8_t>(string[0]))) { + if (string.find_first_of('.') == string.npos) { + GRN_INT64_INIT(&obj, 0); + GRN_INT64_SET(ctx_, &obj, strtoll(string.c_str(), NULL, 10)); + } else { + GRN_FLOAT_INIT(&obj, 0); + GRN_FLOAT_SET(ctx_, &obj, strtod(string.c_str(), NULL)); + } + } else if (string == "true") { + GRN_BOOL_INIT(&obj, 0); + GRN_BOOL_SET(ctx_, &obj, GRN_TRUE); + } else if (string == "false") { + GRN_BOOL_INIT(&obj, 0); + GRN_BOOL_SET(ctx_, &obj, GRN_FALSE); + } else { + GRN_TEXT_INIT(&obj, 0); + GRN_TEXT_SET(ctx_, &obj, string.data(), string.size()); + } + rc = push_token(ExpressionToken(string, DUMMY_TOKEN)); + if (rc == GRN_SUCCESS) { + rc = expression_->push_object(&obj); + } + GRN_OBJ_FIN(ctx_, &obj); + break; + } + case NAME_TOKEN: { + rc = push_token(ExpressionToken(token.string(), DUMMY_TOKEN)); + if (rc == GRN_SUCCESS) { + grn_obj *column = grn_obj_column( + ctx_, table_, token.string().data(), token.string().size()); + rc = expression_->push_object(column); + } + break; + } + case UNARY_OPERATOR_TOKEN: { + if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) { + // A unary operator must not follow an operand. + return GRN_INVALID_ARGUMENT; + } + stack_.push_back(token); + break; + } + case BINARY_OPERATOR_TOKEN: { + if ((stack_.size() == 0) || (stack_.back().type() != DUMMY_TOKEN)) { + // A binary operator must follow an operand. + return GRN_INVALID_ARGUMENT; + } + // Apply previous operators if those are prior to the new operator. + while (stack_.size() >= 2) { + ExpressionToken operator_token = stack_[stack_.size() - 2]; +// if (operator_token.type() == DEREFERENCE_TOKEN) { +// expression_->end_subexpression(); +// stack_.pop_back(); +// stack_.pop_back(); +// push_token(ExpressionToken("", DUMMY_TOKEN)); +// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) { + if (operator_token.type() == UNARY_OPERATOR_TOKEN) { + rc = expression_->push_operator(operator_token.operator_type()); + if (rc == GRN_SUCCESS) { + stack_.pop_back(); + stack_.pop_back(); + rc = push_token(ExpressionToken("", DUMMY_TOKEN)); + } + } else if ((operator_token.type() == BINARY_OPERATOR_TOKEN) && + (operator_token.priority() <= token.priority())) { + rc = expression_->push_operator(operator_token.operator_type()); + if (rc == GRN_SUCCESS) { + stack_.pop_back(); + stack_.pop_back(); + stack_.pop_back(); + rc = push_token(ExpressionToken("", DUMMY_TOKEN)); + } + } else { + break; + } + if (rc != GRN_SUCCESS) { + return rc; + } + } + stack_.push_back(token); + break; + } +// case DEREFERENCE_TOKEN: { +// builder_->begin_subexpression(); +// stack_.pop_back(); +// stack_.push_back(token); +// break; +// } + case BRACKET_TOKEN: { + if (token.bracket_type() == LEFT_ROUND_BRACKET) { + // A left round bracket must not follow a dummy. + if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) { + return GRN_INVALID_ARGUMENT; + } + stack_.push_back(token); + } else if (token.bracket_type() == RIGHT_ROUND_BRACKET) { + // A right round bracket must follow a dummy. + // A left round bracket must exist before a right round bracket. + if ((stack_.size() < 2) || (stack_.back().type() != DUMMY_TOKEN)) { + return GRN_INVALID_ARGUMENT; + } + // Apply operators in brackets. + while (stack_.size() >= 2) { + ExpressionToken operator_token = stack_[stack_.size() - 2]; +// if (operator_token.type() == DEREFERENCE_TOKEN) { +// rc = expression_->end_subexpression(); +// if (rc == GRN_SUCCESS) { +// stack_.pop_back(); +// stack_.pop_back(); +// rc = push_token(ExpressionToken("", DUMMY_TOKEN)); +// } +// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) { + if (operator_token.type() == UNARY_OPERATOR_TOKEN) { + rc = expression_->push_operator(operator_token.operator_type()); + if (rc == GRN_SUCCESS) { + stack_.pop_back(); + stack_.pop_back(); + rc = push_token(ExpressionToken("", DUMMY_TOKEN)); + } + } else if (operator_token.type() == BINARY_OPERATOR_TOKEN) { + rc = expression_->push_operator(operator_token.operator_type()); + if (rc == GRN_SUCCESS) { + stack_.pop_back(); + stack_.pop_back(); + stack_.pop_back(); + rc = push_token(ExpressionToken("", DUMMY_TOKEN)); + } + } else { + break; + } + if (rc != GRN_SUCCESS) { + return rc; + } + } + if ((stack_.size() < 2) || + (stack_[stack_.size() - 2].type() != BRACKET_TOKEN) || + (stack_[stack_.size() - 2].bracket_type() != LEFT_ROUND_BRACKET)) { + return GRN_INVALID_ARGUMENT; + } + stack_[stack_.size() - 2] = stack_.back(); + stack_.pop_back(); +// } else if (token.bracket_type() == LEFT_SQUARE_BRACKET) { +// // A left square bracket must follow a dummy. +// if ((stack_.size() == 0) || (stack_.back().type() != DUMMY_TOKEN)) { +// return GRN_INVALID_ARGUMENT; +// } +// stack_.push_back(token); +// } else if (token.bracket_type() == RIGHT_SQUARE_BRACKET) { +// // A right round bracket must follow a dummy. +// // A left round bracket must exist before a right round bracket. +// if ((stack_.size() < 2) || (stack_.back().type() != DUMMY_TOKEN)) { +// return GRN_INVALID_ARGUMENT; +// } +// // Apply operators in bracket. +// while (stack_.size() >= 2) { +// ExpressionToken operator_token = stack_[stack_.size() - 2]; +// if (operator_token.type() == DEREFERENCE_TOKEN) { +// builder_->end_subexpression(); +// stack_.pop_back(); +// stack_.pop_back(); +// push_token(ExpressionToken("", DUMMY_TOKEN)); +// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) { +// builder_->push_operator(operator_token.operator_type()); +// stack_.pop_back(); +// stack_.pop_back(); +// push_token(ExpressionToken("", DUMMY_TOKEN)); +// } else if (operator_token.type() == BINARY_OPERATOR_TOKEN) { +// builder_->push_operator(operator_token.operator_type()); +// stack_.pop_back(); +// stack_.pop_back(); +// stack_.pop_back(); +// push_token(ExpressionToken("", DUMMY_TOKEN)); +// } else { +// break; +// } +// } +// if ((stack_.size() < 2) || +// (stack_[stack_.size() - 2].type() != BRACKET_TOKEN) || +// (stack_[stack_.size() - 2].bracket_type() != LEFT_SQUARE_BRACKET)) { +// return GRN_INVALID_ARGUMENT; +// } +// stack_.pop_back(); +// stack_.pop_back(); +// builder_->push_operator(GRNXX_SUBSCRIPT); + } else { + return GRN_INVALID_ARGUMENT; + } + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + return rc; +} + +// -- Expression -- + +Expression::Expression(grn_ctx *ctx, grn_obj *table) + : ctx_(ctx), table_(table), type_(GRN_EGN_INCOMPLETE), + data_type_(GRN_DB_VOID), stack_() {} + +Expression::~Expression() { + for (size_t i = 0; i < stack_.size(); ++i) { + delete stack_[i]; + } +} + +grn_rc Expression::open( + grn_ctx *ctx, grn_obj *table, Expression **expression) { + if (!ctx || !grn_egn_is_table(table) || !expression) { + return GRN_INVALID_ARGUMENT; + } + Expression *new_expression = new (std::nothrow) Expression(ctx, table); + if (!new_expression) { + return GRN_NO_MEMORY_AVAILABLE; + } + *expression = new_expression; + return GRN_SUCCESS; +} + +grn_rc Expression::parse(grn_ctx *ctx, grn_obj *table, + const char *query, size_t query_size, Expression **expression) { + if (!ctx || !grn_egn_is_table(table) || + !query || (query_size == 0) || !expression) { + return GRN_INVALID_ARGUMENT; + } + return ExpressionParser::parse(ctx, table, query, query_size, expression); +} + +grn_rc Expression::push_object(grn_obj *obj) { + if (!obj) { + return GRN_INVALID_ARGUMENT; + } + grn_rc rc = GRN_UNKNOWN_ERROR; + switch (obj->header.type) { + case GRN_BULK: { + rc = push_bulk_object(obj); + break; + } + case GRN_UVECTOR: { + // FIXME: To be supported. + return GRN_INVALID_ARGUMENT; + } + case GRN_VECTOR: { + // FIXME: To be supported. + return GRN_INVALID_ARGUMENT; + } + case GRN_ACCESSOR: { + grn_accessor *accessor = (grn_accessor *)obj; + switch (accessor->action) { + case GRN_ACCESSOR_GET_ID: { + ExpressionNode *node; + rc = IDNode::open(&node); + if (rc == GRN_SUCCESS) try { + stack_.push_back(node); + } catch (const std::bad_alloc &) { + delete node; + return GRN_NO_MEMORY_AVAILABLE; + } + break; + } + case GRN_ACCESSOR_GET_KEY: { + // TODO: KeyNode should be provided for performance. + ExpressionNode *node; + grn_id range = grn_obj_get_range(ctx_, obj); + switch (range) { + case GRN_DB_BOOL: { + rc = ColumnNode<Bool>::open(ctx_, obj, &node); + break; + } + case GRN_DB_INT8: + case GRN_DB_INT16: + case GRN_DB_INT32: + case GRN_DB_INT64: + case GRN_DB_UINT8: + case GRN_DB_UINT16: + case GRN_DB_UINT32: + case GRN_DB_UINT64: { + rc = ColumnNode<Int>::open(ctx_, obj, &node); + break; + } + case GRN_DB_FLOAT: { + rc = ColumnNode<Float>::open(ctx_, obj, &node); + break; + } + case GRN_DB_TIME: { + rc = ColumnNode<Time>::open(ctx_, obj, &node); + break; + } + case GRN_DB_TOKYO_GEO_POINT: + case GRN_DB_WGS84_GEO_POINT: { + rc = ColumnNode<GeoPoint>::open(ctx_, obj, &node); + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + if (rc == GRN_SUCCESS) try { + stack_.push_back(node); + } catch (const std::bad_alloc &) { + delete node; + return GRN_NO_MEMORY_AVAILABLE; + } + break; + } + case GRN_ACCESSOR_GET_VALUE: { + // TODO + return GRN_INVALID_ARGUMENT; + } + case GRN_ACCESSOR_GET_SCORE: { + ExpressionNode *node; + rc = ScoreNode::open(&node); + if (rc == GRN_SUCCESS) try { + stack_.push_back(node); + } catch (const std::bad_alloc &) { + delete node; + return GRN_NO_MEMORY_AVAILABLE; + } + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + break; + } + case GRN_COLUMN_FIX_SIZE: + case GRN_COLUMN_VAR_SIZE: { + rc = push_column_object(obj); + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + if (rc == GRN_SUCCESS) { + update_types(); + } + return rc; +} + +grn_rc Expression::push_operator(OperatorType operator_type) { + grn_rc rc = GRN_UNKNOWN_ERROR; + ExpressionNode *node; + switch (operator_type) { + case GRN_OP_NOT: { + if (stack_.size() < 1) { + return GRN_INVALID_FORMAT; + } + ExpressionNode *arg = stack_[stack_.size() - 1]; + rc = create_unary_node(operator_type, arg, &node); + if (rc == GRN_SUCCESS) { + stack_.resize(stack_.size() - 1); + } + break; + } + case GRN_OP_AND: + case GRN_OP_OR: + case GRN_OP_EQUAL: + case GRN_OP_NOT_EQUAL: + case GRN_OP_LESS: + case GRN_OP_LESS_EQUAL: + case GRN_OP_GREATER: + case GRN_OP_GREATER_EQUAL: { + if (stack_.size() < 2) { + return GRN_INVALID_FORMAT; + } + ExpressionNode *arg1 = stack_[stack_.size() - 2]; + ExpressionNode *arg2 = stack_[stack_.size() - 1]; + rc = create_binary_node(operator_type, arg1, arg2, &node); + if (rc == GRN_SUCCESS) { + stack_.resize(stack_.size() - 2); + } + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + if (rc == GRN_SUCCESS) { + stack_.push_back(node); + update_types(); + } + return rc; +} + +grn_rc Expression::filter( + Record *input, size_t input_size, + Record *output, size_t *output_size) { + if ((!input && (input_size != 0)) || + ((output > input) && (output < (input + input_size))) || !output_size) { + return GRN_INVALID_ARGUMENT; + } + ExpressionNode *root = this->root(); + if (!root) { + return GRN_UNKNOWN_ERROR; + } + if (!output) { + output = input; + } + size_t total_output_size = 0; + while (input_size > 0) { + size_t batch_input_size = GRN_EGN_MAX_BATCH_SIZE; + if (input_size < batch_input_size) { + batch_input_size = input_size; + } + size_t batch_output_size; + grn_rc rc = root->filter( + input, batch_input_size, output, &batch_output_size); + if (rc != GRN_SUCCESS) { + return rc; + } + input += batch_input_size; + input_size -= batch_input_size; + output += batch_output_size; + total_output_size += batch_output_size; + } + *output_size = total_output_size; + return GRN_SUCCESS; +} + +grn_rc Expression::adjust(Record *records, size_t num_records) { + if (!records && (num_records != 0)) { + return GRN_INVALID_ARGUMENT; + } + ExpressionNode *root = this->root(); + if (!root) { + return GRN_UNKNOWN_ERROR; + } + while (num_records > 0) { + size_t batch_size = GRN_EGN_MAX_BATCH_SIZE; + if (num_records < batch_size) { + batch_size = num_records; + } + grn_rc rc = root->adjust(records, batch_size); + if (rc != GRN_SUCCESS) { + return rc; + } + records += batch_size; + num_records -= batch_size; + } + return GRN_SUCCESS; +} + +template <typename T> +grn_rc Expression::evaluate( + const Record *records, size_t num_records, T *results) { + if (((!records || !results) && (num_records != 0)) || + (T::data_type() != data_type())) { + return GRN_INVALID_ARGUMENT; + } + ExpressionNode *root = this->root(); + if (!root) { + return GRN_UNKNOWN_ERROR; + } + // FIXME: Records should be processed per block. + // However, the contents of old blocks will be lost. + return static_cast<TypedNode<T> *>(root)->evaluate( + records, num_records, results); +} + +template grn_rc Expression::evaluate( + const Record *records, size_t num_records, Bool *results); +template grn_rc Expression::evaluate( + const Record *records, size_t num_records, Int *results); +template grn_rc Expression::evaluate( + const Record *records, size_t num_records, Float *results); +template grn_rc Expression::evaluate( + const Record *records, size_t num_records, Time *results); +template grn_rc Expression::evaluate( + const Record *records, size_t num_records, Text *results); +template grn_rc Expression::evaluate( + const Record *records, size_t num_records, GeoPoint *results); + +ExpressionNode *Expression::root() const { + if (stack_.size() != 1) { + return NULL; + } + return stack_.front(); +} + +void Expression::update_types() { + ExpressionNode *root = this->root(); + if (!root) { + type_ = GRN_EGN_INCOMPLETE; + data_type_ = GRN_DB_VOID; + } else { + switch (root->type()) { + case GRN_EGN_ID_NODE: { + type_ = GRN_EGN_ID; + break; + } + case GRN_EGN_SCORE_NODE: { + type_ = GRN_EGN_SCORE; + break; + } + case GRN_EGN_CONSTANT_NODE: { + type_ = GRN_EGN_CONSTANT; + break; + } + case GRN_EGN_COLUMN_NODE: + case GRN_EGN_OPERATOR_NODE: { + type_ = GRN_EGN_VARIABLE; + break; + } + default: { + type_ = GRN_EGN_INCOMPLETE; + break; + } + } + data_type_ = root->data_type(); + } +} + +grn_rc Expression::push_bulk_object(grn_obj *obj) { + grn_rc rc; + ExpressionNode *node; + switch (obj->header.domain) { + case GRN_DB_BOOL: { + rc = ConstantNode<Bool>::open(Bool(GRN_BOOL_VALUE(obj)), &node); + break; + } + case GRN_DB_INT8: { + rc = ConstantNode<Int>::open(Int(GRN_INT8_VALUE(obj)), &node); + break; + } + case GRN_DB_INT16: { + rc = ConstantNode<Int>::open(Int(GRN_INT16_VALUE(obj)), &node); + break; + } + case GRN_DB_INT32: { + rc = ConstantNode<Int>::open(Int(GRN_INT32_VALUE(obj)), &node); + break; + } + case GRN_DB_INT64: { + rc = ConstantNode<Int>::open(Int(GRN_INT64_VALUE(obj)), &node); + break; + } + case GRN_DB_UINT8: { + rc = ConstantNode<Int>::open(Int(GRN_UINT8_VALUE(obj)), &node); + break; + } + case GRN_DB_UINT16: { + rc = ConstantNode<Int>::open(Int(GRN_UINT16_VALUE(obj)), &node); + break; + } + case GRN_DB_UINT32: { + rc = ConstantNode<Int>::open(Int(GRN_UINT32_VALUE(obj)), &node); + break; + } + case GRN_DB_UINT64: { + // FIXME: Type conversion from UInt64 to Int may lose the content. + rc = ConstantNode<Int>::open(Int(GRN_UINT64_VALUE(obj)), &node); + break; + } + case GRN_DB_FLOAT: { + rc = ConstantNode<Float>::open(Float(GRN_FLOAT_VALUE(obj)), &node); + break; + } + case GRN_DB_TIME: { + rc = ConstantNode<Time>::open(Time(GRN_TIME_VALUE(obj)), &node); + break; + } + case GRN_DB_SHORT_TEXT: + case GRN_DB_TEXT: + case GRN_DB_LONG_TEXT: { + Text value(GRN_TEXT_VALUE(obj), GRN_TEXT_LEN(obj)); + rc = ConstantNode<Text>::open(value, &node); + break; + } + // TODO: TokyoGeoPoint and Wgs84GeoPoint should be provided? + case GRN_DB_TOKYO_GEO_POINT: + case GRN_DB_WGS84_GEO_POINT: { + GeoPoint value; + GRN_GEO_POINT_VALUE(obj, value.raw.latitude, value.raw.longitude); + rc = ConstantNode<GeoPoint>::open(value, &node); + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + if (rc == GRN_SUCCESS) try { + stack_.push_back(node); + } catch (const std::bad_alloc &) { + delete node; + return GRN_NO_MEMORY_AVAILABLE; + } + return rc; +} + +grn_rc Expression::push_column_object(grn_obj *obj) { + grn_obj *owner_table = grn_column_table(ctx_, obj); + if (owner_table != table_) { + return GRN_INVALID_ARGUMENT; + } + grn_id range = grn_obj_get_range(ctx_, obj); + grn_rc rc; + ExpressionNode *node; + switch (obj->header.type) { + case GRN_COLUMN_FIX_SIZE: { + switch (range) { + case GRN_DB_BOOL: { + rc = ColumnNode<Bool>::open(ctx_, obj, &node); + break; + } + case GRN_DB_INT8: + case GRN_DB_INT16: + case GRN_DB_INT32: + case GRN_DB_INT64: + case GRN_DB_UINT8: + case GRN_DB_UINT16: + case GRN_DB_UINT32: + case GRN_DB_UINT64: { + rc = ColumnNode<Int>::open(ctx_, obj, &node); + break; + } + case GRN_DB_FLOAT: { + rc = ColumnNode<Float>::open(ctx_, obj, &node); + break; + } + case GRN_DB_TIME: { + rc = ColumnNode<Time>::open(ctx_, obj, &node); + break; + } + case GRN_DB_TOKYO_GEO_POINT: + case GRN_DB_WGS84_GEO_POINT: { + rc = ColumnNode<GeoPoint>::open(ctx_, obj, &node); + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + break; + } + case GRN_COLUMN_VAR_SIZE: { + grn_obj_flags column_type = obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK; + switch (column_type) { + case GRN_OBJ_COLUMN_SCALAR: { + switch (range) { + case GRN_DB_SHORT_TEXT: + case GRN_DB_TEXT: + case GRN_DB_LONG_TEXT: { + rc = ColumnNode<Text>::open(ctx_, obj, &node); + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + break; + } + break; + } + case GRN_OBJ_COLUMN_VECTOR: { + return GRN_OPERATION_NOT_SUPPORTED; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + if (rc == GRN_SUCCESS) try { + stack_.push_back(node); + } catch (const std::bad_alloc &) { + delete node; + return GRN_NO_MEMORY_AVAILABLE; + } + return rc; +} + +grn_rc Expression::create_unary_node(OperatorType operator_type, + ExpressionNode *arg, ExpressionNode **node) { + grn_rc rc = GRN_SUCCESS; + switch (operator_type) { + case GRN_OP_NOT: { + if (arg->data_type() != GRN_DB_BOOL) { + return GRN_UNKNOWN_ERROR; + } + rc = LogicalNotNode::open(arg, node); + break; + } + default: { + return GRN_INVALID_ARGUMENT; + } + } + return rc; +} + +grn_rc Expression::create_binary_node(OperatorType operator_type, + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) { + switch (operator_type) { + case GRN_OP_AND: { + if ((arg1->data_type() != GRN_DB_BOOL) || + (arg1->data_type() != GRN_DB_BOOL)) { + return GRN_INVALID_FORMAT; + } + return LogicalAndNode::open(arg1, arg2, node); + } + case GRN_OP_OR: { + if ((arg1->data_type() != GRN_DB_BOOL) || + (arg1->data_type() != GRN_DB_BOOL)) { + return GRN_INVALID_FORMAT; + } + return LogicalOrNode::open(arg1, arg2, node); + } + case GRN_OP_EQUAL: { + if (arg1->data_type() != arg2->data_type()) { + return GRN_INVALID_FORMAT; + } + switch (arg1->data_type()) { + case GRN_DB_BOOL: { + return equal_node_open(EqualOperator<Bool>(), arg1, arg2, node); + } + case GRN_DB_INT64: { + return equal_node_open(EqualOperator<Int>(), arg1, arg2, node); + } + case GRN_DB_FLOAT: { + return equal_node_open(EqualOperator<Float>(), arg1, arg2, node); + } + case GRN_DB_TIME: { + return equal_node_open(EqualOperator<Time>(), arg1, arg2, node); + } + case GRN_DB_TEXT: { + return equal_node_open(EqualOperator<Text>(), arg1, arg2, node); + } + case GRN_DB_WGS84_GEO_POINT: { + return equal_node_open(EqualOperator<GeoPoint>(), arg1, arg2, node); + } + default: { + return GRN_UNKNOWN_ERROR; + } + } + } + case GRN_OP_NOT_EQUAL: { + if (arg1->data_type() != arg2->data_type()) { + return GRN_INVALID_FORMAT; + } + switch (arg1->data_type()) { + case GRN_DB_BOOL: { + return not_equal_node_open( + NotEqualOperator<Bool>(), arg1, arg2, node); + } + case GRN_DB_INT64: { + return not_equal_node_open( + NotEqualOperator<Int>(), arg1, arg2, node); + } + case GRN_DB_FLOAT: { + return not_equal_node_open( + NotEqualOperator<Float>(), arg1, arg2, node); + } + case GRN_DB_TIME: { + return not_equal_node_open( + NotEqualOperator<Time>(), arg1, arg2, node); + } + case GRN_DB_TEXT: { + return not_equal_node_open( + NotEqualOperator<Text>(), arg1, arg2, node); + } + case GRN_DB_WGS84_GEO_POINT: { + return not_equal_node_open( + NotEqualOperator<GeoPoint>(), arg1, arg2, node); + } + default: { + return GRN_UNKNOWN_ERROR; + } + } + } + case GRN_OP_LESS: { + if (arg1->data_type() != arg2->data_type()) { + return GRN_INVALID_FORMAT; + } + switch (arg1->data_type()) { + case GRN_DB_INT64: { + return less_node_open(LessOperator<Int>(), arg1, arg2, node); + } + case GRN_DB_FLOAT: { + return less_node_open(LessOperator<Float>(), arg1, arg2, node); + } + case GRN_DB_TIME: { + return less_node_open(LessOperator<Time>(), arg1, arg2, node); + } + case GRN_DB_TEXT: { + return less_node_open(LessOperator<Text>(), arg1, arg2, node); + } + default: { + return GRN_UNKNOWN_ERROR; + } + } + } + case GRN_OP_LESS_EQUAL: { + if (arg1->data_type() != arg2->data_type()) { + return GRN_INVALID_FORMAT; + } + switch (arg1->data_type()) { + case GRN_DB_INT64: { + return less_equal_node_open( + LessEqualOperator<Int>(), arg1, arg2, node); + } + case GRN_DB_FLOAT: { + return less_equal_node_open( + LessEqualOperator<Float>(), arg1, arg2, node); + } + case GRN_DB_TIME: { + return less_equal_node_open( + LessEqualOperator<Time>(), arg1, arg2, node); + } + case GRN_DB_TEXT: { + return less_equal_node_open( + LessEqualOperator<Text>(), arg1, arg2, node); + } + default: { + return GRN_UNKNOWN_ERROR; + } + } + } + case GRN_OP_GREATER: { + if (arg1->data_type() != arg2->data_type()) { + return GRN_INVALID_FORMAT; + } + switch (arg1->data_type()) { + case GRN_DB_INT64: { + return greater_node_open(GreaterOperator<Int>(), arg1, arg2, node); + } + case GRN_DB_FLOAT: { + return greater_node_open(GreaterOperator<Float>(), arg1, arg2, node); + } + case GRN_DB_TIME: { + return greater_node_open(GreaterOperator<Time>(), arg1, arg2, node); + } + case GRN_DB_TEXT: { + return greater_node_open(GreaterOperator<Text>(), arg1, arg2, node); + } + default: { + return GRN_UNKNOWN_ERROR; + } + } + } + case GRN_OP_GREATER_EQUAL: { + if (arg1->data_type() != arg2->data_type()) { + return GRN_INVALID_FORMAT; + } + switch (arg1->data_type()) { + case GRN_DB_INT64: { + return greater_equal_node_open( + GreaterEqualOperator<Int>(), arg1, arg2, node); + } + case GRN_DB_FLOAT: { + return greater_equal_node_open( + GreaterEqualOperator<Float>(), arg1, arg2, node); + } + case GRN_DB_TIME: { + return greater_equal_node_open( + GreaterEqualOperator<Time>(), arg1, arg2, node); + } + case GRN_DB_TEXT: { + return greater_equal_node_open( + GreaterEqualOperator<Text>(), arg1, arg2, node); + } + default: { + return GRN_UNKNOWN_ERROR; + } + } + } + default: { + return GRN_INVALID_ARGUMENT; + } + } +} + +} // namespace egn +} // namespace grn + +#ifdef __cplusplus +extern "C" { +#endif + +static grn_rc +grn_egn_select_filter(grn_ctx *ctx, grn_obj *table, + const char *filter, size_t filter_size, + int offset, int limit, + std::vector<grn_egn_record> *records, + size_t *num_hits) { + if (offset < 0) { + offset = 0; + } + if (limit < 0) { + limit = std::numeric_limits<int>::max(); + } + grn::egn::Cursor *cursor; + grn_rc rc = grn::egn::Cursor::open_table_cursor(ctx, table, &cursor); + if (rc == GRN_SUCCESS) { + grn::egn::Expression *expression; + rc = grn::egn::Expression::parse( + ctx, table, filter, filter_size, &expression); + if (rc == GRN_SUCCESS) { + size_t count = 0; + for ( ; ; ) { + size_t records_offset = records->size(); + try { + records->resize(records->size() + GRN_EGN_MAX_BATCH_SIZE); + } catch (const std::bad_alloc &) { + rc = GRN_NO_MEMORY_AVAILABLE; + break; + } + size_t batch_size; + rc = cursor->read(&(*records)[records_offset], + GRN_EGN_MAX_BATCH_SIZE, &batch_size); + if (rc != GRN_SUCCESS) { + break; + } + if (batch_size == 0) { + records->resize(records_offset); + break; + } + rc = expression->filter(&(*records)[records_offset], batch_size, + NULL, &batch_size); + if (rc != GRN_SUCCESS) { + break; + } + count += batch_size; + if (offset > 0) { + if (offset >= batch_size) { + offset -= batch_size; + batch_size = 0; + } else { + std::memcpy(&(*records)[0], &(*records)[offset], + sizeof(grn_egn_record) * (batch_size - offset)); + batch_size -= offset; + offset = 0; + } + } + if (limit >= batch_size) { + limit -= batch_size; + } else { + batch_size = limit; + limit = 0; + } + records->resize(records_offset + batch_size); + } + delete expression; + *num_hits = count; + } + delete cursor; + } + return rc; +} + +static grn_rc +grn_egn_select_output(grn_ctx *ctx, grn_obj *table, + const char *output_columns, size_t output_columns_size, + const grn_egn_record *records, size_t num_records, + size_t num_hits) { + grn_rc rc = GRN_SUCCESS; + std::vector<std::string> names; + std::vector<grn::egn::Expression *> expressions; + + const char *rest = output_columns; + size_t rest_size = output_columns_size; + while (rest_size != 0) { + size_t pos; + for (pos = 0; pos < rest_size; ++pos) { + if ((rest[pos] != ',') && + !std::isspace(static_cast<unsigned char>(rest[pos]))) { + break; + } + } + if (pos >= rest_size) { + break; + } + rest += pos; + rest_size -= pos; + for (pos = 0; pos < rest_size; ++pos) { + if ((rest[pos] == ',') || + std::isspace(static_cast<unsigned char>(rest[pos]))) { + break; + } + } + // TODO: Error handling. + std::string name(rest, pos); + if (name == "*") { + grn_hash *columns; + if ((columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, + GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY))) { + if (grn_table_columns(ctx, table, "", 0, (grn_obj *)columns)) { + grn_id *key; + GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, { + grn_obj *column = grn_ctx_at(ctx, *key); + if (column) { + char name_buf[1024]; + int name_size = grn_column_name( + ctx, column, name_buf, sizeof(name_buf)); + grn::egn::Expression *expression; + grn_rc r = grn::egn::Expression::open(ctx, table, &expression); + if (r == GRN_SUCCESS) { + r = expression->push_object(column); + if (r == GRN_SUCCESS) { + names.push_back(std::string(name_buf, name_size)); + expressions.push_back(expression); + } + } + } + }); + } + grn_hash_close(ctx, columns); + } + } else { + grn::egn::Expression *expression; + grn_rc r = grn::egn::Expression::parse( + ctx, table, rest, pos, &expression); + if (r == GRN_SUCCESS) { + names.push_back(name); + expressions.push_back(expression); + } + } + if (pos >= rest_size) { + break; + } + rest += pos + 1; + rest_size -= pos + 1; + } + + GRN_OUTPUT_ARRAY_OPEN("RESULT", 1); + GRN_OUTPUT_ARRAY_OPEN("RESULTSET", 2 + num_records); + GRN_OUTPUT_ARRAY_OPEN("NHITS", 1); + grn_text_ulltoa(ctx, ctx->impl->outbuf, num_hits); + GRN_OUTPUT_ARRAY_CLOSE(); // NHITS. + GRN_OUTPUT_ARRAY_OPEN("COLUMNS", expressions.size()); + for (size_t i = 0; i < expressions.size(); ++i) { + GRN_OUTPUT_ARRAY_OPEN("COLUMN", 2); + GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"'); + GRN_TEXT_PUT(ctx, ctx->impl->outbuf, names[i].data(), names[i].size()); + GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "\",\"", 3); + switch (expressions[i]->data_type()) { + case GRN_DB_BOOL: { + GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Bool"); + break; + } + case GRN_DB_INT64: { + GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Int64"); + break; + } + case GRN_DB_FLOAT: { + GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Float"); + break; + } + case GRN_DB_TIME: { + GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Time"); + break; + } + case GRN_DB_SHORT_TEXT: + case GRN_DB_TEXT: + case GRN_DB_LONG_TEXT: { + GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Text"); + break; + } + case GRN_DB_WGS84_GEO_POINT: { + GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "GeoPoint"); + break; + } + default: { + GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "N/A"); + break; + } + } + GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"'); + GRN_OUTPUT_ARRAY_CLOSE(); + } + GRN_OUTPUT_ARRAY_CLOSE(); // COLUMNS. + if (num_records != 0) { + size_t count = 0; + std::vector<std::vector<char> > bufs(expressions.size()); + while (count < num_records) { + size_t batch_size = GRN_EGN_MAX_BATCH_SIZE; + if (batch_size > (num_records - count)) { + batch_size = num_records - count; + } + for (size_t i = 0; i < expressions.size(); ++i) { + switch (expressions[i]->data_type()) { + case GRN_DB_BOOL: { + bufs[i].resize(sizeof(grn_egn_bool) * batch_size); + expressions[i]->evaluate(records + count, batch_size, + (grn::egn::Bool *)&bufs[i][0]); + break; + } + case GRN_DB_INT64: { + bufs[i].resize(sizeof(grn_egn_int) * batch_size); + expressions[i]->evaluate(records + count, batch_size, + (grn::egn::Int *)&bufs[i][0]); + break; + } + case GRN_DB_FLOAT: { + bufs[i].resize(sizeof(grn_egn_float) * batch_size); + expressions[i]->evaluate(records + count, batch_size, + (grn::egn::Float *)&bufs[i][0]); + break; + } + case GRN_DB_TIME: { + bufs[i].resize(sizeof(grn_egn_time) * batch_size); + expressions[i]->evaluate(records + count, batch_size, + (grn::egn::Time *)&bufs[i][0]); + break; + } + case GRN_DB_TEXT: { + bufs[i].resize(sizeof(grn_egn_text) * batch_size); + expressions[i]->evaluate(records + count, batch_size, + (grn::egn::Text *)&bufs[i][0]); + break; + } + case GRN_DB_WGS84_GEO_POINT: { + bufs[i].resize(sizeof(grn_egn_geo_point) * batch_size); + expressions[i]->evaluate(records + count, batch_size, + (grn::egn::GeoPoint *)&bufs[i][0]); + break; + } + default: { + break; + } + } + } + for (size_t i = 0; i < batch_size; ++i) { + GRN_OUTPUT_ARRAY_OPEN("HIT", expressions.size()); + for (size_t j = 0; j < expressions.size(); ++j) { + if (j != 0) { + GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, ','); + } + switch (expressions[j]->data_type()) { + case GRN_DB_BOOL: { + if (((grn_egn_bool *)&bufs[j][0])[i]) { + GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "true", 4); + } else { + GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "false", 5); + } + break; + } + case GRN_DB_INT64: { + grn_text_lltoa(ctx, ctx->impl->outbuf, + ((grn_egn_int *)&bufs[j][0])[i]); + break; + } + case GRN_DB_FLOAT: { + grn_text_ftoa(ctx, ctx->impl->outbuf, + ((grn_egn_float *)&bufs[j][0])[i]); + break; + } + case GRN_DB_TIME: { + grn_text_ftoa(ctx, ctx->impl->outbuf, + ((grn_egn_time *)&bufs[j][0])[i] * 0.000001); + break; + } + case GRN_DB_TEXT: { + grn_egn_text text = ((grn_egn_text *)&bufs[j][0])[i]; + grn_text_esc(ctx, ctx->impl->outbuf, text.ptr, text.size); + break; + } + case GRN_DB_WGS84_GEO_POINT: { + grn_egn_geo_point geo_point = + ((grn_egn_geo_point *)&bufs[j][0])[i]; + GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"'); + grn_text_itoa(ctx, ctx->impl->outbuf, geo_point.latitude); + GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, 'x'); + grn_text_itoa(ctx, ctx->impl->outbuf, geo_point.longitude); + GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"'); + break; + } + default: { + break; + } + } + } + GRN_OUTPUT_ARRAY_CLOSE(); // HITS. + } + count += batch_size; + } + } + GRN_OUTPUT_ARRAY_CLOSE(); // RESULTSET. + GRN_OUTPUT_ARRAY_CLOSE(); // RESET. + for (size_t i = 0; i < expressions.size(); ++i) { + delete expressions[i]; + } + return rc; +} + +grn_rc +grn_egn_select(grn_ctx *ctx, grn_obj *table, + const char *filter, size_t filter_size, + const char *output_columns, size_t output_columns_size, + int offset, int limit) { + if (!ctx || !grn_egn_is_table(table) || (!filter && (filter_size != 0)) || + (!output_columns && (output_columns_size != 0))) { + return GRN_INVALID_ARGUMENT; + } + std::vector<grn_egn_record> records; + size_t num_hits; + grn_rc rc = grn_egn_select_filter(ctx, table, filter, filter_size, + offset, limit, &records, &num_hits); + if (rc == GRN_SUCCESS) { + rc = grn_egn_select_output(ctx, table, output_columns, output_columns_size, + &*records.begin(), records.size(), num_hits); + } + return rc; +} + +#ifdef __cplusplus +} +#endif + +#endif // GRN_WITH_EGN diff --git a/storage/mroonga/vendor/groonga/lib/error.c b/storage/mroonga/vendor/groonga/lib/error.c index e14ef3754fd..561394231ea 100644 --- a/storage/mroonga/vendor/groonga/lib/error.c +++ b/storage/mroonga/vendor/groonga/lib/error.c @@ -62,3 +62,17 @@ grn_current_error_message(void) return strerror(errno); } #endif + +const char * +grn_strerror(int error_code) +{ +#ifdef WIN32 +# define MESSAGE_BUFFER_SIZE 1024 + static char message[MESSAGE_BUFFER_SIZE]; + strerror_s(message, MESSAGE_BUFFER_SIZE, error_code); + return message; +# undef MESSAGE_BUFFER_SIZE +#else /* WIN32 */ + return strerror(error_code); +#endif /* WIN32 */ +} diff --git a/storage/mroonga/vendor/groonga/lib/expr.c b/storage/mroonga/vendor/groonga/lib/expr.c index f13502a0f14..9ce1fa0adfc 100644 --- a/storage/mroonga/vendor/groonga/lib/expr.c +++ b/storage/mroonga/vendor/groonga/lib/expr.c @@ -22,6 +22,7 @@ #include "grn_ii.h" #include "grn_geo.h" #include "grn_expr.h" +#include "grn_expr_code.h" #include "grn_util.h" #include "grn_mrb.h" #include "mrb/mrb_expr.h" @@ -782,8 +783,9 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op, for (i = 0; i < nargs; i++) { int rest_n_codes = 1; while (rest_n_codes > 0) { - if (!code->value) { - rest_n_codes += code->nargs; + rest_n_codes += code->nargs; + if (code->value) { + rest_n_codes--; } rest_n_codes--; code--; @@ -1274,7 +1276,10 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller) } #define PUSH1(v) do {\ - if (EXPRVP(v)) { vp++; }\ + if (EXPRVP(v)) {\ + vp++;\ + if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\ + }\ s1 = s0;\ *sp++ = s0 = v;\ } while (0) @@ -1301,6 +1306,7 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller) } else {\ if (sp < s_ + 1) { ERR(GRN_INVALID_ARGUMENT, "stack underflow"); goto exit; }\ sp[-1] = s0 = value = vp++;\ + if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\ s0->header.impl_flags |= GRN_OBJ_EXPRVALUE;\ }\ } while (0) @@ -1314,6 +1320,7 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller) if (sp < s_ + 1) { ERR(GRN_INVALID_ARGUMENT, "stack underflow"); goto exit; }\ s1 = sp[-2];\ sp[-1] = s0 = value = vp++;\ + if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\ s0->header.impl_flags |= GRN_OBJ_EXPRVALUE;\ } while (0) @@ -2226,11 +2233,11 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller) } while (0) inline static void -grn_expr_exec_get_member(grn_ctx *ctx, - grn_obj *expr, - grn_obj *column_and_record_id, - grn_obj *index, - grn_obj *result) +grn_expr_exec_get_member_vector(grn_ctx *ctx, + grn_obj *expr, + grn_obj *column_and_record_id, + grn_obj *index, + grn_obj *result) { grn_obj *column; grn_id record_id; @@ -2268,6 +2275,34 @@ grn_expr_exec_get_member(grn_ctx *ctx, GRN_OBJ_FIN(ctx, &values); } +inline static void +grn_expr_exec_get_member_table(grn_ctx *ctx, + grn_obj *expr, + grn_obj *table, + grn_obj *key, + grn_obj *result) +{ + grn_id id; + + if (table->header.domain == key->header.domain) { + id = grn_table_get(ctx, table, GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key)); + } else { + grn_obj casted_key; + GRN_OBJ_INIT(&casted_key, GRN_BULK, 0, table->header.domain); + if (grn_obj_cast(ctx, key, &casted_key, GRN_FALSE) == GRN_SUCCESS) { + id = grn_table_get(ctx, table, + GRN_BULK_HEAD(&casted_key), + GRN_BULK_VSIZE(&casted_key)); + } else { + id = GRN_ID_NIL; + } + GRN_OBJ_FIN(ctx, &casted_key); + } + + grn_obj_reinit(ctx, result, DB_OBJ(table)->id, 0); + GRN_RECORD_SET(ctx, result, id); +} + static inline grn_bool grn_expr_exec_is_simple_expr(grn_ctx *ctx, grn_obj *expr) { @@ -3045,16 +3080,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_GEO_DISTANCE1 : { - grn_obj *e; + grn_obj *value; double lng1, lat1, lng2, lat2, x, y, d; - POP1(e); - lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1ALLOC1(e, res); - lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); + POP1(value); + lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1ALLOC1(value, res); + lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5); y = (lat2 - lat1); d = sqrt((x * x) + (y * y)) * GEO_RADIOUS; @@ -3066,16 +3101,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_GEO_DISTANCE2 : { - grn_obj *e; + grn_obj *value; double lng1, lat1, lng2, lat2, x, y, d; - POP1(e); - lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1ALLOC1(e, res); - lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); + POP1(value); + lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1ALLOC1(value, res); + lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); x = sin(fabs(lng2 - lng1) * 0.5); y = sin(fabs(lat2 - lat1) * 0.5); d = asin(sqrt((y * y) + cos(lat1) * cos(lat2) * x * x)) * 2 * GEO_RADIOUS; @@ -3087,16 +3122,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_GEO_DISTANCE3 : { - grn_obj *e; + grn_obj *value; double lng1, lat1, lng2, lat2, p, q, m, n, x, y, d; - POP1(e); - lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1ALLOC1(e, res); - lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); + POP1(value); + lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1ALLOC1(value, res); + lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); p = (lat1 + lat2) * 0.5; q = (1 - GEO_BES_C3 * sin(p) * sin(p)); m = GEO_BES_C1 / sqrt(q * q * q); @@ -3112,16 +3147,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_GEO_DISTANCE4 : { - grn_obj *e; + grn_obj *value; double lng1, lat1, lng2, lat2, p, q, m, n, x, y, d; - POP1(e); - lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1ALLOC1(e, res); - lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); + POP1(value); + lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1ALLOC1(value, res); + lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); p = (lat1 + lat2) * 0.5; q = (1 - GEO_GRS_C3 * sin(p) * sin(p)); m = GEO_GRS_C1 / sqrt(q * q * q); @@ -3138,26 +3173,26 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) case GRN_OP_GEO_WITHINP5 : { int r; - grn_obj *e; + grn_obj *value; double lng0, lat0, lng1, lat1, x, y, d; - POP1(e); - lng0 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lat0 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1ALLOC1(e, res); + POP1(value); + lng0 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lat0 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1ALLOC1(value, res); x = (lng1 - lng0) * cos((lat0 + lat1) * 0.5); y = (lat1 - lat0); d = sqrt((x * x) + (y * y)) * GEO_RADIOUS; - switch (e->header.domain) { + switch (value->header.domain) { case GRN_DB_INT32 : - r = d <= GRN_INT32_VALUE(e); + r = d <= GRN_INT32_VALUE(value); break; case GRN_DB_FLOAT : - r = d <= GRN_FLOAT_VALUE(e); + r = d <= GRN_FLOAT_VALUE(value); break; default : r = 0; @@ -3172,20 +3207,20 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) case GRN_OP_GEO_WITHINP6 : { int r; - grn_obj *e; + grn_obj *value; double lng0, lat0, lng1, lat1, lng2, lat2, x, y, d; - POP1(e); - lng0 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lat0 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1(e); - lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); - POP1ALLOC1(e, res); - lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e)); + POP1(value); + lng0 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lat0 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1(value); + lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); + POP1ALLOC1(value, res); + lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value)); x = (lng1 - lng0) * cos((lat0 + lat1) * 0.5); y = (lat1 - lat0); d = (x * x) + (y * y); @@ -3201,24 +3236,24 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) case GRN_OP_GEO_WITHINP8 : { int r; - grn_obj *e; + grn_obj *value; int64_t ln0, la0, ln1, la1, ln2, la2, ln3, la3; - POP1(e); - ln0 = GRN_INT32_VALUE(e); - POP1(e); - la0 = GRN_INT32_VALUE(e); - POP1(e); - ln1 = GRN_INT32_VALUE(e); - POP1(e); - la1 = GRN_INT32_VALUE(e); - POP1(e); - ln2 = GRN_INT32_VALUE(e); - POP1(e); - la2 = GRN_INT32_VALUE(e); - POP1(e); - ln3 = GRN_INT32_VALUE(e); - POP1ALLOC1(e, res); - la3 = GRN_INT32_VALUE(e); + POP1(value); + ln0 = GRN_INT32_VALUE(value); + POP1(value); + la0 = GRN_INT32_VALUE(value); + POP1(value); + ln1 = GRN_INT32_VALUE(value); + POP1(value); + la1 = GRN_INT32_VALUE(value); + POP1(value); + ln2 = GRN_INT32_VALUE(value); + POP1(value); + la2 = GRN_INT32_VALUE(value); + POP1(value); + ln3 = GRN_INT32_VALUE(value); + POP1ALLOC1(value, res); + la3 = GRN_INT32_VALUE(value); r = ((ln2 <= ln0) && (ln0 <= ln3) && (la2 <= la0) && (la0 <= la3)); GRN_INT32_SET(ctx, res, r); res->header.type = GRN_BULK; @@ -3458,9 +3493,15 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_GET_MEMBER : { - grn_obj *column_and_record_id, *index; - POP2ALLOC1(column_and_record_id, index, res); - grn_expr_exec_get_member(ctx, expr, column_and_record_id, index, res); + grn_obj *receiver, *index_or_key; + POP2ALLOC1(receiver, index_or_key, res); + if (receiver->header.type == GRN_PTR) { + grn_obj *index = index_or_key; + grn_expr_exec_get_member_vector(ctx, expr, receiver, index, res); + } else { + grn_obj *key = index_or_key; + grn_expr_exec_get_member_table(ctx, expr, receiver, key, res); + } code++; } break; @@ -5996,7 +6037,7 @@ resolve_top_level_name(grn_ctx *ctx, const char *name, unsigned int name_size) } static grn_rc -get_identifier(grn_ctx *ctx, efs_info *q) +get_identifier(grn_ctx *ctx, efs_info *q, grn_obj *name_resolve_context) { const char *s; unsigned int len; @@ -6072,6 +6113,14 @@ done : grn_obj *obj; const char *name = q->cur; unsigned int name_size = s - q->cur; + if (name_resolve_context) { + if ((obj = grn_obj_column(ctx, name_resolve_context, name, name_size))) { + grn_expr_take_obj(ctx, q->e, obj); + PARSE(GRN_EXPR_TOKEN_IDENTIFIER); + grn_expr_append_obj(ctx, q->e, obj, GRN_OP_GET_VALUE, 2); + goto exit; + } + } if ((obj = grn_expr_get_var(ctx, q->e, name, name_size))) { PARSE(GRN_EXPR_TOKEN_IDENTIFIER); grn_expr_append_obj(ctx, q->e, obj, GRN_OP_PUSH, 1); @@ -6108,11 +6157,59 @@ set_tos_minor_to_curr(grn_ctx *ctx, efs_info *q) yytos->minor.yy0 = ((grn_expr *)(q->e))->codes_curr; } +static grn_obj * +parse_script_extract_name_resolve_context(grn_ctx *ctx, efs_info *q) +{ + grn_expr *expr = (grn_expr *)(q->e); + grn_expr_code *code_start; + grn_expr_code *code_last; + + if (expr->codes_curr == 0) { + return NULL; + } + + code_start = expr->codes; + code_last = code_start + (expr->codes_curr - 1); + switch (code_last->op) { + case GRN_OP_GET_MEMBER : + { + unsigned int n_used_codes_for_key; + grn_expr_code *code_key; + grn_expr_code *code_receiver; + + code_key = code_last - 1; + if (code_key < code_start) { + return NULL; + } + + n_used_codes_for_key = grn_expr_code_n_used_codes(ctx, + code_start, + code_key); + if (n_used_codes_for_key == 0) { + return NULL; + } + code_receiver = code_key - n_used_codes_for_key; + if (code_receiver < code_start) { + return NULL; + } + return code_receiver->value; + } + break; + default : + /* TODO: Support other operators. */ + return NULL; + break; + } +} + static grn_rc parse_script(grn_ctx *ctx, efs_info *q) { grn_rc rc = GRN_SUCCESS; + grn_obj *name_resolve_context = NULL; for (;;) { + grn_obj *current_name_resolve_context = name_resolve_context; + name_resolve_context = NULL; skip_space(ctx, q); if (q->cur >= q->str_end) { rc = GRN_END_OF_DATA; goto exit; } switch (*q->cur) { @@ -6150,6 +6247,7 @@ parse_script(grn_ctx *ctx, efs_info *q) break; case '.' : PARSE(GRN_EXPR_TOKEN_DOT); + name_resolve_context = parse_script_extract_name_resolve_context(ctx, q); q->cur++; break; case ':' : @@ -6538,7 +6636,9 @@ parse_script(grn_ctx *ctx, efs_info *q) } break; default : - if ((rc = get_identifier(ctx, q))) { goto exit; } + if ((rc = get_identifier(ctx, q, current_name_resolve_context))) { + goto exit; + } break; } if (ctx->rc) { rc = ctx->rc; break; } diff --git a/storage/mroonga/vendor/groonga/lib/expr_code.c b/storage/mroonga/vendor/groonga/lib/expr_code.c new file mode 100644 index 00000000000..4f03867402a --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/expr_code.c @@ -0,0 +1,71 @@ +/* -*- c-basic-offset: 2 -*- */ +/* Copyright(C) 2014-2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "grn_expr_code.h" + +unsigned int +grn_expr_code_n_used_codes(grn_ctx *ctx, + grn_expr_code *start, + grn_expr_code *target) +{ + unsigned int n_codes; + int i, n_args; + grn_bool have_proc_push_code = GRN_FALSE; + grn_expr_code *sub_code; + + if (start == target) { + return 0; + } + + n_args = target->nargs; + if (target->op == GRN_OP_CALL) { + if (!target->value) { + have_proc_push_code = GRN_TRUE; + } + } else { + if (target->value) { + n_args--; + if (n_args == 0) { + return 1; + } + } + } + + n_codes = 1; + sub_code = target - 1; + for (i = 0; i < n_args; i++) { + int sub_n_codes; + sub_n_codes = grn_expr_code_n_used_codes(ctx, start, sub_code); + n_codes += sub_n_codes; + sub_code -= sub_n_codes; + if (sub_code < start) { + /* TODO: report error */ + return 0; + } + } + + if (have_proc_push_code) { + n_codes++; + sub_code--; + if (sub_code < start) { + /* TODO: report error */ + return 0; + } + } + + return n_codes; +} diff --git a/storage/mroonga/vendor/groonga/lib/grn.h b/storage/mroonga/vendor/groonga/lib/grn.h index f4ee6e962a9..80622a8421b 100644 --- a/storage/mroonga/vendor/groonga/lib/grn.h +++ b/storage/mroonga/vendor/groonga/lib/grn.h @@ -31,17 +31,13 @@ # define __STDC_LIMIT_MACROS #endif -#ifdef HAVE_STDLIB_H -# include <stdlib.h> -#endif /* HAVE_STDLIB_H */ +#include <stdlib.h> #ifdef HAVE_STDINT_H # include <stdint.h> #endif /* HAVE_STDINT_H */ -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif /* HAVE_SYS_TYPES_H */ +#include <sys/types.h> #ifdef HAVE_SYS_PARAM_H # include <sys/param.h> diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx.h b/storage/mroonga/vendor/groonga/lib/grn_ctx.h index 2f052f5f1c5..4ba5f3c9bc6 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ctx.h +++ b/storage/mroonga/vendor/groonga/lib/grn_ctx.h @@ -153,7 +153,6 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx); #ifdef WIN32 -#define SYSTEM_ERROR_MESSAGE_BUFFER_SIZE 1024 #define SERR(str) do {\ grn_rc rc;\ const char *system_message;\ @@ -333,8 +332,8 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx); grn_rc rc;\ int errno_keep = errno;\ grn_bool show_errno = GRN_FALSE;\ - char system_message[SYSTEM_ERROR_MESSAGE_BUFFER_SIZE];\ - strerror_s(system_message, SYSTEM_ERROR_MESSAGE_BUFFER_SIZE, errno);\ + const char *system_message;\ + system_message = grn_strerror(errno);\ switch (errno_keep) {\ case EPERM : rc = GRN_OPERATION_NOT_PERMITTED; break;\ case ENOENT : rc = GRN_NO_SUCH_FILE_OR_DIRECTORY; break;\ diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h index 61cf088b2ae..3e46d2e417f 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h +++ b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013 Brazil + Copyright(C) 2013-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -26,6 +26,7 @@ extern "C" { #endif +void grn_ctx_impl_mrb_init_from_env(void); void grn_ctx_impl_mrb_init(grn_ctx *ctx); void grn_ctx_impl_mrb_fin(grn_ctx *ctx); diff --git a/storage/mroonga/vendor/groonga/lib/grn_dat.h b/storage/mroonga/vendor/groonga/lib/grn_dat.h index aefd044d0b7..d3c768fa65c 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_dat.h +++ b/storage/mroonga/vendor/groonga/lib/grn_dat.h @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2011-2014 Brazil +/* Copyright(C) 2011-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -79,6 +79,8 @@ GRN_API grn_rc grn_dat_clear_status_flags(grn_ctx *ctx, grn_dat *dat); */ GRN_API grn_rc grn_dat_repair(grn_ctx *ctx, grn_dat *dat); +GRN_API grn_rc grn_dat_flush(grn_ctx *ctx, grn_dat *dat); + #ifdef __cplusplus } #endif diff --git a/storage/mroonga/vendor/groonga/lib/grn_db.h b/storage/mroonga/vendor/groonga/lib/grn_db.h index cbc2cccaf4e..6c84ad921f4 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_db.h +++ b/storage/mroonga/vendor/groonga/lib/grn_db.h @@ -56,6 +56,8 @@ typedef struct { grn_id range; } grn_obj_spec; +void grn_db_init_from_env(void); + GRN_API grn_rc grn_db_close(grn_ctx *ctx, grn_obj *db); grn_obj *grn_db_keys(grn_obj *s); diff --git a/storage/mroonga/vendor/groonga/lib/grn_egn.h b/storage/mroonga/vendor/groonga/lib/grn_egn.h new file mode 100644 index 00000000000..3d1d54ca9aa --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/grn_egn.h @@ -0,0 +1,90 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GRN_EGN_H +#define GRN_EGN_H + +#include "grn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Constant values. + +typedef grn_operator grn_egn_operator_type; +typedef grn_builtin_type grn_egn_data_type; + +typedef enum { + GRN_EGN_ID_NODE, + GRN_EGN_SCORE_NODE, + GRN_EGN_CONSTANT_NODE, + GRN_EGN_COLUMN_NODE, + GRN_EGN_OPERATOR_NODE +} grn_egn_expression_node_type; + +typedef enum { + GRN_EGN_INCOMPLETE, + GRN_EGN_ID, + GRN_EGN_SCORE, + GRN_EGN_CONSTANT, + GRN_EGN_VARIABLE +} grn_egn_expression_type; + +// Built-in data types. + +typedef grn_id grn_egn_id; +typedef float grn_egn_score; +typedef struct { + grn_egn_id id; + grn_egn_score score; +} grn_egn_record; + +typedef grn_bool grn_egn_bool; +typedef int64_t grn_egn_int; +typedef double grn_egn_float; +typedef int64_t grn_egn_time; +typedef struct { + const char *ptr; + size_t size; +} grn_egn_text; +typedef grn_geo_point grn_egn_geo_point; + +/* + * grn_egn_select() finds records passing through a filter (specified by + * `filter' and `filter_size') and writes the associated values (specified by + * `output_columns' and `output_columns_size') into the output buffer of `ctx' + * (`ctx->impl->outbuf'). + * + * Note that the first `offset` records will be discarded and at most `limit` + * records will be output. + * + * On success, grn_egn_select() returns GRN_SUCCESS. + * On failure, grn_egn_select() returns an error code and set the details into + * `ctx`. + */ +grn_rc grn_egn_select(grn_ctx *ctx, grn_obj *table, + const char *filter, size_t filter_size, + const char *output_columns, size_t output_columns_size, + int offset, int limit); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_EGN_H */ diff --git a/storage/mroonga/vendor/groonga/lib/grn_egn.hpp b/storage/mroonga/vendor/groonga/lib/grn_egn.hpp new file mode 100644 index 00000000000..46511afd6ca --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/grn_egn.hpp @@ -0,0 +1,318 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GRN_EGN_HPP +#define GRN_EGN_HPP + +#include <cstring> +#include <vector> + +#include "grn_egn.h" + +namespace grn { +namespace egn { + +// Constant values. + +typedef grn_egn_operator_type OperatorType; +typedef grn_egn_data_type DataType; + +typedef grn_egn_expression_node_type ExpressionNodeType; +typedef grn_egn_expression_type ExpressionType; + +// Built-in data types. + +typedef grn_egn_id ID; +typedef grn_egn_score Score; +typedef grn_egn_record Record; + +//typedef grn_egn_bool Bool; +//typedef grn_egn_int Int; +//typedef grn_egn_float Float; +//typedef grn_egn_time Time; +//typedef grn_egn_text Text; +//typedef grn_egn_geo_point GeoPoint; + +//inline bool operator==(const Text &lhs, const Text &rhs) { +// if (lhs.size != rhs.size) { +// return false; +// } +// return std::memcmp(lhs.ptr, rhs.ptr, lhs.size) == 0; +//} +//inline bool operator!=(const Text &lhs, const Text &rhs) { +// if (lhs.size != rhs.size) { +// return true; +// } +// return std::memcmp(lhs.ptr, rhs.ptr, lhs.size) != 0; +//} +//inline bool operator<(const Text &lhs, const Text &rhs) { +// size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size; +// int result = std::memcmp(lhs.ptr, rhs.ptr, min_size); +// if (result == 0) { +// return lhs.size < rhs.size; +// } +// return result < 0; +//} +//inline bool operator<=(const Text &lhs, const Text &rhs) { +// size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size; +// int result = std::memcmp(lhs.ptr, rhs.ptr, min_size); +// if (result == 0) { +// return lhs.size <= rhs.size; +// } +// return result <= 0; +//} +//inline bool operator>(const Text &lhs, const Text &rhs) { +// return rhs < lhs; +//} +//inline bool operator>=(const Text &lhs, const Text &rhs) { +// return rhs <= lhs; +//} + +//inline bool operator==(const GeoPoint &lhs, const GeoPoint &rhs) { +// return (lhs.latitude == rhs.latitude) && (lhs.longitude == rhs.longitude); +//} +//inline bool operator!=(const GeoPoint &lhs, const GeoPoint &rhs) { +// return (lhs.latitude != rhs.latitude) || (lhs.longitude != rhs.longitude); +//} + +struct Bool { + typedef grn_egn_bool Raw; + Raw raw; + + static DataType data_type() { + return GRN_DB_BOOL; + } + + Bool() : raw() {} + Bool(const Bool &value) : raw(value.raw) {} + explicit Bool(Raw value) : raw(value) {} + ~Bool() {} +}; + +inline bool operator!(Bool value) { return !value.raw; } +inline bool operator==(Bool lhs, Bool rhs) { return lhs.raw == rhs.raw; } +inline bool operator!=(Bool lhs, Bool rhs) { return lhs.raw != rhs.raw; } + +struct Int { + typedef grn_egn_int Raw; + Raw raw; + + static DataType data_type() { + return GRN_DB_INT64; + } + + Int() : raw() {} + Int(const Int &value) : raw(value.raw) {} + explicit Int(Raw value) : raw(value) {} + ~Int() {} +}; + +inline bool operator==(Int lhs, Int rhs) { return lhs.raw == rhs.raw; } +inline bool operator!=(Int lhs, Int rhs) { return lhs.raw != rhs.raw; } +inline bool operator<(Int lhs, Int rhs) { return lhs.raw < rhs.raw; } +inline bool operator<=(Int lhs, Int rhs) { return lhs.raw <= rhs.raw; } +inline bool operator>(Int lhs, Int rhs) { return lhs.raw > rhs.raw; } +inline bool operator>=(Int lhs, Int rhs) { return lhs.raw >= rhs.raw; } + +struct Float { + typedef grn_egn_float Raw; + Raw raw; + + static DataType data_type() { + return GRN_DB_FLOAT; + } + + Float() : raw() {} + Float(const Float &value) : raw(value.raw) {} + explicit Float(Raw value) : raw(value) {} + ~Float() {} +}; + +inline bool operator==(Float lhs, Float rhs) { return lhs.raw == rhs.raw; } +inline bool operator!=(Float lhs, Float rhs) { return lhs.raw != rhs.raw; } +inline bool operator<(Float lhs, Float rhs) { return lhs.raw < rhs.raw; } +inline bool operator<=(Float lhs, Float rhs) { return lhs.raw <= rhs.raw; } +inline bool operator>(Float lhs, Float rhs) { return lhs.raw > rhs.raw; } +inline bool operator>=(Float lhs, Float rhs) { return lhs.raw >= rhs.raw; } + +struct Time { + typedef grn_egn_time Raw; + Raw raw; + + static DataType data_type() { + return GRN_DB_TIME; + } + + Time() : raw() {} + Time(const Time &value) : raw(value.raw) {} + explicit Time(Raw value) : raw(value) {} + ~Time() {} +}; + +inline bool operator==(Time lhs, Time rhs) { return lhs.raw == rhs.raw; } +inline bool operator!=(Time lhs, Time rhs) { return lhs.raw != rhs.raw; } +inline bool operator<(Time lhs, Time rhs) { return lhs.raw < rhs.raw; } +inline bool operator<=(Time lhs, Time rhs) { return lhs.raw <= rhs.raw; } +inline bool operator>(Time lhs, Time rhs) { return lhs.raw > rhs.raw; } +inline bool operator>=(Time lhs, Time rhs) { return lhs.raw >= rhs.raw; } + +struct Text { + typedef grn_egn_text Raw; + Raw raw; + + static DataType data_type() { + return GRN_DB_TEXT; + } + + Text() : raw() {} + Text(const Text &value) : raw(value.raw) {} + explicit Text(const Raw &value) : raw(value) {} + Text(const char *ptr, size_t size) : raw((Raw){ptr, size}) {} + ~Text() {} +}; + +inline bool operator==(const Text &lhs, const Text &rhs) { + if (lhs.raw.size != rhs.raw.size) { + return false; + } + return std::memcmp(lhs.raw.ptr, rhs.raw.ptr, lhs.raw.size) == 0; +} +inline bool operator!=(const Text &lhs, const Text &rhs) { + if (lhs.raw.size != rhs.raw.size) { + return true; + } + return std::memcmp(lhs.raw.ptr, rhs.raw.ptr, lhs.raw.size) != 0; +} +inline bool operator<(const Text &lhs, const Text &rhs) { + size_t min_size = (lhs.raw.size < rhs.raw.size) ? + lhs.raw.size : rhs.raw.size; + int result = std::memcmp(lhs.raw.ptr, rhs.raw.ptr, min_size); + if (result == 0) { + return lhs.raw.size < rhs.raw.size; + } + return result < 0; +} +inline bool operator<=(const Text &lhs, const Text &rhs) { + size_t min_size = (lhs.raw.size < rhs.raw.size) ? + lhs.raw.size : rhs.raw.size; + int result = std::memcmp(lhs.raw.ptr, rhs.raw.ptr, min_size); + if (result == 0) { + return lhs.raw.size <= rhs.raw.size; + } + return result <= 0; +} +inline bool operator>(const Text &lhs, const Text &rhs) { return rhs < lhs; } +inline bool operator>=(const Text &lhs, const Text &rhs) { return rhs <= lhs; } + +struct GeoPoint { + typedef grn_egn_geo_point Raw; + Raw raw; + + static DataType data_type() { + return GRN_DB_WGS84_GEO_POINT; + } + + GeoPoint() : raw() {} + GeoPoint(const GeoPoint &value) : raw(value.raw) {} + explicit GeoPoint(Raw value) : raw(value) {} + GeoPoint(int latitude, int longitude) : raw((Raw){ latitude, longitude }) {} + ~GeoPoint() {} +}; + +inline bool operator==(GeoPoint lhs, GeoPoint rhs) { + return (lhs.raw.latitude == rhs.raw.latitude) && + (lhs.raw.longitude == rhs.raw.longitude); +} +inline bool operator!=(GeoPoint lhs, GeoPoint rhs) { + return (lhs.raw.latitude != rhs.raw.latitude) || + (lhs.raw.longitude != rhs.raw.longitude); +} + +// Cursor is a base class which provides an interface for sequential access to +// records. +class Cursor { + public: + Cursor() {} + virtual ~Cursor() {} + + // FIXME: Give me options. + static grn_rc open_table_cursor(grn_ctx *ctx, grn_obj *table, + Cursor **cursor); + + virtual grn_rc read(Record *records, size_t size, size_t *count); +}; + +// ExpressionNode is an element of Expression. +class ExpressionNode; + +// Expression is a class which represents an expression. +class Expression { + public: + Expression(grn_ctx *ctx, grn_obj *table); + ~Expression(); + + static grn_rc open(grn_ctx *ctx, grn_obj *table, Expression **expression); + static grn_rc parse(grn_ctx *ctx, grn_obj *table, + const char *query, size_t query_size, + Expression **expression); + + ExpressionType type() const { + return type_; + } + DataType data_type() const { + return data_type_; + } + + grn_rc push_object(grn_obj *obj); + grn_rc push_operator(grn_operator operator_type); + + grn_rc filter(Record *input, size_t input_size, + Record *output, size_t *output_size); + grn_rc adjust(Record *records, size_t num_records); + + template <typename T> + grn_rc evaluate(const Record *records, size_t num_records, T *results); + + private: + grn_ctx *ctx_; + grn_obj *table_; + ExpressionType type_; + DataType data_type_; + std::vector<ExpressionNode *> stack_; + + // Disable copy and assignment. + Expression(const Expression &); + Expression &operator=(const Expression &); + + ExpressionNode *root() const; + + void update_types(); + + grn_rc push_bulk_object(grn_obj *obj); + grn_rc push_column_object(grn_obj *obj); + + grn_rc create_unary_node(OperatorType operator_type, + ExpressionNode *arg, ExpressionNode **node); + grn_rc create_binary_node(OperatorType operator_type, + ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node); +}; + +} // namespace egn +} // namespace grn + +#endif // GRN_EGN_HPP diff --git a/storage/mroonga/vendor/groonga/lib/grn_error.h b/storage/mroonga/vendor/groonga/lib/grn_error.h index 2581f934135..a0b18ca7183 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_error.h +++ b/storage/mroonga/vendor/groonga/lib/grn_error.h @@ -27,6 +27,7 @@ extern "C" { #endif GRN_API const char *grn_current_error_message(void); +GRN_API const char *grn_strerror(int error_code); #ifdef __cplusplus } diff --git a/storage/mroonga/vendor/groonga/lib/grn_expr_code.h b/storage/mroonga/vendor/groonga/lib/grn_expr_code.h new file mode 100644 index 00000000000..a0fd680e7d4 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/grn_expr_code.h @@ -0,0 +1,37 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GRN_EXPR_CODE_H +#define GRN_EXPR_CODE_H + +#include "grn_db.h" + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int grn_expr_code_n_used_codes(grn_ctx *ctx, + grn_expr_code *start, + grn_expr_code *target); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_EXPR_CODE_H */ + diff --git a/storage/mroonga/vendor/groonga/lib/grn_ii.h b/storage/mroonga/vendor/groonga/lib/grn_ii.h index fe9b1ec26a4..1ac9528e4cd 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ii.h +++ b/storage/mroonga/vendor/groonga/lib/grn_ii.h @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2009-2012 Brazil +/* Copyright(C) 2009-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -87,6 +87,8 @@ struct _grn_ii_updspec { typedef struct _grn_ii_updspec grn_ii_updspec; +void grn_ii_init_from_env(void); + GRN_API grn_ii *grn_ii_create(grn_ctx *ctx, const char *path, grn_obj *lexicon, uint32_t flags); GRN_API grn_ii *grn_ii_open(grn_ctx *ctx, const char *path, grn_obj *lexicon); @@ -103,6 +105,7 @@ grn_rc grn_ii_updspec_add(grn_ctx *ctx, grn_ii_updspec *u, int pos, int32_t weig int grn_ii_updspec_cmp(grn_ii_updspec *a, grn_ii_updspec *b); void grn_ii_expire(grn_ctx *ctx, grn_ii *ii); +grn_rc grn_ii_flush(grn_ctx *ctx, grn_ii *ii); typedef struct { grn_id rid; diff --git a/storage/mroonga/vendor/groonga/lib/grn_io.h b/storage/mroonga/vendor/groonga/lib/grn_io.h index 14f5e496f8b..6de63bd172a 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_io.h +++ b/storage/mroonga/vendor/groonga/lib/grn_io.h @@ -350,12 +350,13 @@ uint32_t grn_io_detect_type(grn_ctx *ctx, const char *path); grn_rc grn_io_set_type(grn_io *io, uint32_t type); uint32_t grn_io_get_type(grn_io *io); -grn_rc grn_io_init(void); -grn_rc grn_io_fin(void); +void grn_io_init_from_env(void); uint32_t grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit); uint32_t grn_expire(grn_ctx *ctx, int count_thresh, uint32_t limit); +grn_rc grn_io_flush(grn_ctx *ctx, grn_io *io); + /* encode/decode */ #define GRN_B_ENC(v,p) do {\ diff --git a/storage/mroonga/vendor/groonga/lib/grn_mrb.h b/storage/mroonga/vendor/groonga/lib/grn_mrb.h index 7fae820d342..3726cdcba29 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_mrb.h +++ b/storage/mroonga/vendor/groonga/lib/grn_mrb.h @@ -30,6 +30,8 @@ extern "C" { #endif +void grn_mrb_init_from_env(void); + #ifdef GRN_WITH_MRUBY GRN_API mrb_value grn_mrb_eval(grn_ctx *ctx, const char *script, int script_length); GRN_API mrb_value grn_mrb_load(grn_ctx *ctx, const char *path); diff --git a/storage/mroonga/vendor/groonga/lib/grn_plugin.h b/storage/mroonga/vendor/groonga/lib/grn_plugin.h index 75b29f56cc9..22749c634aa 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_plugin.h +++ b/storage/mroonga/vendor/groonga/lib/grn_plugin.h @@ -46,6 +46,7 @@ struct _grn_plugin { int refcount; }; +void grn_plugin_init_from_env(void); grn_rc grn_plugins_init(void); grn_rc grn_plugins_fin(void); grn_id grn_plugin_open(grn_ctx *ctx, const char *filename); diff --git a/storage/mroonga/vendor/groonga/lib/grn_proc.h b/storage/mroonga/vendor/groonga/lib/grn_proc.h index fb01698ea69..b75d11079a2 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_proc.h +++ b/storage/mroonga/vendor/groonga/lib/grn_proc.h @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2009 Brazil +/* Copyright(C) 2009-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -23,6 +23,8 @@ extern "C" { #endif +void grn_proc_init_from_env(void); + GRN_VAR const char *grn_document_root; void grn_db_init_builtin_query(grn_ctx *ctx); diff --git a/storage/mroonga/vendor/groonga/lib/ii.c b/storage/mroonga/vendor/groonga/lib/ii.c index 2d32df2fd4d..388e0566756 100644 --- a/storage/mroonga/vendor/groonga/lib/ii.c +++ b/storage/mroonga/vendor/groonga/lib/ii.c @@ -74,6 +74,36 @@ # define S_IWUSR 0200 #endif /* S_IWUSR */ +static grn_bool grn_ii_cursor_set_min_enable = GRN_FALSE; +static double grn_ii_select_too_many_index_match_ratio = -1; + +void +grn_ii_init_from_env(void) +{ + { + char grn_ii_cursor_set_min_enable_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_II_CURSOR_SET_MIN_ENABLE", + grn_ii_cursor_set_min_enable_env, + GRN_ENV_BUFFER_SIZE); + if (grn_ii_cursor_set_min_enable_env[0]) { + grn_ii_cursor_set_min_enable = GRN_TRUE; + } else { + grn_ii_cursor_set_min_enable = GRN_FALSE; + } + } + + { + char grn_ii_select_too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO", + grn_ii_select_too_many_index_match_ratio_env, + GRN_ENV_BUFFER_SIZE); + if (grn_ii_select_too_many_index_match_ratio_env[0]) { + grn_ii_select_too_many_index_match_ratio = + atof(grn_ii_select_too_many_index_match_ratio_env); + } + } +} + /* segment */ inline static uint32_t @@ -3492,6 +3522,7 @@ _grn_ii_create(grn_ctx *ctx, grn_ii *ii, const char *path, grn_obj *lexicon, uin } if (!chunk) { grn_io_close(ctx, seg); + grn_io_remove(ctx, path); return NULL; } header = grn_io_header(seg); @@ -3688,6 +3719,19 @@ grn_ii_expire(grn_ctx *ctx, grn_ii *ii) grn_io_expire(ctx, ii->chunk, 0, 1000000); } +grn_rc +grn_ii_flush(grn_ctx *ctx, grn_ii *ii) +{ + grn_rc rc; + + rc = grn_io_flush(ctx, ii->seg); + if (rc == GRN_SUCCESS) { + rc = grn_io_flush(ctx, ii->chunk); + } + + return rc; +} + #define BIT11_01(x) ((x >> 1) & 0x7ff) #define BIT31_12(x) (x >> 12) @@ -4023,6 +4067,7 @@ grn_ii_cursor_open(grn_ctx *ctx, grn_ii *ii, grn_id tid, uint32_t pos, *a; if (!(a = array_at(ctx, ii, tid))) { return NULL; } for (;;) { + c = NULL; if (!(pos = a[0])) { goto exit; } if (!(c = GRN_MALLOC(sizeof(grn_ii_cursor)))) { goto exit; } memset(c, 0, sizeof(grn_ii_cursor)); @@ -4112,16 +4157,11 @@ exit : static inline void grn_ii_cursor_set_min(grn_ctx *ctx, grn_ii_cursor *c, grn_id min) { - char grn_ii_cursor_set_min_enable_env[GRN_ENV_BUFFER_SIZE]; - if (c->min >= min) { return; } - grn_getenv("GRN_II_CURSOR_SET_MIN_ENABLE", - grn_ii_cursor_set_min_enable_env, - GRN_ENV_BUFFER_SIZE); - if (grn_ii_cursor_set_min_enable_env[0]) { + if (grn_ii_cursor_set_min_enable) { c->min = min; if (c->buf && c->pc.rid < c->min && c->curr_chunk < c->nchunks) { uint32_t i, skip_chunk = 0; @@ -6019,6 +6059,77 @@ grn_ii_term_extract(grn_ctx *ctx, grn_ii *ii, const char *string, return rc; } +static grn_rc +grn_ii_select_regexp(grn_ctx *ctx, grn_ii *ii, + const char *string, unsigned int string_len, + grn_hash *s, grn_operator op, grn_select_optarg *optarg) +{ + grn_rc rc; + grn_obj parsed_string; + grn_bool escaping = GRN_FALSE; + int nth_char = 0; + const char *current = string; + const char *string_end = string + string_len; + + GRN_TEXT_INIT(&parsed_string, 0); + while (current < string_end) { + const char *target; + int char_len; + + char_len = grn_charlen(ctx, current, string_end); + if (char_len == 0) { + ERR(GRN_INVALID_ARGUMENT, + "[ii][select][regexp] invalid encoding character: <%.*s|%#x|>", + (int)(current - string), string, + *current); + return ctx->rc; + } + target = current; + current += char_len; + + if (escaping) { + escaping = GRN_FALSE; + if (char_len == 1) { + switch (*target) { + case 'A' : + if (nth_char == 0) { + target = GRN_TOKENIZER_BEGIN_MARK_UTF8; + char_len = GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN; + } + break; + case 'z' : + if (current == string_end) { + target = GRN_TOKENIZER_END_MARK_UTF8; + char_len = GRN_TOKENIZER_END_MARK_UTF8_LEN; + } + break; + default : + break; + } + } + } else { + if (char_len == 1 && *target == '\\') { + escaping = GRN_TRUE; + continue; + } + } + + GRN_TEXT_PUT(ctx, &parsed_string, target, char_len); + nth_char++; + } + + if (optarg) { + optarg->mode = GRN_OP_MATCH; + } + + rc = grn_ii_select(ctx, ii, + GRN_TEXT_VALUE(&parsed_string), + GRN_TEXT_LEN(&parsed_string), + s, op, optarg); + + return rc; +} + #ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH static grn_bool grn_ii_select_sequential_search_should_use(grn_ctx *ctx, @@ -6156,16 +6267,6 @@ grn_ii_select_sequential_search(grn_ctx *ctx, grn_bool processed = GRN_TRUE; { - /* Disabled by default. */ - double too_many_index_match_ratio = -1; - char too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE]; - grn_getenv("GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO", - too_many_index_match_ratio_env, - GRN_ENV_BUFFER_SIZE); - if (too_many_index_match_ratio_env[0]) { - too_many_index_match_ratio = atof(too_many_index_match_ratio_env); - } - if (!grn_ii_select_sequential_search_should_use(ctx, ii, raw_query, @@ -6176,7 +6277,7 @@ grn_ii_select_sequential_search(grn_ctx *ctx, optarg, token_infos, n_token_infos, - too_many_index_match_ratio)) { + grn_ii_select_too_many_index_match_ratio)) { return GRN_FALSE; } } @@ -6259,6 +6360,9 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_ if (mode == GRN_OP_TERM_EXTRACT) { return grn_ii_term_extract(ctx, ii, string, string_len, s, op, optarg); } + if (mode == GRN_OP_REGEXP) { + return grn_ii_select_regexp(ctx, ii, string, string_len, s, op, optarg); + } /* todo : support subrec rep = (s->record_unit == grn_rec_position || s->subrec_unit == grn_rec_position); orp = (s->record_unit == grn_rec_position || op == GRN_OP_OR); @@ -7907,6 +8011,20 @@ grn_ii_buffer_parse(grn_ctx *ctx, grn_ii_buffer *ii_buffer, grn_ii_buffer_tokenize(ctx, ii_buffer, rid, sid, 0, GRN_TEXT_VALUE(&rv), GRN_TEXT_LEN(&rv)); break; + case GRN_UVECTOR : + { + unsigned int i, size; + unsigned int element_size; + + size = grn_uvector_size(ctx, &rv); + element_size = grn_uvector_element_size(ctx, &rv); + for (i = 0; i < size; i++) { + grn_ii_buffer_tokenize(ctx, ii_buffer, rid, sid, 0, + GRN_BULK_HEAD(&rv) + (element_size * i), + element_size); + } + } + break; case GRN_VECTOR : if (rv.u.v.body) { int i; diff --git a/storage/mroonga/vendor/groonga/lib/io.c b/storage/mroonga/vendor/groonga/lib/io.c index a78c7f242c9..3cee03f5123 100644 --- a/storage/mroonga/vendor/groonga/lib/io.c +++ b/storage/mroonga/vendor/groonga/lib/io.c @@ -30,10 +30,12 @@ #include "grn_ctx_impl.h" #ifdef WIN32 +# include <io.h> # include <share.h> #endif /* WIN32 */ #define GRN_IO_IDSTR "GROONGA:IO:00001" +#define GRN_IO_IDSTR_LEN (sizeof(GRN_IO_IDSTR) - 1) #define GRN_IO_VERSION_DEFAULT 1 @@ -99,8 +101,8 @@ inline static int grn_msync(grn_ctx *ctx, void *start, size_t length); inline static grn_rc grn_pread(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset); inline static grn_rc grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset); -grn_rc -grn_io_init(void) +void +grn_io_init_from_env(void) { char version_env[GRN_ENV_BUFFER_SIZE]; @@ -110,14 +112,6 @@ grn_io_init(void) if (version_env[0]) { grn_io_version_default = atoi(version_env); } - - return GRN_SUCCESS; -} - -grn_rc -grn_io_fin(void) -{ - return GRN_SUCCESS; } static inline uint32_t @@ -320,7 +314,12 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg GRN_MUNMAP(&grn_gctx, NULL, &fis->fmo, fis, header, b); } grn_fileinfo_close(ctx, fis); - grn_unlink(path); + if (grn_unlink(path) == -1) { + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to grn_unlink() path on grn_io_create() error: " + "<%s>: <%s>", + path, grn_strerror(errno)); + } } GRN_GFREE(fis); } @@ -479,13 +478,19 @@ grn_io_detect_type(grn_ctx *ctx, const char *path) struct stat s; if (fstat(fd, &s) != -1 && s.st_size >= sizeof(struct _grn_io_header)) { if (grn_read(fd, &h, sizeof(struct _grn_io_header)) == sizeof(struct _grn_io_header)) { - if (!memcmp(h.idstr, GRN_IO_IDSTR, 16)) { + if (!memcmp(h.idstr, GRN_IO_IDSTR, GRN_IO_IDSTR_LEN)) { res = h.type; } else { - ERR(GRN_INCOMPATIBLE_FILE_FORMAT, "incompatible file format"); + ERR(GRN_INCOMPATIBLE_FILE_FORMAT, + "failed to detect type: format ID is different: <%s>: <%.*s>", + path, + (int)GRN_IO_IDSTR_LEN, GRN_IO_IDSTR); } } else { SERR(path); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to read enough data for detecting type: <%s>", + path); } } else { ERR(GRN_INVALID_FORMAT, "grn_io_detect_type failed"); @@ -493,6 +498,9 @@ grn_io_detect_type(grn_ctx *ctx, const char *path) grn_close(fd); } else { ERRNO_ERR(path); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to open path for detecting type: <%s>", + path); } return res; } @@ -513,17 +521,23 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode) grn_open(fd, path, O_RDWR | GRN_OPEN_FLAG_BINARY); if (fd == -1) { ERRNO_ERR(path); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to open path: <%s>", + path); return NULL; } if (fstat(fd, &s) != -1 && s.st_size >= sizeof(struct _grn_io_header)) { if (grn_read(fd, &h, sizeof(struct _grn_io_header)) == sizeof(struct _grn_io_header)) { - if (!memcmp(h.idstr, GRN_IO_IDSTR, 16)) { + if (!memcmp(h.idstr, GRN_IO_IDSTR, GRN_IO_IDSTR_LEN)) { header_size = h.header_size; segment_size = h.segment_size; max_segment = h.max_segment; flags = h.flags; } else { - ERR(GRN_INCOMPATIBLE_FILE_FORMAT, "incompatible file format"); + ERR(GRN_INCOMPATIBLE_FILE_FORMAT, + "failed to open: format ID is different: <%s>: <%.*s>", + path, + (int)GRN_IO_IDSTR_LEN, GRN_IO_IDSTR); } } } @@ -705,6 +719,9 @@ grn_io_size(grn_ctx *ctx, grn_io *io, uint64_t *size) gen_pathname(io->path, buffer, fno); if (stat(buffer, &s)) { SERR(buffer); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to stat path to compute size: <%s>", + buffer); } else { tsize += s.st_size; } @@ -722,6 +739,9 @@ grn_io_remove(grn_ctx *ctx, const char *path) return ctx->rc; } else if (grn_unlink(path)) { ERRNO_ERR(path); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to remove path: <%s>", + path); return ctx->rc; } else { int fno; @@ -731,6 +751,9 @@ grn_io_remove(grn_ctx *ctx, const char *path) if (!stat(buffer, &s)) { if (grn_unlink(buffer)) { ERRNO_ERR(buffer); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to remove path: <%s>", + buffer); } } else { break; @@ -749,6 +772,9 @@ grn_io_rename(grn_ctx *ctx, const char *old_name, const char *new_name) return ctx->rc; } else if (rename(old_name, new_name)) { SERR(old_name); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to rename path: <%s> -> <%s>", + old_name, new_name); return ctx->rc; } else { int fno; @@ -758,9 +784,17 @@ grn_io_rename(grn_ctx *ctx, const char *old_name, const char *new_name) gen_pathname(old_name, old_buffer, fno); if (!stat(old_buffer, &s)) { gen_pathname(new_name, new_buffer, fno); - if (rename(old_buffer, new_buffer)) { SERR(old_buffer); } + if (rename(old_buffer, new_buffer)) { + SERR(old_buffer); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to rename path: <%s> -> <%s>", + old_buffer, new_buffer); + } } else { SERR("stat"); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to stat path to rename: <%s>", + old_buffer); return ctx->rc; } } @@ -1057,34 +1091,30 @@ grn_io_win_unmap(grn_io_win *iw) }\ } while (0) -#define SEG_MAP(io,segno,info) do {\ - uint32_t segment_size = io->header->segment_size;\ - if ((io->flags & GRN_IO_TEMPORARY)) {\ - DO_MAP(io, &info->fmo, NULL, 0, segment_size, segno, info->map);\ - } else {\ - unsigned long file_size = grn_io_compute_file_size(io->header->version);\ - uint32_t segments_per_file = file_size / segment_size;\ - uint32_t bseg = segno + io->base_seg;\ - uint32_t fno = bseg / segments_per_file;\ - off_t base = fno ? 0 : io->base - (uint64_t)segment_size * io->base_seg;\ - off_t pos = (uint64_t)segment_size * (bseg % segments_per_file) + base;\ - fileinfo *fi = &io->fis[fno];\ - if (!grn_fileinfo_opened(fi)) {\ - char path[PATH_MAX];\ - gen_pathname(io->path, path, fno);\ - if (!grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) { \ - DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);\ - }\ - } else {\ - DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);\ - }\ - }\ -} while (0) - void grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *info) { - SEG_MAP(io, segno, info); + uint32_t segment_size = io->header->segment_size; + if ((io->flags & GRN_IO_TEMPORARY)) { + DO_MAP(io, &info->fmo, NULL, 0, segment_size, segno, info->map); + } else { + unsigned long file_size = grn_io_compute_file_size(io->header->version); + uint32_t segments_per_file = file_size / segment_size; + uint32_t bseg = segno + io->base_seg; + uint32_t fno = bseg / segments_per_file; + off_t base = fno ? 0 : io->base - (uint64_t)segment_size * io->base_seg; + off_t pos = (uint64_t)segment_size * (bseg % segments_per_file) + base; + fileinfo *fi = &io->fis[fno]; + if (!grn_fileinfo_opened(fi)) { + char path[PATH_MAX]; + gen_pathname(io->path, path, fno); + if (!grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) { + DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map); + } + } else { + DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map); + } + } } grn_rc @@ -1311,6 +1341,49 @@ grn_io_is_locked(grn_io *io) return io ? *io->lock : 0; } +grn_rc +grn_io_flush(grn_ctx *ctx, grn_io *io) +{ + grn_rc rc = GRN_SUCCESS; + struct _grn_io_header *header; + uint32_t aligned_header_size; + + if (!io->path) { + return GRN_SUCCESS; + } + + header = io->header; + aligned_header_size = grn_io_compute_base(header->header_size); + + if (grn_msync(ctx, header, aligned_header_size) != 0) { + return ctx->rc; + } + + if (io->maps) { + uint32_t i; + uint32_t max_mapped_segment; + uint32_t segment_size; + + max_mapped_segment = grn_io_max_segment(io); + segment_size = header->segment_size; + for (i = 0; i < max_mapped_segment; i++) { + grn_io_mapinfo *info = &(io->maps[i]); + if (!info) { + continue; + } + if (!info->map) { + continue; + } + if (grn_msync(ctx, info->map, segment_size) != 0) { + rc = ctx->rc; + break; + } + } + } + + return rc; +} + /** mmap abstraction **/ static size_t mmap_size = 0; @@ -1341,7 +1414,15 @@ grn_mmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, off_t offset, size_t length /* CRITICAL_SECTION_ENTER(fi->cs); */ /* try to create fmo */ *fmo = CreateFileMapping(fi->fh, NULL, PAGE_READWRITE, 0, offset + length, NULL); - if (!*fmo) { return NULL; } + if (!*fmo) { + SERR("CreateFileMapping"); + GRN_LOG(ctx, GRN_LOG_ERROR, + "CreateFileMapping(%lu + %" GRN_FMT_SIZE ") failed " + "<%" GRN_FMT_SIZE ">", + (DWORD)offset, length, + mmap_size); + return NULL; + } res = MapViewOfFile(*fmo, FILE_MAP_WRITE, 0, (DWORD)offset, (SIZE_T)length); if (!res) { SERR("MapViewOfFile"); @@ -1486,16 +1567,22 @@ grn_fileinfo_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags /* may be wrong if flags is just only O_RDWR */ if ((flags & O_CREAT)) { DWORD dwCreationDisposition; + const char *flags_description; if (flags & O_EXCL) { dwCreationDisposition = CREATE_NEW; + flags_description = "O_RDWR|O_CREAT|O_EXCL"; } else { dwCreationDisposition = OPEN_ALWAYS; + flags_description = "O_RDWR|O_CREAT"; } fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0); if (fi->fh == INVALID_HANDLE_VALUE) { SERR("CreateFile"); + GRN_LOG(ctx, GRN_LOG_ERROR, + "CreateFile(<%s>, <%s>) failed", + path, flags_description); goto exit; } goto exit; @@ -1508,6 +1595,9 @@ grn_fileinfo_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (fi->fh == INVALID_HANDLE_VALUE) { SERR("CreateFile"); + GRN_LOG(ctx, GRN_LOG_ERROR, + "CreateFile(<%s>, <O_RDWR|O_TRUNC>) failed", + path); goto exit; } goto exit; @@ -1518,6 +1608,9 @@ grn_fileinfo_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (fi->fh == INVALID_HANDLE_VALUE) { SERR("CreateFile"); + GRN_LOG(ctx, GRN_LOG_ERROR, + "CreateFile(<%s>, <O_RDWR>) failed", + path); goto exit; } @@ -1636,8 +1729,18 @@ grn_fileinfo_opened(fileinfo *fi) inline static int grn_msync(grn_ctx *ctx, void *start, size_t length) { - /* return value may be wrong... */ - return FlushViewOfFile(start, length); + BOOL succeeded; + + succeeded = FlushViewOfFile(start, length); + if (succeeded) { + return 0; + } else { + SERR("FlushViewOfFile"); + GRN_LOG(ctx, GRN_LOG_ERROR, + "FlushViewOfFile(<%p>, <%" GRN_FMT_SIZE ">) failed", + start, length); + return -1; + } } inline static grn_rc @@ -1693,10 +1796,16 @@ grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) grn_open(fi->fd, path, flags); if (fi->fd == -1) { ERRNO_ERR(path); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to open file info path: <%s>", + path); return ctx->rc; } if (fstat(fi->fd, &st) == -1) { ERRNO_ERR(path); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to stat file info path: <%s>", + path); return ctx->rc; } fi->dev = st.st_dev; diff --git a/storage/mroonga/vendor/groonga/lib/logger.c b/storage/mroonga/vendor/groonga/lib/logger.c index fc9fe71767e..5a85de3d43e 100644 --- a/storage/mroonga/vendor/groonga/lib/logger.c +++ b/storage/mroonga/vendor/groonga/lib/logger.c @@ -314,9 +314,6 @@ grn_logger_put(grn_ctx *ctx, grn_log_level level, void grn_logger_init(void) { - if (!default_logger_path) { - default_logger_path = grn_strdup_raw(GRN_LOG_PATH); - } grn_memcpy(¤t_logger, &default_logger, sizeof(grn_logger)); CRITICAL_SECTION_INIT(default_logger_lock); } @@ -572,6 +569,7 @@ grn_query_logger_fin(grn_ctx *ctx) current_query_logger_fin(ctx); if (default_query_logger_path) { free(default_query_logger_path); + default_query_logger_path = NULL; } CRITICAL_SECTION_FIN(default_query_logger_lock); } diff --git a/storage/mroonga/vendor/groonga/lib/mrb.c b/storage/mroonga/vendor/groonga/lib/mrb.c index 60d2172d520..d406c2d356a 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb.c +++ b/storage/mroonga/vendor/groonga/lib/mrb.c @@ -20,6 +20,8 @@ #include "grn_ctx_impl.h" #include "grn_util.h" +#include <string.h> + #ifdef GRN_WITH_MRUBY # include <mruby/proc.h> # include <mruby/compile.h> @@ -35,6 +37,16 @@ #define BUFFER_SIZE 2048 #define E_LOAD_ERROR (mrb_class_get(mrb, "LoadError")) +static char grn_mrb_ruby_scripts_dir[GRN_ENV_BUFFER_SIZE]; + +void +grn_mrb_init_from_env(void) +{ + grn_getenv("GRN_RUBY_SCRIPTS_DIR", + grn_mrb_ruby_scripts_dir, + GRN_ENV_BUFFER_SIZE); +} + #ifdef GRN_WITH_MRUBY # ifdef WIN32 static char *win32_ruby_scripts_dir = NULL; @@ -68,13 +80,8 @@ grn_mrb_get_default_system_ruby_scripts_dir(void) const char * grn_mrb_get_system_ruby_scripts_dir(grn_ctx *ctx) { - static char ruby_scripts_dir[GRN_ENV_BUFFER_SIZE]; - - grn_getenv("GRN_RUBY_SCRIPTS_DIR", - ruby_scripts_dir, - GRN_ENV_BUFFER_SIZE); - if (ruby_scripts_dir[0]) { - return ruby_scripts_dir; + if (grn_mrb_ruby_scripts_dir[0]) { + return grn_mrb_ruby_scripts_dir; } else { return grn_mrb_get_default_system_ruby_scripts_dir(); } diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c index f19bcfa9563..f90a7c6a639 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c @@ -23,6 +23,7 @@ #include <mruby/class.h> #include <mruby/data.h> +#include "mrb_ctx.h" #include "mrb_array.h" static struct mrb_data_type mrb_grn_array_type = { @@ -31,6 +32,33 @@ static struct mrb_data_type mrb_grn_array_type = { }; static mrb_value +mrb_grn_array_singleton_create(mrb_state *mrb, mrb_value klass) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + char *name; + mrb_int name_length; + const char *path = NULL; + mrb_value mrb_value_type; + grn_obj *value_type = NULL; + grn_obj *array; + + mrb_get_args(mrb, "so", &name, &name_length, &mrb_value_type); + if (!mrb_nil_p(mrb_value_type)) { + value_type = DATA_PTR(mrb_value_type); + } + + array = grn_table_create(ctx, + name, name_length, + path, + GRN_TABLE_NO_KEY, + NULL, + value_type); + grn_mrb_ctx_check(mrb); + + return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, array)); +} + +static mrb_value mrb_grn_array_initialize(mrb_state *mrb, mrb_value self) { mrb_value mrb_array_ptr; @@ -54,6 +82,10 @@ grn_mrb_array_init(grn_ctx *ctx) klass = mrb_define_class_under(mrb, module, "Array", table_class); MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); + mrb_define_singleton_method(mrb, (struct RObject *)klass, "create", + mrb_grn_array_singleton_create, + MRB_ARGS_REQ(2)); + mrb_define_method(mrb, klass, "initialize", mrb_grn_array_initialize, MRB_ARGS_REQ(1)); } diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c index eb57a016148..84cfb8dc204 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c @@ -28,6 +28,7 @@ #include "../grn_db.h" #include "mrb_bulk.h" +#include "mrb_object.h" static struct mrb_data_type mrb_grn_bulk_type = { "Groonga::Bulk", @@ -136,27 +137,47 @@ grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk) break; default : { -#define MESSAGE_SIZE 4096 - char message[MESSAGE_SIZE]; grn_obj *domain; - char domain_name[GRN_TABLE_MAX_KEY_SIZE]; - int domain_name_size; + grn_bool is_record = GRN_FALSE; domain = grn_ctx_at(ctx, bulk->header.domain); if (domain) { - domain_name_size = grn_obj_name(ctx, domain, - domain_name, GRN_TABLE_MAX_KEY_SIZE); + switch (domain->header.type) { + case GRN_TABLE_HASH_KEY : + case GRN_TABLE_PAT_KEY : + case GRN_TABLE_DAT_KEY : + case GRN_TABLE_NO_KEY : + is_record = GRN_TRUE; + break; + default : + break; + } + } + + if (is_record) { + mrb_value_ = mrb_fixnum_value(GRN_RECORD_VALUE(bulk)); grn_obj_unlink(ctx, domain); } else { - grn_strcpy(domain_name, GRN_TABLE_MAX_KEY_SIZE, "unknown"); - domain_name_size = strlen(domain_name); +#define MESSAGE_SIZE 4096 + char message[MESSAGE_SIZE]; + char domain_name[GRN_TABLE_MAX_KEY_SIZE]; + int domain_name_size; + + if (domain) { + domain_name_size = grn_obj_name(ctx, domain, + domain_name, GRN_TABLE_MAX_KEY_SIZE); + grn_obj_unlink(ctx, domain); + } else { + grn_strcpy(domain_name, GRN_TABLE_MAX_KEY_SIZE, "unknown"); + domain_name_size = strlen(domain_name); + } + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "unsupported bulk value type: <%d>(%.*s)", + bulk->header.domain, + domain_name_size, + domain_name); + mrb_raise(mrb, E_RANGE_ERROR, message); } - grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, - "unsupported bulk value type: <%d>(%.*s)", - bulk->header.domain, - domain_name_size, - domain_name); - mrb_raise(mrb, E_RANGE_ERROR, message); #undef MESSAGE_SIZE } break; @@ -234,5 +255,7 @@ grn_mrb_bulk_init(grn_ctx *ctx) mrb_grn_bulk_get_value, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "==", mrb_grn_bulk_equal, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "inspect", + grn_mrb_object_inspect, MRB_ARGS_NONE()); } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c index 1d3bbb69422..68aadce6658 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c @@ -25,9 +25,25 @@ #include "mrb_ctx.h" #include "mrb_column.h" +#include "mrb_bulk.h" #include "mrb_converter.h" static mrb_value +mrb_grn_column_array_reference(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *column; + grn_id record_id; + grn_obj *column_value; + + column = DATA_PTR(self); + mrb_get_args(mrb, "i", &record_id); + + column_value = grn_obj_get_value(ctx, column, record_id, NULL); + return grn_mrb_value_from_grn_obj(mrb, column_value); +} + +static mrb_value mrb_grn_column_is_locked(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; @@ -65,6 +81,9 @@ grn_mrb_column_init(grn_ctx *ctx) klass = mrb_define_class_under(mrb, module, "Column", object_class); MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); + mrb_define_method(mrb, klass, "[]", + mrb_grn_column_array_reference, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "locked?", mrb_grn_column_is_locked, MRB_ARGS_NONE()); diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c index f39202398d1..07c0a74dd31 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c @@ -27,6 +27,7 @@ #include <mruby/string.h> #include "mrb_ctx.h" +#include "mrb_converter.h" #include "mrb_command_input.h" static struct mrb_data_type mrb_grn_command_input_type = { @@ -102,6 +103,19 @@ mrb_grn_command_input_array_reference(mrb_state *mrb, mrb_value self) GRN_TEXT_LEN(argument)); } +static mrb_value +mrb_grn_command_input_get_arguments(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_command_input *input; + grn_obj *arguments; + + input = DATA_PTR(self); + arguments = grn_command_input_get_arguments(ctx, input); + + return grn_mrb_value_from_grn_obj(mrb, arguments); +} + void grn_mrb_command_input_init(grn_ctx *ctx) { @@ -118,5 +132,8 @@ grn_mrb_command_input_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "[]", mrb_grn_command_input_array_reference, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, klass, "arguments", + mrb_grn_command_input_get_arguments, MRB_ARGS_NONE()); } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c index e4c3aceb435..387d921b6d0 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c @@ -130,7 +130,7 @@ grn_mrb_value_to_raw_data(mrb_state *mrb, "%S: failed to convert to %S: %S", mrb_str_new_static(mrb, context, strlen(context)), mrb_str_new_static(mrb, domain_name, domain_name_size), - mrb_value_); + mrb_funcall(mrb, mrb_value_, "inspect", 0)); } *raw_value = GRN_BULK_HEAD(&(buffer->to)); *raw_value_size = GRN_BULK_VSIZE(&(buffer->to)); diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c index eb85ff955fa..2af198c2fdb 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c @@ -24,6 +24,7 @@ #include <mruby/class.h> #include <mruby/data.h> +#include "mrb_ctx.h" #include "mrb_converter.h" #include "mrb_index_column.h" #include "mrb_operator.h" @@ -77,14 +78,22 @@ mrb_grn_index_column_estimate_size_for_query(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *index_column; - char *query; - mrb_int query_len; + grn_obj *lexicon; + mrb_value mrb_query; + void *query; + unsigned int query_size; + grn_mrb_value_to_raw_data_buffer buffer; mrb_value mrb_options = mrb_nil_value(); grn_search_optarg optarg; unsigned int size; index_column = DATA_PTR(self); - mrb_get_args(mrb, "s|H", &query, &query_len, &mrb_options); + mrb_get_args(mrb, "o|H", &mrb_query, &mrb_options); + + lexicon = grn_ctx_at(ctx, index_column->header.domain); + grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer); + grn_mrb_value_to_raw_data(mrb, "query", mrb_query, lexicon->header.domain, + &buffer, &query, &query_size); memset(&optarg, 0, sizeof(grn_search_optarg)); optarg.mode = GRN_OP_EXACT; @@ -99,7 +108,11 @@ mrb_grn_index_column_estimate_size_for_query(mrb_state *mrb, mrb_value self) } size = grn_ii_estimate_size_for_query(ctx, (grn_ii *)index_column, - query, query_len, &optarg); + query, query_size, &optarg); + grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer); + + grn_mrb_ctx_check(mrb); + return mrb_fixnum_value(size); } diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c index 8efaa41e50d..77eb4ef3025 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c @@ -26,12 +26,13 @@ #include <mruby/data.h> #include "../grn_mrb.h" +#include "mrb_ctx.h" #include "mrb_object.h" #include "mrb_operator.h" #include "mrb_converter.h" -static mrb_value -object_inspect(mrb_state *mrb, mrb_value self) +mrb_value +grn_mrb_object_inspect(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *object; @@ -170,6 +171,21 @@ object_close(mrb_state *mrb, mrb_value self) } static mrb_value +object_remove(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *object; + + object = DATA_PTR(self); + grn_obj_remove(ctx, object); + grn_mrb_ctx_check(mrb); + + DATA_PTR(self) = NULL; + + return mrb_nil_value(); +} + +static mrb_value object_get_domain_id(mrb_state *mrb, mrb_value self) { grn_obj *object; @@ -237,7 +253,7 @@ grn_mrb_object_init(grn_ctx *ctx) data->object_class = klass; mrb_define_method(mrb, klass, "inspect", - object_inspect, MRB_ARGS_NONE()); + grn_mrb_object_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "id", object_get_id, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "name", object_get_name, MRB_ARGS_NONE()); @@ -247,6 +263,7 @@ grn_mrb_object_init(grn_ctx *ctx) object_grn_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "==", object_equal, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "close", object_close, MRB_ARGS_NONE()); + mrb_define_method(mrb, klass, "remove", object_remove, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "domain_id", object_get_domain_id, MRB_ARGS_NONE()); diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h index 97a586c0f11..82468bd0156 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h @@ -27,6 +27,8 @@ extern "C" { void grn_mrb_object_init(grn_ctx *ctx); +mrb_value grn_mrb_object_inspect(mrb_state *mrb, mrb_value self); + #ifdef __cplusplus } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c index 651a77e4549..2b9e00d8f04 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c @@ -66,6 +66,25 @@ mrb_grn_table_array_reference(mrb_state *mrb, mrb_value self) } static mrb_value +mrb_grn_table_find_column(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *table; + mrb_value mrb_column_name; + grn_obj *column; + + mrb_get_args(mrb, "o", &mrb_column_name); + + table = DATA_PTR(self); + column = grn_obj_column(ctx, table, + RSTRING_PTR(mrb_column_name), + RSTRING_LEN(mrb_column_name)); + grn_mrb_ctx_check(mrb); + + return grn_mrb_value_from_grn_obj(mrb, column); +} + +static mrb_value mrb_grn_table_is_locked(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; @@ -138,22 +157,21 @@ mrb_grn_table_select(mrb_state *mrb, mrb_value self) return grn_mrb_value_from_grn_obj(mrb, result); } -/* TODO: Fix memory leak on error */ static mrb_value -mrb_grn_table_sort(mrb_state *mrb, mrb_value self) +mrb_grn_table_sort_raw(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *table; - grn_obj *result = NULL; + mrb_value mrb_keys; grn_table_sort_key *keys; int i, n_keys; - int offset = 0; - int limit = -1; - mrb_value mrb_keys; - mrb_value mrb_options = mrb_nil_value(); + mrb_int offset; + mrb_int limit; + mrb_value mrb_result; + grn_obj *result; table = DATA_PTR(self); - mrb_get_args(mrb, "o|H", &mrb_keys, &mrb_options); + mrb_get_args(mrb, "oiio", &mrb_keys, &offset, &limit, &mrb_result); mrb_keys = mrb_convert_type(mrb, mrb_keys, MRB_TT_ARRAY, "Array", "to_ary"); @@ -161,69 +179,118 @@ mrb_grn_table_sort(mrb_state *mrb, mrb_value self) n_keys = RARRAY_LEN(mrb_keys); keys = GRN_MALLOCN(grn_table_sort_key, n_keys); for (i = 0; i < n_keys; i++) { - mrb_value mrb_sort_options; - mrb_value mrb_sort_key; - mrb_value mrb_sort_order; - - mrb_sort_options = RARRAY_PTR(mrb_keys)[i]; - mrb_sort_key = grn_mrb_options_get_lit(mrb, mrb_sort_options, "key"); - switch (mrb_type(mrb_sort_key)) { - case MRB_TT_STRING : - keys[i].key = grn_obj_column(ctx, table, - RSTRING_PTR(mrb_sort_key), - RSTRING_LEN(mrb_sort_key)); - break; - case MRB_TT_SYMBOL : - { - const char *name; - mrb_int name_length; - name = mrb_sym2name_len(mrb, mrb_symbol(mrb_sort_key), &name_length); - keys[i].key = grn_obj_column(ctx, table, name, name_length); - } - break; - default : - /* TODO: free */ - mrb_raisef(mrb, E_ARGUMENT_ERROR, - "sort key must be string or symbol: %S", - mrb_sort_key); - break; - } - - keys[i].flags = 0; - mrb_sort_order = grn_mrb_options_get_lit(mrb, mrb_sort_options, "order"); - if (mrb_nil_p(mrb_sort_order) || - (mrb_symbol(mrb_sort_order) == mrb_intern_lit(mrb, "ascending"))) { - keys[i].flags |= GRN_TABLE_SORT_ASC; - } else { - keys[i].flags |= GRN_TABLE_SORT_DESC; - } + memcpy(&(keys[i]), + DATA_PTR(RARRAY_PTR(mrb_keys)[i]), + sizeof(grn_table_sort_key)); } + result = DATA_PTR(mrb_result); + grn_table_sort(ctx, table, offset, limit, result, keys, n_keys); + GRN_FREE(keys); + grn_mrb_ctx_check(mrb); - if (!mrb_nil_p(mrb_options)) { - mrb_value mrb_offset; - mrb_value mrb_limit; + return mrb_result; +} - mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset"); - if (!mrb_nil_p(mrb_offset)) { - offset = mrb_fixnum(mrb_offset); - } +static mrb_value +mrb_grn_table_group_raw(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *table; + mrb_value mrb_keys; + grn_table_sort_key *keys; + int i, n_keys; + mrb_value mrb_result; + grn_table_group_result *result; - mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit"); - if (!mrb_nil_p(mrb_limit)) { - limit = mrb_fixnum(mrb_limit); - } - } + table = DATA_PTR(self); + mrb_get_args(mrb, "oo", &mrb_keys, &mrb_result); - result = grn_table_create(ctx, NULL, 0, NULL, GRN_TABLE_NO_KEY, - NULL, table); - grn_table_sort(ctx, table, offset, limit, result, keys, n_keys); + mrb_keys = mrb_convert_type(mrb, mrb_keys, + MRB_TT_ARRAY, "Array", "to_ary"); + + n_keys = RARRAY_LEN(mrb_keys); + keys = GRN_MALLOCN(grn_table_sort_key, n_keys); for (i = 0; i < n_keys; i++) { - grn_obj_unlink(ctx, keys[i].key); + memcpy(&(keys[i]), + DATA_PTR(RARRAY_PTR(mrb_keys)[i]), + sizeof(grn_table_sort_key)); } + result = DATA_PTR(mrb_result); + grn_table_group(ctx, table, keys, n_keys, result, 1); GRN_FREE(keys); grn_mrb_ctx_check(mrb); - return grn_mrb_value_from_grn_obj(mrb, result); + return mrb_result; +} + +static mrb_value +mrb_grn_table_delete(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *table; + mrb_value mrb_options; + mrb_value mrb_id; + mrb_value mrb_key; + mrb_value mrb_expression; + + table = DATA_PTR(self); + mrb_get_args(mrb, "H", &mrb_options); + + mrb_id = grn_mrb_options_get_lit(mrb, mrb_options, "id"); + if (!mrb_nil_p(mrb_id)) { + grn_table_delete_by_id(ctx, table, mrb_fixnum(mrb_id)); + grn_mrb_ctx_check(mrb); + return mrb_nil_value(); + } + + mrb_key = grn_mrb_options_get_lit(mrb, mrb_options, "key"); + if (!mrb_nil_p(mrb_key)) { + grn_id key_domain_id; + void *key; + unsigned int key_size; + grn_mrb_value_to_raw_data_buffer buffer; + + key_domain_id = table->header.domain; + grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer); + grn_mrb_value_to_raw_data(mrb, "key", mrb_key, key_domain_id, + &buffer, &key, &key_size); + grn_table_delete(ctx, table, key, key_size); + grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer); + grn_mrb_ctx_check(mrb); + return mrb_nil_value(); + } + + mrb_expression = grn_mrb_options_get_lit(mrb, mrb_options, "expression"); + if (!mrb_nil_p(mrb_expression)) { + grn_obj *expression; + grn_obj *selected_records; + grn_table_cursor *cursor; + + expression = DATA_PTR(mrb_expression); + selected_records = grn_table_select(ctx, table, expression, NULL, GRN_OP_OR); + grn_mrb_ctx_check(mrb); + cursor = grn_table_cursor_open(ctx, selected_records, + NULL, 0, + NULL, 0, + 0, -1, 0); + if (cursor) { + while (grn_table_cursor_next(ctx, cursor) != GRN_ID_NIL) { + grn_id *id; + grn_table_cursor_get_key(ctx, cursor, (void **)&id); + grn_table_delete_by_id(ctx, table, *id); + } + grn_table_cursor_close(ctx, cursor); + } + grn_mrb_ctx_check(mrb); + + return mrb_nil_value(); + } + + mrb_raisef(mrb, E_ARGUMENT_ERROR, + "must have :id, :key or :expression: %S", + mrb_options); + + return mrb_nil_value(); } void @@ -241,6 +308,9 @@ grn_mrb_table_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "[]", mrb_grn_table_array_reference, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "find_column", + mrb_grn_table_find_column, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "locked?", mrb_grn_table_is_locked, MRB_ARGS_NONE()); @@ -251,7 +321,13 @@ grn_mrb_table_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "select", mrb_grn_table_select, MRB_ARGS_ARG(1, 1)); - mrb_define_method(mrb, klass, "sort", - mrb_grn_table_sort, MRB_ARGS_ARG(1, 1)); + mrb_define_method(mrb, klass, "sort_raw", + mrb_grn_table_sort_raw, MRB_ARGS_REQ(4)); + mrb_define_method(mrb, klass, "group_raw", + mrb_grn_table_group_raw, MRB_ARGS_REQ(2)); + + mrb_define_method(mrb, klass, "delete", + mrb_grn_table_delete, MRB_ARGS_REQ(1)); + } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.c new file mode 100644 index 00000000000..9419f1b7939 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.c @@ -0,0 +1,48 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../grn_ctx_impl.h" + +#ifdef GRN_WITH_MRUBY +#include <mruby.h> +#include <mruby/class.h> + +#include "mrb_table_group_flags.h" + +void +grn_mrb_table_group_flags_init(grn_ctx *ctx) +{ + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + struct RClass *module = data->module; + struct RClass *flags_module; + + flags_module = mrb_define_module_under(mrb, module, "TableGroupFlags"); + + mrb_define_const(mrb, flags_module, "CALC_COUNT", + mrb_fixnum_value(GRN_TABLE_GROUP_CALC_COUNT)); + mrb_define_const(mrb, flags_module, "CALC_MAX", + mrb_fixnum_value(GRN_TABLE_GROUP_CALC_MAX)); + mrb_define_const(mrb, flags_module, "CALC_MIN", + mrb_fixnum_value(GRN_TABLE_GROUP_CALC_MIN)); + mrb_define_const(mrb, flags_module, "CALC_SUM", + mrb_fixnum_value(GRN_TABLE_GROUP_CALC_SUM)); + mrb_define_const(mrb, flags_module, "CALC_AVG", + mrb_fixnum_value(GRN_TABLE_GROUP_CALC_AVG)); +} +#endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h new file mode 100644 index 00000000000..fda2a9be82f --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h @@ -0,0 +1,34 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GRN_MRB_TABLE_GROUP_FLAGS_H +#define GRN_MRB_TABLE_GROUP_FLAGS_H + +#include "../grn_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void grn_mrb_table_group_flags_init(grn_ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_MRB_TABLE_GROUP_FLAGS_H */ diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c new file mode 100644 index 00000000000..970ebd06220 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c @@ -0,0 +1,250 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../grn_ctx_impl.h" + +#ifdef GRN_WITH_MRUBY +#include <mruby.h> +#include <mruby/class.h> +#include <mruby/data.h> +#include <mruby/hash.h> +#include <mruby/array.h> +#include <mruby/string.h> + +#include "mrb_ctx.h" +#include "mrb_converter.h" +#include "mrb_operator.h" +#include "mrb_table_group_result.h" + +static void +mrb_grn_table_group_result_free(mrb_state *mrb, void *data) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_table_group_result *result = data; + + if (!result) { + return; + } + + if (result->calc_target) { + grn_obj_unlink(ctx, result->calc_target); + } + if (result->table) { + grn_obj_unlink(ctx, result->table); + } + mrb_free(mrb, result); +} + +static struct mrb_data_type mrb_grn_table_group_result_type = { + "Groonga::TableGroupResult", + mrb_grn_table_group_result_free +}; + +static mrb_value +mrb_grn_table_group_result_initialize(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + + DATA_TYPE(self) = &mrb_grn_table_group_result_type; + + result = mrb_calloc(mrb, 1, sizeof(grn_table_group_result)); + DATA_PTR(self) = result; + + return self; +} + + +static mrb_value +mrb_grn_table_group_result_close(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + + result = DATA_PTR(self); + if (result) { + mrb_grn_table_group_result_free(mrb, result); + DATA_PTR(self) = NULL; + } + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_group_result_get_table(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + + result = DATA_PTR(self); + + return grn_mrb_value_from_grn_obj(mrb, result->table); +} + +static mrb_value +mrb_grn_table_group_result_set_table(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + mrb_value mrb_table; + + result = DATA_PTR(self); + mrb_get_args(mrb, "o", &mrb_table); + + if (mrb_nil_p(mrb_table)) { + result->table = NULL; + } else { + result->table = DATA_PTR(mrb_table); + } + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_group_result_set_key_begin(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + mrb_int key_begin; + + result = DATA_PTR(self); + mrb_get_args(mrb, "i", &key_begin); + + result->key_begin = key_begin; + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_group_result_set_key_end(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + mrb_int key_end; + + result = DATA_PTR(self); + mrb_get_args(mrb, "i", &key_end); + + result->key_end = key_end; + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_group_result_set_limit(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + mrb_int limit; + + result = DATA_PTR(self); + mrb_get_args(mrb, "i", &limit); + + result->limit = limit; + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_group_result_set_flags(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + mrb_int flags; + + result = DATA_PTR(self); + mrb_get_args(mrb, "i", &flags); + + result->flags = flags; + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_group_result_set_operator(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + mrb_value mrb_operator; + + result = DATA_PTR(self); + mrb_get_args(mrb, "o", &mrb_operator); + + result->op = grn_mrb_value_to_operator(mrb, mrb_operator); + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_group_result_set_max_n_subrecs(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + mrb_int max_n_subrecs; + + result = DATA_PTR(self); + mrb_get_args(mrb, "i", &max_n_subrecs); + + result->max_n_subrecs = max_n_subrecs; + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_group_result_set_calc_target(mrb_state *mrb, mrb_value self) +{ + grn_table_group_result *result; + mrb_value mrb_calc_target; + + result = DATA_PTR(self); + mrb_get_args(mrb, "o", &mrb_calc_target); + + result->calc_target = DATA_PTR(mrb_calc_target); + + return mrb_nil_value(); +} + +void +grn_mrb_table_group_result_init(grn_ctx *ctx) +{ + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + struct RClass *module = data->module; + struct RClass *klass; + + klass = mrb_define_class_under(mrb, module, "TableGroupResult", + mrb->object_class); + MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); + + mrb_define_method(mrb, klass, "initialize", + mrb_grn_table_group_result_initialize, MRB_ARGS_NONE()); + + mrb_define_method(mrb, klass, "close", + mrb_grn_table_group_result_close, MRB_ARGS_NONE()); + + mrb_define_method(mrb, klass, "table", + mrb_grn_table_group_result_get_table, MRB_ARGS_NONE()); + mrb_define_method(mrb, klass, "table=", + mrb_grn_table_group_result_set_table, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "key_begin=", + mrb_grn_table_group_result_set_key_begin, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "key_end=", + mrb_grn_table_group_result_set_key_end, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "limit=", + mrb_grn_table_group_result_set_limit, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "flags=", + mrb_grn_table_group_result_set_flags, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "operator=", + mrb_grn_table_group_result_set_operator, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "max_n_subrecs=", + mrb_grn_table_group_result_set_max_n_subrecs, + MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "calc_target=", + mrb_grn_table_group_result_set_calc_target, MRB_ARGS_REQ(1)); +} +#endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h new file mode 100644 index 00000000000..cc3c70ff3bb --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h @@ -0,0 +1,34 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GRN_MRB_TABLE_GROUP_RESULT_H +#define GRN_MRB_TABLE_GROUP_RESULT_H + +#include "../grn_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void grn_mrb_table_group_result_init(grn_ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_MRB_TABLE_GROUP_RESULT_H */ diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c new file mode 100644 index 00000000000..0c402591042 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c @@ -0,0 +1,42 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../grn_ctx_impl.h" + +#ifdef GRN_WITH_MRUBY +#include <mruby.h> +#include <mruby/class.h> + +#include "mrb_table_sort_flags.h" + +void +grn_mrb_table_sort_flags_init(grn_ctx *ctx) +{ + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + struct RClass *module = data->module; + struct RClass *flags_module; + + flags_module = mrb_define_module_under(mrb, module, "TableSortFlags"); + + mrb_define_const(mrb, flags_module, "ASCENDING", + mrb_fixnum_value(GRN_TABLE_SORT_ASC)); + mrb_define_const(mrb, flags_module, "DESCENDING", + mrb_fixnum_value(GRN_TABLE_SORT_DESC)); +} +#endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h new file mode 100644 index 00000000000..0b5c40b9993 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h @@ -0,0 +1,34 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GRN_MRB_TABLE_SORT_FLAGS_H +#define GRN_MRB_TABLE_SORT_FLAGS_H + +#include "../grn_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void grn_mrb_table_sort_flags_init(grn_ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_MRB_TABLE_SORT_FLAGS_H */ diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c new file mode 100644 index 00000000000..3313cceebb6 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c @@ -0,0 +1,157 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../grn_ctx_impl.h" + +#ifdef GRN_WITH_MRUBY +#include <mruby.h> +#include <mruby/class.h> +#include <mruby/data.h> +#include <mruby/hash.h> +#include <mruby/array.h> +#include <mruby/string.h> + +#include "mrb_ctx.h" +#include "mrb_table_sort_key.h" + +static void +mrb_grn_table_sort_key_free(mrb_state *mrb, void *data) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_table_sort_key *sort_key = data; + + if (!sort_key) { + return; + } + + if (sort_key->key) { + grn_obj_unlink(ctx, sort_key->key); + } + mrb_free(mrb, sort_key); +} + +static struct mrb_data_type mrb_grn_table_sort_key_type = { + "Groonga::TableSortKey", + mrb_grn_table_sort_key_free +}; + +static mrb_value +mrb_grn_table_sort_key_initialize(mrb_state *mrb, mrb_value self) +{ + grn_table_sort_key *result; + + DATA_TYPE(self) = &mrb_grn_table_sort_key_type; + + result = mrb_calloc(mrb, 1, sizeof(grn_table_sort_key)); + DATA_PTR(self) = result; + + return self; +} + + +static mrb_value +mrb_grn_table_sort_key_close(mrb_state *mrb, mrb_value self) +{ + grn_table_sort_key *sort_key; + + sort_key = DATA_PTR(self); + if (sort_key) { + mrb_grn_table_sort_key_free(mrb, sort_key); + DATA_PTR(self) = NULL; + } + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_sort_key_set_key(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_table_sort_key *sort_key; + mrb_value mrb_key; + + sort_key = DATA_PTR(self); + mrb_get_args(mrb, "o", &mrb_key); + + if (sort_key->key) { + grn_obj_unlink(ctx, sort_key->key); + } + + if (mrb_nil_p(mrb_key)) { + sort_key->key = NULL; + } else { + sort_key->key = DATA_PTR(mrb_key); + } + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_sort_key_set_flags(mrb_state *mrb, mrb_value self) +{ + grn_table_sort_key *sort_key; + mrb_int flags; + + sort_key = DATA_PTR(self); + mrb_get_args(mrb, "i", &flags); + + sort_key->flags = flags; + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_table_sort_key_set_offset(mrb_state *mrb, mrb_value self) +{ + grn_table_sort_key *sort_key; + mrb_int offset; + + sort_key = DATA_PTR(self); + mrb_get_args(mrb, "i", &offset); + + sort_key->offset = offset; + + return mrb_nil_value(); +} + +void +grn_mrb_table_sort_key_init(grn_ctx *ctx) +{ + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + struct RClass *module = data->module; + struct RClass *klass; + + klass = mrb_define_class_under(mrb, module, "TableSortKey", + mrb->object_class); + MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); + + mrb_define_method(mrb, klass, "initialize", + mrb_grn_table_sort_key_initialize, MRB_ARGS_NONE()); + + mrb_define_method(mrb, klass, "close", + mrb_grn_table_sort_key_close, MRB_ARGS_NONE()); + + mrb_define_method(mrb, klass, "key=", + mrb_grn_table_sort_key_set_key, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "flags=", + mrb_grn_table_sort_key_set_flags, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "offset=", + mrb_grn_table_sort_key_set_offset, MRB_ARGS_REQ(1)); +} +#endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h new file mode 100644 index 00000000000..1d56bcd6313 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h @@ -0,0 +1,34 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GRN_MRB_TABLE_SORT_KEY_H +#define GRN_MRB_TABLE_SORT_KEY_H + +#include "../grn_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void grn_mrb_table_sort_key_init(grn_ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_MRB_TABLE_SORT_KEY_H */ diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb index 73b44cae3dd..28b80fc3de3 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb @@ -99,7 +99,12 @@ module Groonga def estimate_equal(data, index_column) lexicon = index_column.lexicon - term_id = lexicon[data.query] + query = data.query + if query.domain == lexicon.id + term_id = query.value + else + term_id = lexicon[query] + end return 0 if term_id.nil? index_column.estimate_size(:term_id => term_id) diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb index ea26a031e0a..ccd44758d07 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb @@ -6,6 +6,7 @@ require "writer" require "object" require "database" +require "table" require "index_column" require "command" require "table_cursor" diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am index 5ddcba18d4c..6fda01812b9 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am @@ -19,5 +19,6 @@ RUBY_SCRIPT_FILES = \ scan_info_builder.rb \ scan_info_data.rb \ scan_info_search_index.rb \ + table.rb \ table_cursor.rb \ writer.rb diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb new file mode 100644 index 00000000000..5a1b640c25f --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb @@ -0,0 +1,90 @@ +module Groonga + class Table + def sort(keys, options={}) + offset = options[:offset] || 0 + limit = options[:limit] || -1 + ensure_sort_keys(keys) do |sort_keys| + sorted = Array.create("", self) + begin + sort_raw(sort_keys, offset, limit, sorted) + rescue Exception + sorted.close + raise + end + sorted + end + end + + def group(keys, result) + ensure_sort_keys(keys) do |sort_keys| + group_raw(sort_keys, result) + end + end + + private + def ensure_sort_keys(keys) + if keys.is_a?(::Array) and keys.all? {|key| key.is_a?(TableSortKey)} + return yield(keys) + end + + converted_keys = [] + + begin + keys = [keys] unless keys.is_a?(::Array) + sort_keys = keys.collect do |key| + ensure_sort_key(key, converted_keys) + end + yield(sort_keys) + ensure + converted_keys.each do |converted_key| + converted_key.close + end + end + end + + def ensure_sort_key(key, converted_keys) + return key if key.is_a?(TableSortKey) + + sort_key = TableSortKey.new + converted_keys << sort_key + + key_name = nil + order = :ascending + offset = 0 + if key.is_a?(::Hash) + key_name = key[:key] + order = key[:order] || order + offset = key[:offset] || offset + else + key_name = key + end + + case key_name + when String + # Do nothing + when Symbol + key_name = key_name.to_s + else + message = "sort key name must be String or Symbol: " + + "#{key_name.inspect}: #{key.inspect}" + raise ArgumentError, message + end + + if key_name.start_with?("-") + key_name[0] = "" + order = :descending + elsif key_name.start_with?("+") + key_name[0] = "" + end + + sort_key.key = find_column(key_name) + if order == :ascending + sort_key.flags = Groonga::TableSortFlags::ASCENDING + else + sort_key.flags = Groonga::TableSortFlags::DESCENDING + end + sort_key.offset = offset + sort_key + end + end +end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/sources.am index 5cda570bc37..b27e3654af8 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/sources.am +++ b/storage/mroonga/vendor/groonga/lib/mrb/sources.am @@ -55,6 +55,14 @@ libgrnmrb_la_SOURCES = \ mrb_table_cursor.h \ mrb_table_cursor_flags.c \ mrb_table_cursor_flags.h \ + mrb_table_group_flags.c \ + mrb_table_group_flags.h \ + mrb_table_group_result.c \ + mrb_table_group_result.h \ + mrb_table_sort_flags.c \ + mrb_table_sort_flags.h \ + mrb_table_sort_key.c \ + mrb_table_sort_key.h \ mrb_type.c \ mrb_type.h \ mrb_variable_size_column.c \ diff --git a/storage/mroonga/vendor/groonga/lib/operator.c b/storage/mroonga/vendor/groonga/lib/operator.c index 14a870cd885..e57408e0081 100644 --- a/storage/mroonga/vendor/groonga/lib/operator.c +++ b/storage/mroonga/vendor/groonga/lib/operator.c @@ -612,6 +612,60 @@ grn_operator_exec_greater_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y) } static grn_bool +exec_match_uvector_bulk(grn_ctx *ctx, grn_obj *uvector, grn_obj *query) +{ + grn_bool matched = GRN_FALSE; + unsigned int i, size; + grn_obj element; + unsigned int element_size; + + size = grn_uvector_size(ctx, uvector); + element_size = grn_uvector_element_size(ctx, uvector); + GRN_VALUE_FIX_SIZE_INIT(&element, 0, uvector->header.domain); + for (i = 0; i < size; i++) { + GRN_BULK_REWIND(&element); + grn_bulk_write(ctx, &element, + GRN_BULK_HEAD(uvector) + (element_size * i), + element_size); + if (grn_operator_exec_equal(ctx, &element, query)) { + matched = GRN_TRUE; + break; + } + } + GRN_OBJ_FIN(ctx, &element); + + return matched; +} + +static grn_bool +exec_match_vector_bulk(grn_ctx *ctx, grn_obj *vector, grn_obj *query) +{ + grn_bool matched = GRN_FALSE; + unsigned int i, size; + grn_obj element; + + size = grn_vector_size(ctx, vector); + GRN_VOID_INIT(&element); + for (i = 0; i < size; i++) { + const char *content; + unsigned int content_size; + grn_id domain_id; + + content_size = grn_vector_get_element(ctx, vector, i, + &content, NULL, &domain_id); + grn_obj_reinit(ctx, &element, domain_id, 0); + grn_bulk_write(ctx, &element, content, content_size); + if (grn_operator_exec_equal(ctx, &element, query)) { + matched = GRN_TRUE; + break; + } + } + GRN_OBJ_FIN(ctx, &element); + + return matched; +} + +static grn_bool string_have_sub_text(grn_ctx *ctx, const char *text, unsigned int text_len, const char *sub_text, unsigned int sub_text_len) @@ -905,7 +959,17 @@ grn_operator_exec_match(grn_ctx *ctx, grn_obj *target, grn_obj *sub_text) { grn_bool matched; GRN_API_ENTER; - matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_MATCH, target, sub_text); + switch (target->header.type) { + case GRN_UVECTOR : + matched = exec_match_uvector_bulk(ctx, target, sub_text); + break; + case GRN_VECTOR : + matched = exec_match_vector_bulk(ctx, target, sub_text); + break; + default : + matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_MATCH, target, sub_text); + break; + } GRN_API_RETURN(matched); } diff --git a/storage/mroonga/vendor/groonga/lib/output.c b/storage/mroonga/vendor/groonga/lib/output.c index 0036e9a8619..f78ef75a560 100644 --- a/storage/mroonga/vendor/groonga/lib/output.c +++ b/storage/mroonga/vendor/groonga/lib/output.c @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2009-2014 Brazil +/* Copyright(C) 2009-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,6 +20,7 @@ #include <string.h> #include "grn_str.h" #include "grn_db.h" +#include "grn_expr_code.h" #include "grn_util.h" #include "grn_output.h" @@ -1134,57 +1135,6 @@ count_n_elements_in_expression(grn_ctx *ctx, grn_obj *expression) return n_elements; } -static inline int -count_used_n_codes(grn_ctx *ctx, grn_expr_code *start, grn_expr_code *target) -{ - int n_codes; - int i, n_args; - grn_bool have_proc_push_code = GRN_FALSE; - grn_expr_code *sub_code; - - if (start == target) { - return 0; - } - - n_args = target->nargs; - if (target->op == GRN_OP_CALL) { - if (!target->value) { - have_proc_push_code = GRN_TRUE; - } - } else { - if (target->value) { - n_args--; - if (n_args == 0) { - return 1; - } - } - } - - n_codes = 1; - sub_code = target - 1; - for (i = 0; i < n_args; i++) { - int sub_n_codes; - sub_n_codes = count_used_n_codes(ctx, start, sub_code); - n_codes += sub_n_codes; - sub_code -= sub_n_codes; - if (sub_code < start) { - /* TODO: report error */ - return 0; - } - } - - if (have_proc_push_code) { - n_codes++; - sub_code--; - if (sub_code < start) { - /* TODO: report error */ - return 0; - } - } - - return n_codes; -} - static grn_bool is_score_accessor(grn_ctx *ctx, grn_obj *obj) { @@ -1305,10 +1255,10 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf, have_comma = GRN_TRUE; if (is_first_comma) { - int n_used_codes; + unsigned int n_used_codes; int code_end_offset; - n_used_codes = count_used_n_codes(ctx, expr->codes, code - 1); + n_used_codes = grn_expr_code_n_used_codes(ctx, expr->codes, code - 1); code_end_offset = code - expr->codes - n_used_codes; grn_output_table_column_by_expression(ctx, outbuf, output_type, @@ -1417,13 +1367,13 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf, have_comma = GRN_TRUE; if (is_first_comma) { int second_code_offset; - int second_code_n_used_code; + unsigned int second_code_n_used_codes; second_code_offset = code - expr->codes - 1; - second_code_n_used_code = - count_used_n_codes(ctx, - expr->codes, - expr->codes + second_code_offset); - expr->codes_curr = second_code_offset - second_code_n_used_code + 1; + second_code_n_used_codes = + grn_expr_code_n_used_codes(ctx, + expr->codes, + expr->codes + second_code_offset); + expr->codes_curr = second_code_offset - second_code_n_used_codes + 1; grn_output_table_record_by_expression(ctx, outbuf, output_type, format->expression); code_start_offset = expr->codes_curr; diff --git a/storage/mroonga/vendor/groonga/lib/plugin.c b/storage/mroonga/vendor/groonga/lib/plugin.c index 48ccded0b92..7db19c1a5a5 100644 --- a/storage/mroonga/vendor/groonga/lib/plugin.c +++ b/storage/mroonga/vendor/groonga/lib/plugin.c @@ -66,6 +66,16 @@ static grn_critical_section grn_plugins_lock; #define GRN_PLUGIN_KEY_SIZE(filename) (strlen((filename)) + 1) +static char grn_plugins_dir[GRN_ENV_BUFFER_SIZE]; + +void +grn_plugin_init_from_env(void) +{ + grn_getenv("GRN_PLUGINS_DIR", + grn_plugins_dir, + GRN_ENV_BUFFER_SIZE); +} + static int compute_name_size(const char *name, int name_size) { @@ -513,13 +523,8 @@ grn_plugin_get_default_system_plugins_dir(void) const char * grn_plugin_get_system_plugins_dir(void) { - static char plugins_dir[GRN_ENV_BUFFER_SIZE]; - - grn_getenv("GRN_PLUGINS_DIR", - plugins_dir, - GRN_ENV_BUFFER_SIZE); - if (plugins_dir[0]) { - return plugins_dir; + if (grn_plugins_dir[0]) { + return grn_plugins_dir; } else { return grn_plugin_get_default_system_plugins_dir(); } diff --git a/storage/mroonga/vendor/groonga/lib/proc.c b/storage/mroonga/vendor/groonga/lib/proc.c index fc6aa690e74..86b0fd58c02 100644 --- a/storage/mroonga/vendor/groonga/lib/proc.c +++ b/storage/mroonga/vendor/groonga/lib/proc.c @@ -26,12 +26,17 @@ #include "grn_token_cursor.h" #include "grn_expr.h" +#ifdef GRN_WITH_EGN +# include "grn_egn.h" +#endif /* GRN_WITH_EGN */ + #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #ifdef WIN32 +# include <io.h> # include <share.h> #endif /* WIN32 */ @@ -57,6 +62,36 @@ const char *grn_document_root = NULL; #define GRN_SELECT_INTERNAL_VAR_CONDITION "$condition" #define GRN_SELECT_INTERNAL_VAR_MATCH_COLUMNS "$match_columns" + +static double grn_between_too_many_index_match_ratio = 0.01; +static double grn_in_values_too_many_index_match_ratio = 0.01; + +void +grn_proc_init_from_env(void) +{ + { + char grn_between_too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO", + grn_between_too_many_index_match_ratio_env, + GRN_ENV_BUFFER_SIZE); + if (grn_between_too_many_index_match_ratio_env[0]) { + grn_between_too_many_index_match_ratio = + atof(grn_between_too_many_index_match_ratio_env); + } + } + + { + char grn_in_values_too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_IN_VALUES_TOO_MANY_INDEX_MATCH_RATIO", + grn_in_values_too_many_index_match_ratio_env, + GRN_ENV_BUFFER_SIZE); + if (grn_in_values_too_many_index_match_ratio_env[0]) { + grn_in_values_too_many_index_match_ratio = + atof(grn_in_values_too_many_index_match_ratio_env); + } + } +} + /* bulk must be initialized grn_bulk or grn_msg */ static int grn_bulk_put_from_file(grn_ctx *ctx, grn_obj *bulk, const char *path) @@ -871,6 +906,19 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len, long long int threshold, original_threshold = 0; grn_cache *cache_obj = grn_cache_current_get(ctx); + { + const char *query_end = query + query_len; + int space_len; + while (query < query_end) { + space_len = grn_isspace(query, ctx->encoding); + if (space_len == 0) { + break; + } + query += space_len; + query_len -= space_len; + } + } + cache_key_size = table_len + 1 + match_columns_len + 1 + query_len + 1 + filter_len + 1 + scorer_len + 1 + sortby_len + 1 + output_columns_len + 1 + match_escalation_threshold_len + 1 + @@ -963,6 +1011,19 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len, } if ((table_ = grn_ctx_get(ctx, table, table_len))) { // match_columns_ = grn_obj_column(ctx, table_, match_columns, match_columns_len); +#ifdef GRN_WITH_EGN + if (filter_len && (filter[0] == '?') && + (ctx->impl->output_type == GRN_CONTENT_JSON)) { + ctx->rc = grn_egn_select(ctx, table_, filter + 1, filter_len - 1, + output_columns, output_columns_len, + offset, limit); + if (!ctx->rc && cacheable && cache_key_size <= GRN_CACHE_MAX_KEY_SIZE && + (!cache || cache_len != 2 || cache[0] != 'n' || cache[1] != 'o')) { + grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf); + } + goto exit; + } +#endif /* GRN_WITH_EGN */ if (query_len || filter_len) { grn_obj *v; GRN_EXPR_CREATE_FOR_QUERY(ctx, table_, cond, v); @@ -973,6 +1034,9 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len, grn_expr_parse(ctx, match_columns_, match_columns, match_columns_len, NULL, GRN_OP_MATCH, GRN_OP_AND, GRN_EXPR_SYNTAX_SCRIPT); + if (ctx->rc) { + goto exit; + } } else { /* todo */ } @@ -980,16 +1044,16 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len, if (query_len) { grn_expr_flags flags; grn_obj query_expander_buf; - GRN_TEXT_INIT(&query_expander_buf, 0); flags = GRN_EXPR_SYNTAX_QUERY; if (query_flags_len) { flags |= grn_parse_query_flags(ctx, query_flags, query_flags_len); - } else { - flags |= GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN; if (ctx->rc) { goto exit; } + } else { + flags |= GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN; } + GRN_TEXT_INIT(&query_expander_buf, 0); if (query_expander_len) { if (expand_query(ctx, query, query_len, flags, query_expander, query_expander_len, @@ -3953,6 +4017,7 @@ parse_tokenize_flags(grn_ctx *ctx, grn_obj *flag_names) typedef struct { grn_id id; int32_t position; + grn_bool force_prefix; } tokenize_token; static void @@ -3969,7 +4034,7 @@ output_tokens(grn_ctx *ctx, grn_obj *tokens, grn_obj *lexicon) token = ((tokenize_token *)(GRN_BULK_HEAD(tokens))) + i; - GRN_OUTPUT_MAP_OPEN("TOKEN", 2); + GRN_OUTPUT_MAP_OPEN("TOKEN", 3); GRN_OUTPUT_CSTR("value"); value_size = grn_table_get_key(ctx, lexicon, token->id, @@ -3979,6 +4044,9 @@ output_tokens(grn_ctx *ctx, grn_obj *tokens, grn_obj *lexicon) GRN_OUTPUT_CSTR("position"); GRN_OUTPUT_INT32(token->position); + GRN_OUTPUT_CSTR("force_prefix"); + GRN_OUTPUT_BOOL(token->force_prefix); + GRN_OUTPUT_MAP_CLOSE(); } GRN_OUTPUT_ARRAY_CLOSE(); @@ -4088,6 +4156,7 @@ tokenize(grn_ctx *ctx, grn_obj *lexicon, grn_obj *string, grn_tokenize_mode mode current_token = ((tokenize_token *)(GRN_BULK_CURR(tokens))) - 1; current_token->id = token_id; current_token->position = token_cursor->pos; + current_token->force_prefix = token_cursor->force_prefix; } grn_token_cursor_close(ctx, token_cursor); } @@ -5134,11 +5203,12 @@ run_sub_filter(grn_ctx *ctx, grn_obj *table, case GRN_ACCESSOR : case GRN_COLUMN_FIX_SIZE : case GRN_COLUMN_VAR_SIZE : + case GRN_COLUMN_INDEX : break; default : - /* TODO: put inspected the 1nd argument to message */ + /* TODO: put inspected the 1st argument to message */ ERR(GRN_INVALID_ARGUMENT, - "sub_filter(): the 1nd argument must be column or accessor"); + "sub_filter(): the 1st argument must be column or accessor"); rc = ctx->rc; goto exit; break; @@ -5712,21 +5782,9 @@ selector_between_sequential_search(grn_ctx *ctx, between_data *data, grn_obj *res, grn_operator op) { - double too_many_index_match_ratio = 0.01; - - { - char too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE]; - grn_getenv("GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO", - too_many_index_match_ratio_env, - GRN_ENV_BUFFER_SIZE); - if (too_many_index_match_ratio_env[0]) { - too_many_index_match_ratio = atof(too_many_index_match_ratio_env); - } - } - if (!selector_between_sequential_search_should_use( ctx, table, index, index_table, data, res, op, - too_many_index_match_ratio)) { + grn_between_too_many_index_match_ratio)) { return GRN_FALSE; } @@ -6210,19 +6268,8 @@ selector_in_values_sequential_search(grn_ctx *ctx, { grn_obj *source; int n_existing_records; - double too_many_index_match_ratio = 0.01; - { - char too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE]; - grn_getenv("GRN_IN_VALUES_TOO_MANY_INDEX_MATCH_RATIO", - too_many_index_match_ratio_env, - GRN_ENV_BUFFER_SIZE); - if (too_many_index_match_ratio_env[0]) { - too_many_index_match_ratio = atof(too_many_index_match_ratio_env); - } - } - - if (too_many_index_match_ratio < 0.0) { + if (grn_in_values_too_many_index_match_ratio < 0.0) { return GRN_FALSE; } @@ -6288,9 +6335,11 @@ selector_in_values_sequential_search(grn_ctx *ctx, /* * Same as: - * ((n_existing_record / n_indexed_records) > too_many_index_match_ratio) + * ((n_existing_record / n_indexed_records) > + * grn_in_values_too_many_index_match_ratio) */ - if (n_existing_records > (n_indexed_records * too_many_index_match_ratio)) { + if (n_existing_records > + (n_indexed_records * grn_in_values_too_many_index_match_ratio)) { grn_obj_unlink(ctx, &value_ids); grn_obj_unlink(ctx, source); return GRN_FALSE; @@ -6709,6 +6758,47 @@ proc_plugin_unregister(grn_ctx *ctx, int nargs, grn_obj **args, return NULL; } +static grn_obj * +proc_io_flush(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) +{ + grn_obj *target_name; + grn_obj *recursive; + grn_obj *target; + grn_bool is_recursive; + + target_name = VAR(0); + recursive = VAR(1); + + if (GRN_TEXT_LEN(target_name) > 0) { + target = grn_ctx_get(ctx, + GRN_TEXT_VALUE(target_name), + GRN_TEXT_LEN(target_name)); + if (!target) { + ERR(GRN_INVALID_ARGUMENT, "[io_flush] unknown target: <%.*s>", + (int)GRN_TEXT_LEN(target_name), + GRN_TEXT_VALUE(target_name)); + GRN_OUTPUT_BOOL(GRN_FALSE); + return NULL; + } + } else { + target = grn_ctx_db(ctx); + } + + is_recursive = bool_option_value(recursive, GRN_TRUE); + { + grn_rc rc; + if (is_recursive) { + rc = grn_obj_flush_recursive(ctx, target); + } else { + rc = grn_obj_flush(ctx, target); + } + + GRN_OUTPUT_BOOL(rc == GRN_SUCCESS); + } + + return NULL; +} + #define DEF_VAR(v,name_str) do {\ (v).name = (name_str);\ (v).name_size = GRN_STRLEN(name_str);\ @@ -6987,4 +7077,8 @@ grn_db_init_builtin_query(grn_ctx *ctx) DEF_VAR(vars[0], "name"); DEF_COMMAND("plugin_unregister", proc_plugin_unregister, 1, vars); + + DEF_VAR(vars[0], "target_name"); + DEF_VAR(vars[1], "recursive"); + DEF_COMMAND("io_flush", proc_io_flush, 2, vars); } diff --git a/storage/mroonga/vendor/groonga/lib/sources.am b/storage/mroonga/vendor/groonga/lib/sources.am index 459b73792ab..ab1ad3e81b5 100644 --- a/storage/mroonga/vendor/groonga/lib/sources.am +++ b/storage/mroonga/vendor/groonga/lib/sources.am @@ -11,10 +11,15 @@ libgroonga_la_SOURCES = \ grn_dat.h \ db.c \ grn_db.h \ + egn.cpp \ + grn_egn.h \ + grn_egn.hpp \ error.c \ grn_error.h \ expr.c \ grn_expr.h \ + expr_code.c \ + grn_expr_code.h \ geo.c \ grn_geo.h \ grn.h \ diff --git a/storage/mroonga/vendor/groonga/lib/store.c b/storage/mroonga/vendor/groonga/lib/store.c index 027f86baac8..d43ebb466e3 100644 --- a/storage/mroonga/vendor/groonga/lib/store.c +++ b/storage/mroonga/vendor/groonga/lib/store.c @@ -23,7 +23,8 @@ /* rectangular arrays */ -#define GRN_RA_SEGMENT_SIZE (1 << 22) +#define GRN_RA_W_SEGMENT 22 +#define GRN_RA_SEGMENT_SIZE (1 << GRN_RA_W_SEGMENT) static grn_ra * _grn_ra_create(grn_ctx *ctx, grn_ra *ra, const char *path, unsigned int element_size) @@ -46,7 +47,7 @@ _grn_ra_create(grn_ctx *ctx, grn_ra *ra, const char *path, unsigned int element_ grn_io_set_type(io, GRN_COLUMN_FIX_SIZE); header->element_size = actual_size; n_elm = GRN_RA_SEGMENT_SIZE / header->element_size; - for (w_elm = 22; (1 << w_elm) > n_elm; w_elm--); + for (w_elm = GRN_RA_W_SEGMENT; (1 << w_elm) > n_elm; w_elm--); ra->io = io; ra->header = header; ra->element_mask = n_elm - 1; @@ -89,7 +90,7 @@ grn_ra_open(grn_ctx *ctx, const char *path) return NULL; } n_elm = GRN_RA_SEGMENT_SIZE / header->element_size; - for (w_elm = 22; (1 << w_elm) > n_elm; w_elm--); + for (w_elm = GRN_RA_W_SEGMENT; (1 << w_elm) > n_elm; w_elm--); GRN_DB_OBJ_SET_TYPE(ra, GRN_COLUMN_FIX_SIZE); ra->io = io; ra->header = header; diff --git a/storage/mroonga/vendor/groonga/lib/token_cursor.c b/storage/mroonga/vendor/groonga/lib/token_cursor.c index d98d1d46342..ac1c936110b 100644 --- a/storage/mroonga/vendor/groonga/lib/token_cursor.c +++ b/storage/mroonga/vendor/groonga/lib/token_cursor.c @@ -245,7 +245,7 @@ grn_token_cursor_next(grn_ctx *ctx, grn_token_cursor *token_cursor) continue; } } else { - if (status & GRN_TOKEN_LAST) { + if (status & GRN_TOKEN_REACH_END) { token_cursor->force_prefix = GRN_TRUE; } } diff --git a/storage/mroonga/vendor/groonga/lib/tokenizers.c b/storage/mroonga/vendor/groonga/lib/tokenizers.c index 8ed0b8c37fa..28fd13c33c4 100644 --- a/storage/mroonga/vendor/groonga/lib/tokenizers.c +++ b/storage/mroonga/vendor/groonga/lib/tokenizers.c @@ -473,23 +473,23 @@ typedef struct { grn_tokenizer_token token; grn_tokenizer_query *query; struct { - grn_bool have_begin; - grn_bool have_end; int32_t n_skip_tokens; } get; grn_bool is_begin; grn_bool is_end; - grn_bool is_first_token; + grn_bool is_start_token; grn_bool is_overlapping; const char *next; const char *end; + unsigned int nth_char; + const uint_least8_t *char_types; grn_obj buffer; } grn_regexp_tokenizer; static grn_obj * regexp_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { - unsigned int normalize_flags = 0; + unsigned int normalize_flags = GRN_STRING_WITH_TYPES; grn_tokenizer_query *query; const char *normalized; unsigned int normalized_length_in_bytes; @@ -512,13 +512,11 @@ regexp_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) grn_tokenizer_token_init(ctx, &(tokenizer->token)); tokenizer->query = query; - tokenizer->get.have_begin = GRN_FALSE; - tokenizer->get.have_end = GRN_FALSE; tokenizer->get.n_skip_tokens = 0; tokenizer->is_begin = GRN_TRUE; tokenizer->is_end = GRN_FALSE; - tokenizer->is_first_token = GRN_TRUE; + tokenizer->is_start_token = GRN_TRUE; tokenizer->is_overlapping = GRN_FALSE; grn_string_get_normalized(ctx, tokenizer->query->normalized_query, @@ -526,39 +524,9 @@ regexp_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) NULL); tokenizer->next = normalized; tokenizer->end = tokenizer->next + normalized_length_in_bytes; - - if (tokenizer->query->tokenize_mode == GRN_TOKEN_GET) { - unsigned int query_length = tokenizer->query->length; - if (query_length >= 2) { - const char *query_string = tokenizer->query->ptr; - grn_encoding encoding = tokenizer->query->encoding; - if (query_string[0] == '\\' && query_string[1] == 'A') { - tokenizer->get.have_begin = GRN_TRUE; - /* TODO: It assumes that both "\\" and "A" are normalized to 1 - characters. Normalizer may omit character or expand to - multiple characters. */ - tokenizer->next += grn_charlen_(ctx, tokenizer->next, tokenizer->end, - encoding); - tokenizer->next += grn_charlen_(ctx, tokenizer->next, tokenizer->end, - encoding); - } - if (query_string[query_length - 2] == '\\' && - query_string[query_length - 1] == 'z') { - tokenizer->get.have_end = GRN_TRUE; - /* TODO: It assumes that both "\\" and "z" are normalized to 1 - byte characters. Normalizer may omit character or expand to - multiple characters. */ - tokenizer->end -= grn_charlen_(ctx, - tokenizer->end - 1, - tokenizer->end, - encoding); - tokenizer->end -= grn_charlen_(ctx, - tokenizer->end - 1, - tokenizer->end, - encoding); - } - } - } + tokenizer->nth_char = 0; + tokenizer->char_types = + grn_string_get_types(ctx, tokenizer->query->normalized_query); GRN_TEXT_INIT(&(tokenizer->buffer), 0); @@ -576,23 +544,32 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) grn_obj *buffer = &(tokenizer->buffer); const char *current = tokenizer->next; const char *end = tokenizer->end; + const const uint_least8_t *char_types = tokenizer->char_types; grn_tokenize_mode mode = tokenizer->query->tokenize_mode; - grn_bool escaping = GRN_FALSE; + grn_bool is_begin = tokenizer->is_begin; + grn_bool is_start_token = tokenizer->is_start_token; + grn_bool break_by_blank = GRN_FALSE; + grn_bool break_by_end_mark = GRN_FALSE; GRN_BULK_REWIND(buffer); + tokenizer->is_begin = GRN_FALSE; + tokenizer->is_start_token = GRN_FALSE; - if (mode == GRN_TOKEN_GET) { - if (tokenizer->get.have_begin) { + if (char_types) { + char_types += tokenizer->nth_char; + } + + if (mode != GRN_TOKEN_GET) { + if (is_begin) { grn_tokenizer_token_push(ctx, &(tokenizer->token), GRN_TOKENIZER_BEGIN_MARK_UTF8, GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN, status); - tokenizer->get.have_begin = GRN_FALSE; return NULL; } - if (tokenizer->is_end && tokenizer->get.have_end) { + if (tokenizer->is_end) { status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; grn_tokenizer_token_push(ctx, &(tokenizer->token), @@ -601,18 +578,45 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) status); return NULL; } - } else { - if (tokenizer->is_begin) { + if (is_start_token) { + if (char_types && GRN_STR_ISBLANK(char_types[-1])) { + status |= GRN_TOKEN_SKIP; + grn_tokenizer_token_push(ctx, &(tokenizer->token), "", 0, status); + return NULL; + } + } + } + + char_len = grn_charlen_(ctx, current, end, tokenizer->query->encoding); + if (char_len == 0) { + status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; + grn_tokenizer_token_push(ctx, &(tokenizer->token), "", 0, status); + return NULL; + } + + if (mode == GRN_TOKEN_GET) { + if (is_begin && + char_len == GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN && + memcmp(current, GRN_TOKENIZER_BEGIN_MARK_UTF8, char_len) == 0) { + n_characters++; + GRN_TEXT_PUT(ctx, buffer, current, char_len); + current += char_len; + tokenizer->next = current; + tokenizer->nth_char++; + if (current == end) { + status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; + } grn_tokenizer_token_push(ctx, &(tokenizer->token), GRN_TOKENIZER_BEGIN_MARK_UTF8, GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN, status); - tokenizer->is_begin = GRN_FALSE; return NULL; } - if (tokenizer->is_end) { + if (current + char_len == end && + char_len == GRN_TOKENIZER_END_MARK_UTF8_LEN && + memcmp(current, GRN_TOKENIZER_END_MARK_UTF8, char_len) == 0) { status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; grn_tokenizer_token_push(ctx, &(tokenizer->token), @@ -623,28 +627,21 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) } } - char_len = grn_charlen_(ctx, current, end, tokenizer->query->encoding); - if (char_len == 0) { - status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; - grn_tokenizer_token_push(ctx, &(tokenizer->token), "", 0, status); - return NULL; - } - while (GRN_TRUE) { - if (!escaping && mode == GRN_TOKEN_GET && - char_len == 1 && current[0] == '\\') { - current += char_len; - escaping = GRN_TRUE; - } else { - n_characters++; - GRN_TEXT_PUT(ctx, buffer, current, char_len); - current += char_len; - escaping = GRN_FALSE; - if (n_characters == 1) { - tokenizer->next = current; - } - if (n_characters == ngram_unit) { - break; + n_characters++; + GRN_TEXT_PUT(ctx, buffer, current, char_len); + current += char_len; + if (n_characters == 1) { + tokenizer->next = current; + tokenizer->nth_char++; + } + + if (char_types) { + uint_least8_t char_type; + char_type = char_types[0]; + char_types++; + if (GRN_STR_ISBLANK(char_type)) { + break_by_blank = GRN_TRUE; } } @@ -653,6 +650,21 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) if (char_len == 0) { break; } + + if (mode == GRN_TOKEN_GET && + current + char_len == end && + char_len == GRN_TOKENIZER_END_MARK_UTF8_LEN && + memcmp(current, GRN_TOKENIZER_END_MARK_UTF8, char_len) == 0) { + break_by_end_mark = GRN_TRUE; + } + + if (break_by_blank || break_by_end_mark) { + break; + } + + if (n_characters == ngram_unit) { + break; + } } if (tokenizer->is_overlapping) { @@ -664,27 +676,21 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) tokenizer->is_overlapping = (n_characters > 1); if (mode == GRN_TOKEN_GET) { - if ((end - tokenizer->next) < ngram_unit) { - if (tokenizer->get.have_end) { - if (tokenizer->next == end) { - tokenizer->is_end = GRN_TRUE; - } - if (status & GRN_TOKEN_UNMATURED) { - if (tokenizer->is_first_token) { - status |= GRN_TOKEN_FORCE_PREFIX; - } else { - status |= GRN_TOKEN_SKIP; - } - } - } else { - tokenizer->is_end = GRN_TRUE; - status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; - if (status & GRN_TOKEN_UNMATURED) { - status |= GRN_TOKEN_FORCE_PREFIX; - } + if (current == end) { + tokenizer->is_end = GRN_TRUE; + status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; + if (status & GRN_TOKEN_UNMATURED) { + status |= GRN_TOKEN_FORCE_PREFIX; } } else { - if (tokenizer->get.n_skip_tokens > 0) { + if (break_by_blank) { + tokenizer->get.n_skip_tokens = 0; + tokenizer->is_start_token = GRN_TRUE; + } else if (break_by_end_mark) { + if (!is_start_token && (status & GRN_TOKEN_UNMATURED)) { + status |= GRN_TOKEN_SKIP; + } + } else if (tokenizer->get.n_skip_tokens > 0) { tokenizer->get.n_skip_tokens--; status |= GRN_TOKEN_SKIP; } else { @@ -695,6 +701,9 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) if (tokenizer->next == end) { tokenizer->is_end = GRN_TRUE; } + if (break_by_blank) { + tokenizer->is_start_token = GRN_TRUE; + } } grn_tokenizer_token_push(ctx, @@ -702,7 +711,6 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) GRN_TEXT_VALUE(buffer), GRN_TEXT_LEN(buffer), status); - tokenizer->is_first_token = GRN_FALSE; return NULL; } @@ -751,6 +759,20 @@ grn_db_init_mecab_tokenizer(grn_ctx *ctx) case GRN_ENC_EUC_JP : case GRN_ENC_UTF8 : case GRN_ENC_SJIS : +#if defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) + { + GRN_PLUGIN_DECLARE_FUNCTIONS(tokenizers_mecab); + grn_rc rc; + rc = GRN_PLUGIN_IMPL_NAME_TAGGED(init, tokenizers_mecab)(ctx); + if (rc == GRN_SUCCESS) { + rc = GRN_PLUGIN_IMPL_NAME_TAGGED(register, tokenizers_mecab)(ctx); + if (rc != GRN_SUCCESS) { + GRN_PLUGIN_IMPL_NAME_TAGGED(fin, tokenizers_mecab)(ctx); + } + } + return rc; + } +#else /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */ { const char *mecab_plugin_name = "tokenizers/mecab"; char *path; @@ -762,6 +784,7 @@ grn_db_init_mecab_tokenizer(grn_ctx *ctx) return GRN_NO_SUCH_FILE_OR_DIRECTORY; } } +#endif /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */ break; default : return GRN_OPERATION_NOT_SUPPORTED; diff --git a/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt index 37f6127b0d2..6d6a8df5d5e 100644 --- a/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt @@ -22,8 +22,10 @@ add_subdirectory(token_filters) add_subdirectory(sharding) add_subdirectory(functions) -if(GRN_WITH_MRUBY) - read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/ruby_scripts.am RUBY_SCRIPTS) - install(FILES ${RUBY_SCRIPTS} - DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}") +if(NOT GRN_EMBED) + if(GRN_WITH_MRUBY) + read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/ruby_scripts.am RUBY_SCRIPTS) + install(FILES ${RUBY_SCRIPTS} + DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}") + endif() endif() diff --git a/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt index 28db8b42ef3..d831589b28b 100644 --- a/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt @@ -21,12 +21,20 @@ set(GRN_FUNCTIONS_PLUGIN_DIR "${GRN_RELATIVE_PLUGINS_DIR}/functions") read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/vector_sources.am VECTOR_SOURCES) -add_library(vector_functions MODULE ${VECTOR_SOURCES}) set_source_files_properties(${VECTOR_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") -set_target_properties(vector_functions PROPERTIES - PREFIX "" - OUTPUT_NAME "vector") +if(GRN_EMBED) + add_library(vector_functions STATIC ${VECTOR_SOURCES}) + set_target_properties( + vector_functions + PROPERTIES + POSITION_INDEPENDENT_CODE ON) +else() + add_library(vector_functions MODULE ${VECTOR_SOURCES}) + set_target_properties(vector_functions PROPERTIES + PREFIX "" + OUTPUT_NAME "vector") + install(TARGETS vector_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}") +endif() target_link_libraries(vector_functions libgroonga) -install(TARGETS vector_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}") diff --git a/storage/mroonga/vendor/groonga/plugins/functions/vector.c b/storage/mroonga/vendor/groonga/plugins/functions/vector.c index 34f7a98fd27..a92fee9dbec 100644 --- a/storage/mroonga/vendor/groonga/plugins/functions/vector.c +++ b/storage/mroonga/vendor/groonga/plugins/functions/vector.c @@ -16,6 +16,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG functions_vector +#endif + #include <groonga/plugin.h> static grn_obj * diff --git a/storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt index 57d11abfbcb..7f622608e4b 100644 --- a/storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt @@ -22,9 +22,17 @@ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/tsv_sources.am TSV_SOURCES) set_source_files_properties(${TSV_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") -add_library(tsv_query_expander MODULE ${TSV_SOURCES}) -set_target_properties(tsv_query_expander PROPERTIES - PREFIX "" - OUTPUT_NAME "tsv") +if(GRN_EMBED) + add_library(tsv_query_expander STATIC ${TSV_SOURCES}) + set_target_properties( + tsv_query_expander + PROPERTIES + POSITION_INDEPENDENT_CODE ON) +else() + add_library(tsv_query_expander MODULE ${TSV_SOURCES}) + set_target_properties(tsv_query_expander PROPERTIES + PREFIX "" + OUTPUT_NAME "tsv") + install(TARGETS tsv_query_expander DESTINATION "${QUERY_EXPANDERS_DIR}") +endif() target_link_libraries(tsv_query_expander libgroonga) -install(TARGETS tsv_query_expander DESTINATION "${QUERY_EXPANDERS_DIR}") diff --git a/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c b/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c index 06bb322acb2..00550f6822b 100644 --- a/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c +++ b/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c @@ -15,6 +15,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG query_expanders_tsv +#endif + /* groonga's internal headers */ /* for grn_text_fgets(): We don't want to require stdio.h for groonga.h. What should we do? Should we split header file such as groonga/stdio.h? */ diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt index ba7deafe0d3..63a79938552 100644 --- a/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt @@ -21,20 +21,40 @@ if(GRN_WITH_MRUBY) set(GRN_RELATIVE_RUBY_PLUGINS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/ruby") read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/eval_sources.am RUBY_EVAL_SOURCES) - add_library(eval MODULE ${RUBY_EVAL_SOURCES}) set_source_files_properties(${RUBY_EVAL_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") - set_target_properties(eval PROPERTIES PREFIX "") - target_link_libraries(eval libgroonga) - install(TARGETS eval DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}") + if(GRN_EMBED) + add_library(ruby_eval STATIC ${RUBY_EVAL_SOURCES}) + set_target_properties( + ruby_eval + PROPERTIES + POSITION_INDEPENDENT_CODE ON) + else() + add_library(ruby_eval MODULE ${RUBY_EVAL_SOURCES}) + set_target_properties(ruby_eval PROPERTIES + PREFIX "" + OUTPUT_NAME "eval") + install(TARGETS ruby_eval DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}") + endif() + target_link_libraries(ruby_eval libgroonga) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/load_sources.am RUBY_LOAD_SOURCES) - add_library(load MODULE ${RUBY_LOAD_SOURCES}) set_source_files_properties(${RUBY_LOAD_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") - set_target_properties(load PROPERTIES PREFIX "") - target_link_libraries(load libgroonga) - install(TARGETS load DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}") + if(GRN_EMBED) + add_library(ruby_load STATIC ${RUBY_LOAD_SOURCES}) + set_target_properties( + ruby_load + PROPERTIES + POSITION_INDEPENDENT_CODE ON) + else() + add_library(ruby_load MODULE ${RUBY_LOAD_SOURCES}) + set_target_properties(ruby_load PROPERTIES + PREFIX "" + OUTPUT_NAME "load") + install(TARGETS ruby_load DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}") + endif() + target_link_libraries(ruby_load libgroonga) endif() diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/eval.c b/storage/mroonga/vendor/groonga/plugins/ruby/eval.c index ad1e7948249..bacd9011c12 100644 --- a/storage/mroonga/vendor/groonga/plugins/ruby/eval.c +++ b/storage/mroonga/vendor/groonga/plugins/ruby/eval.c @@ -16,6 +16,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG ruby_eval +#endif + #include "ruby_plugin.h" static grn_obj * diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/load.c b/storage/mroonga/vendor/groonga/plugins/ruby/load.c index a4e60acc357..447882319a5 100644 --- a/storage/mroonga/vendor/groonga/plugins/ruby/load.c +++ b/storage/mroonga/vendor/groonga/plugins/ruby/load.c @@ -16,6 +16,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG ruby_load +#endif + #include "ruby_plugin.h" static grn_obj * diff --git a/storage/mroonga/vendor/groonga/plugins/sharding.rb b/storage/mroonga/vendor/groonga/plugins/sharding.rb index e369c3798da..4ebc9baf438 100644 --- a/storage/mroonga/vendor/groonga/plugins/sharding.rb +++ b/storage/mroonga/vendor/groonga/plugins/sharding.rb @@ -2,3 +2,5 @@ require "sharding/range_expression_builder" require "sharding/logical_enumerator" require "sharding/logical_count" require "sharding/logical_range_filter" +require "sharding/logical_select" +require "sharding/logical_table_remove" diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt index 8d0cdd976dc..588a434e0e0 100644 --- a/storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt @@ -13,10 +13,12 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -if(GRN_WITH_MRUBY) - set(GRN_RELATIVE_SHARDING_PLUGINS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/sharding") +if(NOT GRN_EMBED) + if(GRN_WITH_MRUBY) + set(GRN_RELATIVE_SHARDING_PLUGINS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/sharding") - read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am SHARDING_SCRIPTS) - install(FILES ${SHARDING_SCRIPTS} - DESTINATION "${GRN_RELATIVE_SHARDING_PLUGINS_DIR}") + read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am SHARDING_SCRIPTS) + install(FILES ${SHARDING_SCRIPTS} + DESTINATION "${GRN_RELATIVE_SHARDING_PLUGINS_DIR}") + endif() endif() diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb index 1aeafef5438..35934182591 100644 --- a/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb +++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb @@ -20,15 +20,37 @@ module Groonga private def each_internal(order) - prefix = "#{@logical_table}_" context = Context.instance - context.database.each_table(:prefix => prefix, - :order_by => :key, - :order => order) do |table| - shard_range_raw = table.name[prefix.size..-1] + each_shard_with_around(order) do |prev_shard, current_shard, next_shard| + table = current_shard.table + shard_range_data = current_shard.range_data + shard_range = nil - next unless /\A(\d{4})(\d{2})(\d{2})\z/ =~ shard_range_raw - shard_range = ShardRange.new($1.to_i, $2.to_i, $3.to_i) + if shard_range_data.day.nil? + if order == :ascending + if next_shard + next_shard_range_data = next_shard.range_data + else + next_shard_range_data = nil + end + else + if prev_shard + next_shard_range_data = prev_shard.range_data + else + next_shard_range_data = nil + end + end + max_day = compute_month_shard_max_day(shard_range_data.year, + shard_range_data.month, + next_shard_range_data) + shard_range = MonthShardRange.new(shard_range_data.year, + shard_range_data.month, + max_day) + else + shard_range = DayShardRange.new(shard_range_data.year, + shard_range_data.month, + shard_range_data.day) + end physical_shard_key_name = "#{table.name}.#{@shard_key_name}" shard_key = context[physical_shard_key_name] @@ -43,6 +65,36 @@ module Groonga end end + def each_shard_with_around(order) + context = Context.instance + prefix = "#{@logical_table}_" + + shards = [nil] + context.database.each_table(:prefix => prefix, + :order_by => :key, + :order => order) do |table| + shard_range_raw = table.name[prefix.size..-1] + + case shard_range_raw + when /\A(\d{4})(\d{2})\z/ + shard_range_data = ShardRangeData.new($1.to_i, $2.to_i, nil) + when /\A(\d{4})(\d{2})(\d{2})\z/ + shard_range_data = ShardRangeData.new($1.to_i, $2.to_i, $3.to_i) + else + next + end + + shards << Shard.new(table, shard_range_data) + next if shards.size < 3 + yield(*shards) + shards.shift + end + + if shards.size == 2 + yield(shards[0], shards[1], nil) + end + end + private def initialize_parameters @logical_table = @input[:logical_table] @@ -58,13 +110,84 @@ module Groonga @target_range = TargetRange.new(@command_name, @input) end - class ShardRange + def compute_month_shard_max_day(year, month, next_shard_range) + return nil if next_shard_range.nil? + + return nil if month != next_shard_range.month + + next_shard_range.day + end + + class Shard + attr_reader :table, :range_data + def initialize(table, range_data) + @table = table + @range_data = range_data + end + end + + class ShardRangeData + attr_reader :year, :month, :day + def initialize(year, month, day) + @year = year + @month = month + @day = day + end + end + + class DayShardRange attr_reader :year, :month, :day def initialize(year, month, day) @year = year @month = month @day = day end + + def least_over_time + Time.local(@year, @month, @day + 1) + end + + def min_time + Time.local(@year, @month, @day) + end + + def include?(time) + @year == time.year and + @month == time.month and + @day == time.day + end + end + + class MonthShardRange + attr_reader :year, :month, :max_day + def initialize(year, month, max_day) + @year = year + @month = month + @max_day = max_day + end + + def least_over_time + if @max_day.nil? + Time.local(@year, @month + 1, 1) + else + Time.local(@year, @month, @max_day + 1) + end + end + + def min_time + Time.local(@year, @month, 1) + end + + def include?(time) + return false unless @year == time.year + return false unless @month == time.month + + if @max_day.nil? + true + else + time.day <= @max_day + end + end end class TargetRange @@ -139,16 +262,11 @@ module Groonga end def in_min?(shard_range) - base_time = Time.local(shard_range.year, - shard_range.month, - shard_range.day + 1) - @min < base_time + @min < shard_range.least_over_time end def in_min_partial?(shard_range) - return false unless @min.year == shard_range.year - return false unless @min.month == shard_range.month - return false unless @min.day == shard_range.day + return false unless shard_range.include?(@min) return true if @min_border == :exclude @@ -159,9 +277,7 @@ module Groonga end def in_max?(shard_range) - max_base_time = Time.local(shard_range.year, - shard_range.month, - shard_range.day) + max_base_time = shard_range.min_time if @max_border == :include @max >= max_base_time else @@ -170,9 +286,7 @@ module Groonga end def in_max_partial?(shard_range) - @max.year == shard_range.year and - @max.month == shard_range.month and - @max.day == shard_range.day + shard_range.include?(@max) end end end diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb new file mode 100644 index 00000000000..da6dbe5ae91 --- /dev/null +++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb @@ -0,0 +1,332 @@ +module Groonga + module Sharding + class LogicalSelectCommand < Command + register("logical_select", + [ + "logical_table", + "shard_key", + "min", + "min_border", + "max", + "max_border", + "filter", + "sortby", + "output_columns", + "offset", + "limit", + "drilldown", + "drilldown_sortby", + "drilldown_output_columns", + "drilldown_offset", + "drilldown_limit", + ]) + + def run_body(input) + enumerator = LogicalEnumerator.new("logical_select", input) + + context = ExecuteContext.new(input) + begin + executor = Executor.new(context) + executor.execute + + n_results = 1 + drilldowns = context.drilldown.result_sets + n_results += drilldowns.size + + writer.array("RESULT", n_results) do + write_records(writer, context) + write_drilldowns(writer, context, drilldowns) + end + ensure + context.close + end + end + + private + def write_records(writer, context) + result_sets = context.result_sets + + n_hits = 0 + n_elements = 2 # for N hits and columns + result_sets.each do |result_set| + n_hits += result_set.size + n_elements += result_set.size + end + + output_columns = context.output_columns + + writer.array("RESULTSET", n_elements) do + writer.array("NHITS", 1) do + writer.write(n_hits) + end + first_result_set = result_sets.first + if first_result_set + writer.write_table_columns(first_result_set, output_columns) + end + + current_offset = context.offset + current_offset += n_hits if current_offset < 0 + current_limit = context.limit + current_limit += n_hits + 1 if current_limit < 0 + options = { + :offset => current_offset, + :limit => current_limit, + } + result_sets.each do |result_set| + if result_set.size > current_offset + writer.write_table_records(result_set, output_columns, options) + end + if current_offset > 0 + current_offset = [current_offset - result_set.size, 0].max + end + current_limit -= result_set.size + break if current_limit <= 0 + options[:offset] = current_offset + options[:limit] = current_limit + end + end + end + + def write_drilldowns(writer, context, drilldowns) + output_columns = context.drilldown.output_columns + + options = { + :offset => context.drilldown.output_offset, + :limit => context.drilldown.limit, + } + + drilldowns.each do |drilldown| + n_elements = 2 # for N hits and columns + n_elements += drilldown.size + writer.array("RESULTSET", n_elements) do + writer.array("NHITS", 1) do + writer.write(drilldown.size) + end + writer.write_table_columns(drilldown, output_columns) + writer.write_table_records(drilldown, output_columns, + options) + end + end + end + + module KeysParsable + private + def parse_keys(raw_keys) + return [] if raw_keys.nil? + + raw_keys.strip.split(/ *, */) + end + end + + class ExecuteContext + include KeysParsable + + attr_reader :enumerator + attr_reader :filter + attr_reader :offset + attr_reader :limit + attr_reader :sort_keys + attr_reader :output_columns + attr_reader :result_sets + attr_reader :drilldown + def initialize(input) + @input = input + @enumerator = LogicalEnumerator.new("logical_select", @input) + @filter = @input[:filter] + @offset = (@input[:offset] || 0).to_i + @limit = (@input[:limit] || 10).to_i + @sort_keys = parse_keys(@input[:sortby]) + @output_columns = @input[:output_columns] || "_key, *" + + @result_sets = [] + + @drilldown = DrilldownExecuteContext.new(@input) + end + + def close + @result_sets.each do |result_set| + result_set.close if result_set.temporary? + end + + @drilldown.close + end + end + + class DrilldownExecuteContext + include KeysParsable + + attr_reader :keys + attr_reader :offset + attr_reader :limit + attr_reader :sort_keys + attr_reader :output_columns + attr_reader :output_offset + attr_reader :result_sets + attr_reader :unsorted_result_sets + def initialize(input) + @input = input + @keys = parse_keys(@input[:drilldown]) + @offset = (@input[:drilldown_offset] || 0).to_i + @limit = (@input[:drilldown_limit] || 10).to_i + @sort_keys = parse_keys(@input[:drilldown_sortby]) + @output_columns = @input[:drilldown_output_columns] + @output_columns ||= "_key, _nsubrecs" + + if @sort_keys.empty? + @output_offset = @offset + else + @output_offset = 0 + end + + @result_sets = [] + @unsorted_result_sets = [] + end + + def close + @result_sets.each do |result_set| + result_set.close + end + @unsorted_result_sets.each do |result_set| + result_set.close + end + end + end + + class Executor + def initialize(context) + @context = context + end + + def execute + execute_search + execute_drilldown + end + + private + def execute_search + first_table = nil + enumerator = @context.enumerator + enumerator.each do |table, shard_key, shard_range| + first_table ||= table + next if table.empty? + + shard_executor = ShardExecutor.new(@context, + table, shard_key, shard_range) + shard_executor.execute + end + if first_table.nil? + message = + "[logical_select] no shard exists: " + + "logical_table: <#{enumerator.logical_table}>: " + + "shard_key: <#{enumerator.shard_key_name}>" + raise InvalidArgument, message + end + if @context.result_sets.empty? + result_set = HashTable.create(:flags => ObjectFlags::WITH_SUBREC, + :key_type => first_table) + @context.result_sets << result_set + end + end + + def execute_drilldown + drilldown = @context.drilldown + group_result = TableGroupResult.new + sort_options = { + :offset => drilldown.offset, + :limit => drilldown.limit, + } + begin + group_result.key_begin = 0 + group_result.key_end = 0 + group_result.limit = 1 + group_result.flags = TableGroupFlags::CALC_COUNT + drilldown.keys.each do |key| + @context.result_sets.each do |result_set| + result_set.group([key], group_result) + end + result_set = group_result.table + if drilldown.sort_keys.empty? + drilldown.result_sets << result_set + else + drilldown.result_sets << result_set.sort(drilldown.sort_keys, + sort_options) + drilldown.unsorted_result_sets << result_set + end + group_result.table = nil + end + ensure + group_result.close + end + end + end + + class ShardExecutor + def initialize(context, table, shard_key, shard_range) + @context = context + @table = table + @shard_key = shard_key + @shard_range = shard_range + + @filter = @context.filter + @result_sets = @context.result_sets + + @target_range = @context.enumerator.target_range + + @cover_type = @target_range.cover_type(@shard_range) + + @expression_builder = RangeExpressionBuilder.new(@shard_key, + @target_range, + @filter) + end + + def execute + return if @cover_type == :none + + case @cover_type + when :all + filter_shard_all + when :partial_min + filter_table do |expression| + @expression_builder.build_partial_min(expression) + end + when :partial_max + filter_table do |expression| + @expression_builder.build_partial_max(expression) + end + when :partial_min_and_max + filter_table do |expression| + @expression_builder.build_partial_min_and_max(expression) + end + end + end + + private + def filter_shard_all + if @filter.nil? + @result_sets << @table + else + filter_table do |expression| + @expression_builder.build_all(expression) + end + end + end + + def create_expression(table) + expression = Expression.create(table) + begin + yield(expression) + ensure + expression.close + end + end + + def filter_table + create_expression(@table) do |expression| + yield(expression) + @result_sets << @table.select(expression) + end + end + end + end + end +end diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb new file mode 100644 index 00000000000..f5c31c72bb1 --- /dev/null +++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb @@ -0,0 +1,70 @@ +module Groonga + module Sharding + class LogicalTableRemoveCommand < Command + register("logical_table_remove", + [ + "logical_table", + "shard_key", + "min", + "min_border", + "max", + "max_border", + ]) + + def run_body(input) + enumerator = LogicalEnumerator.new("logical_table_remove", input) + + succeess = true + enumerator.each do |table, shard_key, shard_range| + remove_table(table, + shard_key, + shard_range, + enumerator.target_range) + end + writer.write(succeess) + end + + private + def remove_table(table, shard_key, shard_range, target_range) + cover_type = target_range.cover_type(shard_range) + return if cover_type == :none + + expression_builder = RangeExpressionBuilder.new(shard_key, + target_range, + nil) + + case cover_type + when :all + table.remove + when :partial_min + remove_records(table) do |expression| + expression_builder.build_partial_min(expression) + end + table.remove if table.empty? + when :partial_max + remove_records(table) do |expression| + expression_builder.build_partial_max(expression) + end + table.remove if table.empty? + when :partial_min_and_max + remove_records(table) do |expression| + expression_builder.build_partial_min_and_max(expression) + end + table.remove if table.empty? + end + end + + def remove_records(table) + expression = nil + + begin + expression = Expression.create(table) + yield(expression) + table.delete(:expression => expression) + ensure + expression.close if expression + end + end + end + end +end diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/sources.am b/storage/mroonga/vendor/groonga/plugins/sharding/sources.am index 5defd4880f1..14e56609cae 100644 --- a/storage/mroonga/vendor/groonga/plugins/sharding/sources.am +++ b/storage/mroonga/vendor/groonga/plugins/sharding/sources.am @@ -2,4 +2,6 @@ sharding_scripts = \ logical_count.rb \ logical_enumerator.rb \ logical_range_filter.rb \ + logical_select.rb \ + logical_table_remove.rb \ range_expression_builder.rb diff --git a/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt index 519193918b4..03375f97adb 100644 --- a/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt @@ -18,10 +18,18 @@ include_directories( ${MRUBY_INCLUDE_DIRS}) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am SUGGEST_SOURCES) -add_library(suggest MODULE ${SUGGEST_SOURCES}) set_source_files_properties(${SUGGEST_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") -set_target_properties(suggest PROPERTIES PREFIX "") +if(GRN_EMBED) + add_library(suggest STATIC ${SUGGEST_SOURCES}) + set_target_properties( + suggest + PROPERTIES + POSITION_INDEPENDENT_CODE ON) +else() + add_library(suggest MODULE ${SUGGEST_SOURCES}) + set_target_properties(suggest PROPERTIES PREFIX "") + install(TARGETS suggest DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/suggest") +endif() target_link_libraries(suggest libgroonga) -install(TARGETS suggest DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/suggest") diff --git a/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c b/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c index 863ffcf13e3..073f5e00103 100644 --- a/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c +++ b/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c @@ -15,6 +15,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG suggest_suggest +#endif + #include <string.h> #include "grn_ctx.h" diff --git a/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt index eada0395080..bd423a830b3 100644 --- a/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt @@ -18,10 +18,12 @@ include_directories( ${MRUBY_INCLUDE_DIRS}) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am TABLE_SOURCES) -add_library(table MODULE ${TABLE_SOURCES}) -set_source_files_properties(${TABLE_SOURCES} - PROPERTIES - COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") -set_target_properties(table PROPERTIES PREFIX "") -target_link_libraries(table libgroonga) -install(TARGETS table DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/table") +if(NOT GRN_EMBED) + add_library(table MODULE ${TABLE_SOURCES}) + set_source_files_properties(${TABLE_SOURCES} + PROPERTIES + COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") + set_target_properties(table PROPERTIES PREFIX "") + target_link_libraries(table libgroonga) + install(TARGETS table DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/table") +endif() diff --git a/storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt index a0b964fb659..55491b20bd7 100644 --- a/storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt @@ -21,27 +21,43 @@ set(TOKEN_FILTERS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/token_filters") read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/stop_word_sources.am STOP_WORD_SOURCES) -add_library(stop_word_token_filter MODULE ${STOP_WORD_SOURCES}) set_source_files_properties(${STOP_WORD_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") -set_target_properties(stop_word_token_filter PROPERTIES - PREFIX "" - OUTPUT_NAME "stop_word") +if(GRN_EMBED) + add_library(stop_word_token_filter STATIC ${STOP_WORD_SOURCES}) + set_target_properties( + stop_word_token_filter + PROPERTIES + POSITION_INDEPENDENT_CODE ON) +else() + add_library(stop_word_token_filter MODULE ${STOP_WORD_SOURCES}) + set_target_properties(stop_word_token_filter PROPERTIES + PREFIX "" + OUTPUT_NAME "stop_word") + install(TARGETS stop_word_token_filter DESTINATION "${TOKEN_FILTERS_DIR}") +endif() target_link_libraries(stop_word_token_filter libgroonga) -install(TARGETS stop_word_token_filter DESTINATION "${TOKEN_FILTERS_DIR}") if(GRN_WITH_LIBSTEMMER) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/stem_sources.am STEM_SOURCES) include_directories(${LIBSTEMMER_INCLUDE_DIRS}) link_directories(${LIBSTEMMER_LIBRARY_DIRS}) - add_library(stem_token_filter MODULE ${STEM_SOURCES}) set_source_files_properties(${STEM_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") - set_target_properties(stem_token_filter PROPERTIES - PREFIX "" - OUTPUT_NAME "stem") + if(GRN_EMBED) + add_library(stem_token_filter STATIC ${STEM_SOURCES}) + set_target_properties( + stem_token_filter + PROPERTIES + POSITION_INDEPENDENT_CODE ON) + else() + add_library(stem_token_filter MODULE ${STEM_SOURCES}) + set_target_properties(stem_token_filter PROPERTIES + PREFIX "" + OUTPUT_NAME "stem") + install(TARGETS stem_token_filter DESTINATION "${TOKEN_FILTERS_DIR}") + endif() target_link_libraries(stem_token_filter libgroonga ${LIBSTEMMER_LIBRARIES}) - install(TARGETS stem_token_filter DESTINATION "${TOKEN_FILTERS_DIR}") endif() diff --git a/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c b/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c index 010b8c91867..63e640d5ea2 100644 --- a/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c +++ b/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c @@ -16,6 +16,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG token_filters_stem +#endif + #include <grn_str.h> #include <groonga.h> diff --git a/storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c b/storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c index 054cd65aa37..e5a9a77de2e 100644 --- a/storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c +++ b/storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c @@ -16,6 +16,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG token_filters_stop_word +#endif + #include <grn_str.h> #include <groonga.h> diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt index 5871e982211..9209b44d36f 100644 --- a/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt @@ -22,28 +22,44 @@ if(GRN_WITH_MECAB) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mecab_sources.am MECAB_SOURCES) include_directories(${MECAB_INCLUDE_DIRS}) link_directories(${MECAB_LIBRARY_DIRS}) - add_library(mecab_tokenizer MODULE ${MECAB_SOURCES}) set_source_files_properties(${MECAB_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") - set_target_properties(mecab_tokenizer PROPERTIES - PREFIX "" - OUTPUT_NAME "mecab") + if(GRN_EMBED) + add_library(mecab_tokenizer STATIC ${MECAB_SOURCES}) + set_target_properties( + mecab_tokenizer + PROPERTIES + POSITION_INDEPENDENT_CODE ON) + else() + add_library(mecab_tokenizer MODULE ${MECAB_SOURCES}) + set_target_properties(mecab_tokenizer PROPERTIES + PREFIX "" + OUTPUT_NAME "mecab") + install(TARGETS mecab_tokenizer DESTINATION "${TOKENIZERS_DIR}") + endif() target_link_libraries(mecab_tokenizer libgroonga ${MECAB_LIBRARIES}) - install(TARGETS mecab_tokenizer DESTINATION "${TOKENIZERS_DIR}") endif() if(GRN_WITH_KYTEA) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/kytea_sources.am KYTEA_SOURCES) include_directories(${KYTEA_INCLUDE_DIRS}) link_directories(${KYTEA_LIBRARY_DIRS}) - add_library(kytea_tokenizer MODULE ${KYTEA_SOURCES}) set_source_files_properties(${KYTEA_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS}") - set_target_properties(kytea_tokenizer PROPERTIES - PREFIX "" - OUTPUT_NAME "kytea") + if(GRN_EMBED) + add_library(kytea_tokenizer STATIC ${KYTEA_SOURCES}) + set_target_properties( + kytea_tokenizer + PROPERTIES + POSITION_INDEPENDENT_CODE ON) + else() + add_library(kytea_tokenizer MODULE ${KYTEA_SOURCES}) + set_target_properties(kytea_tokenizer PROPERTIES + PREFIX "" + OUTPUT_NAME "kytea") + install(TARGETS kytea_tokenizer DESTINATION "${TOKENIZERS_DIR}") + endif() target_link_libraries(kytea_tokenizer libgroonga ${KYTEA_LIBRARIES}) - install(TARGETS kytea_tokenizer DESTINATION "${TOKENIZERS_DIR}") endif() diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp b/storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp index a7ee4104592..62ef0bb5845 100644 --- a/storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp +++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp @@ -15,6 +15,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG tokenizers_kytea +#endif + #include <groonga/tokenizer.h> #include <kytea/kytea.h> diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c b/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c index 9207f94229e..bade2f9d3de 100644 --- a/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c +++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c @@ -15,6 +15,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef GRN_EMBEDDED +# define GRN_PLUGIN_FUNCTION_TAG tokenizers_mecab +#endif + #include <grn_str.h> #include <groonga.h> @@ -509,17 +513,21 @@ grn_rc GRN_PLUGIN_INIT(grn_ctx *ctx) { { - const char *env; + char env[GRN_ENV_BUFFER_SIZE]; - env = getenv("GRN_MECAB_CHUNKED_TOKENIZE_ENABLED"); - grn_mecab_chunked_tokenize_enabled = (env && strcmp(env, "yes") == 0); + grn_getenv("GRN_MECAB_CHUNKED_TOKENIZE_ENABLED", + env, + GRN_ENV_BUFFER_SIZE); + grn_mecab_chunked_tokenize_enabled = (env[0] && strcmp(env, "yes") == 0); } { - const char *env; + char env[GRN_ENV_BUFFER_SIZE]; - env = getenv("GRN_MECAB_CHUNK_SIZE_THRESHOLD"); - if (env) { + grn_getenv("GRN_MECAB_CHUNK_SIZE_THRESHOLD", + env, + GRN_ENV_BUFFER_SIZE); + if (env[0]) { int threshold = -1; const char *end; const char *rest; diff --git a/storage/mroonga/vendor/groonga/ra.rb b/storage/mroonga/vendor/groonga/ra.rb new file mode 100755 index 00000000000..dbe493d7454 --- /dev/null +++ b/storage/mroonga/vendor/groonga/ra.rb @@ -0,0 +1,12 @@ +#!/usr/bin/env ruby + +puts "table_create X TABLE_NO_KEY" +puts "column_create X a COLUMN_SCALAR Int64" +puts "load --table X" +puts "[" +n_records = 2 ** 28 +(n_records - 1).times do |i| + puts "{\"a\": #{i}}," +end +puts "{\"a\": #{n_records - 1}}" +puts "]" diff --git a/storage/mroonga/vendor/groonga/src/grndb.c b/storage/mroonga/vendor/groonga/src/grndb.c index d493338f57e..d5a353e229a 100644 --- a/storage/mroonga/vendor/groonga/src/grndb.c +++ b/storage/mroonga/vendor/groonga/src/grndb.c @@ -120,6 +120,8 @@ main(int argc, char **argv) { int exit_code = EXIT_SUCCESS; + grn_default_logger_set_path(GRN_LOG_PATH); + if (grn_init() != GRN_SUCCESS) { return EXIT_FAILURE; } diff --git a/storage/mroonga/vendor/groonga/src/grnslap.c b/storage/mroonga/vendor/groonga/src/grnslap.c index 2f5562fe6a9..f9eee1081fd 100644 --- a/storage/mroonga/vendor/groonga/src/grnslap.c +++ b/storage/mroonga/vendor/groonga/src/grnslap.c @@ -21,11 +21,11 @@ #include <string.h> #include <stdio.h> #ifdef HAVE_SYS_WAIT_H -#include <sys/wait.h> +# include <sys/wait.h> #endif /* HAVE_SYS_WAIT_H */ -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif /* HAVE_NETINET_IN_H */ +#ifndef WIN32 +# include <netinet/in.h> +#endif /* WIN32 */ #define DEFAULT_PORT 10041 #define DEFAULT_HOST "localhost" @@ -362,6 +362,8 @@ main(int argc, char **argv) flags |= flag_usage; } + grn_default_logger_set_path(GRN_LOG_PATH); + if (grn_init()) { return -1; } if (flags & flag_usage) { usage(); r = -1; diff --git a/storage/mroonga/vendor/groonga/src/groonga.c b/storage/mroonga/vendor/groonga/src/groonga.c index 262c4de2e86..28c318664e0 100644 --- a/storage/mroonga/vendor/groonga/src/groonga.c +++ b/storage/mroonga/vendor/groonga/src/groonga.c @@ -39,9 +39,9 @@ #ifdef HAVE_SYS_SOCKET_H # include <sys/socket.h> #endif /* HAVE_SYS_SOCKET_H */ -#ifdef HAVE_NETINET_IN_H +#ifndef WIN32 # include <netinet/in.h> -#endif /* HAVE_NETINET_IN_H */ +#endif /* WIN32 */ #ifdef HAVE_SYS_RESOURCE_H # include <sys/resource.h> @@ -51,9 +51,12 @@ # include <sys/sysctl.h> #endif /* HAVE_SYS_SYSCTL_H */ -#ifdef HAVE_IO_H +#ifdef WIN32 # include <io.h> -#endif /* HAVE_IO_H */ +# include <direct.h> +#else /* WIN32 */ +# include <sys/uio.h> +#endif /* WIN32 */ #ifdef HAVE__STRNICMP # ifdef strncasecmp @@ -2656,7 +2659,7 @@ main(int argc, char **argv) const char *bind_address_arg = NULL; const char *hostname_arg = NULL; const char *protocol_arg = NULL; - const char *log_path_arg = NULL; + const char *log_path_arg = GRN_LOG_PATH; const char *log_rotate_threshold_size_arg = NULL; const char *query_log_path_arg = NULL; const char *query_log_rotate_threshold_size_arg = NULL; diff --git a/storage/mroonga/vendor/groonga/src/groonga_benchmark.c b/storage/mroonga/vendor/groonga/src/groonga_benchmark.c index 656984a7695..2ebca387232 100644 --- a/storage/mroonga/vendor/groonga/src/groonga_benchmark.c +++ b/storage/mroonga/vendor/groonga/src/groonga_benchmark.c @@ -28,14 +28,14 @@ #include <sys/stat.h> #ifdef HAVE_SYS_WAIT_H -#include <sys/wait.h> +# include <sys/wait.h> #endif /* HAVE_SYS_WAIT_H */ #ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> +# include <sys/socket.h> #endif /* HAVE_SYS_SOCKET_H */ -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif /* HAVE_NETINET_IN_H */ +#ifndef WIN32 +# include <netinet/in.h> +#endif /* WIN32 */ #include <grn_str.h> #include <grn_com.h> @@ -3062,6 +3062,8 @@ main(int argc, char **argv) grntest_outtype = OUT_TSV; } + grn_default_logger_set_path(GRN_LOG_PATH); + grn_init(); CRITICAL_SECTION_INIT(grntest_cs); diff --git a/storage/mroonga/vendor/groonga/src/groonga_mruby.c b/storage/mroonga/vendor/groonga/src/groonga_mruby.c index 9978a002f18..2f442fbd126 100644 --- a/storage/mroonga/vendor/groonga/src/groonga_mruby.c +++ b/storage/mroonga/vendor/groonga/src/groonga_mruby.c @@ -67,6 +67,8 @@ main(int argc, char **argv) return EXIT_FAILURE; } + grn_default_logger_set_path(GRN_LOG_PATH); + if (grn_init() != GRN_SUCCESS) { return EXIT_FAILURE; } diff --git a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/config b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/config index fc1fe16fad7..b79eef6ba17 100644 --- a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/config +++ b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/config @@ -10,7 +10,11 @@ if [ "$GROONGA_HTTPD_IN_TREE" = yes ]; then groonga_cflags="-I${GROONGA_HTTPD_IN_TREE_INCLUDE_PATH}" groonga_cflags="${groonga_cflags} -DNGX_HTTP_GROONGA_LOG_PATH=\\\"\"${GROONGA_HTTPD_GROONGA_LOG_PATH}\"\\\"" groonga_cflags="${groonga_cflags} -DNGX_HTTP_GROONGA_QUERY_LOG_PATH=\\\"\"${GROONGA_HTTPD_GROONGA_QUERY_LOG_PATH}\"\\\"" - groonga_libs="-L${GROONGA_HTTPD_IN_TREE_LINK_PATH} -lgroonga" + groonga_libs="-L${GROONGA_HTTPD_IN_TREE_LINK_PATH}" + if [ "${GROONGA_HTTPD_WITH_ONIGMO}" = "yes" ]; then + groonga_libs="$groonga_libs -L${GROONGA_HTTPD_ONIGMO_IN_TREE_LINK_PATH}" + fi + groonga_libs="$groonga_libs -lgroonga" if [ -n "${GROONGA_HTTPD_RPATH}" ]; then groonga_libs="$groonga_libs -Wl,-rpath -Wl,${GROONGA_HTTPD_RPATH}" fi @@ -46,7 +50,7 @@ if [ $ngx_found = yes ]; then CORE_LIBS="$CORE_LIBS $groonga_libs" else cat << END -$0: error: the groonga module requires the groonga library. +$0: error: the groonga module requires the Groonga library. END exit 1 fi diff --git a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c index 6ba1df4a9e8..727e65fa468 100644 --- a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c +++ b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c @@ -134,6 +134,30 @@ ngx_str_is_custom_path(ngx_str_t *string) } static void +ngx_http_groonga_write_fd(ngx_fd_t fd, + u_char *buffer, size_t buffer_size, + const char *message, size_t message_size) +{ + size_t rest_message_size = message_size; + const char *current_message = message; + + while (rest_message_size > 0) { + size_t current_message_size; + + if (rest_message_size > NGX_MAX_ERROR_STR) { + current_message_size = NGX_MAX_ERROR_STR; + } else { + current_message_size = rest_message_size; + } + + grn_memcpy(buffer, current_message, current_message_size); + ngx_write_fd(fd, buffer, current_message_size); + rest_message_size -= current_message_size; + current_message += current_message_size; + } +} + +static void ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level, const char *timestamp, const char *title, const char *message, const char *location, @@ -171,10 +195,14 @@ ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level, LOG_PREFIX_FORMAT, timestamp, *(level_marks + level), title); ngx_write_fd(logger_data->file->fd, buffer, last - buffer); - ngx_write_fd(logger_data->file->fd, (void *)message, message_size); + ngx_http_groonga_write_fd(logger_data->file->fd, + buffer, NGX_MAX_ERROR_STR, + message, message_size); if (location_size > 0) { ngx_write_fd(logger_data->file->fd, " ", 1); - ngx_write_fd(logger_data->file->fd, (void *)location, location_size); + ngx_http_groonga_write_fd(logger_data->file->fd, + buffer, NGX_MAX_ERROR_STR, + location, location_size); } ngx_write_fd(logger_data->file->fd, "\n", 1); } else { diff --git a/storage/mroonga/vendor/groonga/tools/install/install-for-debian-jessie.sh b/storage/mroonga/vendor/groonga/tools/install/install-for-debian-jessie.sh new file mode 100755 index 00000000000..d053d2d9caf --- /dev/null +++ b/storage/mroonga/vendor/groonga/tools/install/install-for-debian-jessie.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e + +sources_list_path=/etc/apt/sources.list.d/groonga.list + +if [ ! -f $sources_list_path ]; then + sudo cat <<SOURCES_LIST | sudo tee $sources_list_path +deb http://packages.groonga.org/debian/ jessie main +deb-src http://packages.groonga.org/debian/ jessie main +SOURCES_LIST +fi + +sudo apt-get update +sudo apt-get install -y --allow-unauthenticated groonga-keyring +sudo apt-get update +sudo apt-get install -y -V groonga diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt index c78fde5d258..f2b27aff7e8 100644 --- a/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt @@ -17,6 +17,7 @@ if(GRN_WITH_MRUBY) include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/include" "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/src" + "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/mrbgems/mruby-compiler/core" "${CMAKE_CURRENT_SOURCE_DIR}/../onigmo-source" ) diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am b/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am index d995ccfcce1..c4285c1c85c 100644 --- a/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am +++ b/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am @@ -3,10 +3,11 @@ EXTRA_DIST = \ mruby_build.rb \ mruby_build.timestamp -DEFAULT_INCLUDES = \ - -I$(srcdir)/../mruby-source/include \ - -I$(srcdir)/../mruby-source/src \ - -Imruby-io/include \ +DEFAULT_INCLUDES = \ + -I$(srcdir)/../mruby-source/include \ + -I$(srcdir)/../mruby-source/src \ + -I$(srcdir)/../mruby-source/mrbgems/mruby-compiler/core \ + -Imruby-io/include \ -I$(srcdir)/mruby-io/include CFLAGS += $(NO_FLOAT_EQUAL_CFLAGS) @@ -27,9 +28,9 @@ include sources.am include built_sources.am libmruby_la_SOURCES += $(BUILT_SOURCES) -parse.c: mruby_build.timestamp mrblib.c: mruby_build.timestamp mrbgems_init.c: mruby_build.timestamp +mruby-compiler/core/parse.c: mruby_build.timestamp mruby-onig-regexp/src/mruby_onig_regexp.c: mruby_build.timestamp mruby-env/src/env.c: mruby_build.timestamp mruby-io/include/mruby/ext/io.h: mruby_build.timestamp diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb b/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb index 5a963f9c7e7..f487e08b808 100644 --- a/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb +++ b/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb @@ -12,6 +12,7 @@ MRuby::Build.new do |conf| enable_debug + conf.gem :core => "mruby-compiler" conf.gem :core => "mruby-sprintf" conf.gem :core => "mruby-print" conf.gem :core => "mruby-math" diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am b/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am index 08c5e3a9453..73726cda58b 100644 --- a/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am +++ b/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am @@ -1,7 +1,7 @@ BUILT_SOURCES = \ - parse.c \ mrblib.c \ mrbgems_init.c \ + mruby-compiler/core/parse.c \ mruby-onig-regexp/src/mruby_onig_regexp.c \ mruby-env/src/env.c \ mruby-io/include/mruby/ext/io.h \ diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb b/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb index f0db931ed38..e2e8d68e7cf 100755 --- a/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb +++ b/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb @@ -28,7 +28,6 @@ end FileUtils.touch(timestamp_file) -FileUtils.cp("#{mruby_build_dir}/host/src/y.tab.c", "parse.c") FileUtils.cp("#{mruby_build_dir}/host/mrblib/mrblib.c", "./") File.open("mrbgems_init.c", "w") do |mrbgems_init| @@ -37,6 +36,11 @@ File.open("mrbgems_init.c", "w") do |mrbgems_init| end end +mruby_compiler_dir = "#{mruby_build_dir}/host/mrbgems/mruby-compiler" +FileUtils.mkdir_p("mruby-compiler/core/") +FileUtils.cp("#{mruby_compiler_dir}/core/y.tab.c", + "mruby-compiler/core/parse.c") + mruby_onig_regexp_dir = "#{mruby_build_dir}/mrbgems/mruby-onig-regexp" FileUtils.mkdir_p("mruby-onig-regexp/") FileUtils.cp_r("#{mruby_onig_regexp_dir}/src/", "mruby-onig-regexp/") diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/sources.am b/storage/mroonga/vendor/groonga/vendor/mruby/sources.am index 68f15c64571..78ecc9b85df 100644 --- a/storage/mroonga/vendor/groonga/vendor/mruby/sources.am +++ b/storage/mroonga/vendor/groonga/vendor/mruby/sources.am @@ -2,7 +2,7 @@ libmruby_la_SOURCES = \ ../mruby-source/src/array.c \ ../mruby-source/src/backtrace.c \ ../mruby-source/src/class.c \ - ../mruby-source/src/codegen.c \ + ../mruby-source/src/codedump.c \ ../mruby-source/src/compar.c \ ../mruby-source/src/crc.c \ ../mruby-source/src/debug.c \ @@ -17,8 +17,6 @@ libmruby_la_SOURCES = \ ../mruby-source/src/init.c \ ../mruby-source/src/kernel.c \ ../mruby-source/src/load.c \ - ../mruby-source/src/mrb_throw.h \ - ../mruby-source/src/node.h \ ../mruby-source/src/numeric.c \ ../mruby-source/src/object.c \ ../mruby-source/src/opcode.h \ @@ -33,6 +31,8 @@ libmruby_la_SOURCES = \ ../mruby-source/src/variable.c \ ../mruby-source/src/version.c \ ../mruby-source/src/vm.c \ + ../mruby-source/mrbgems/mruby-compiler/core/codegen.c \ + ../mruby-source/mrbgems/mruby-compiler/core/node.h \ ../mruby-source/mrbgems/mruby-sprintf/src/kernel.c \ ../mruby-source/mrbgems/mruby-sprintf/src/sprintf.c \ ../mruby-source/mrbgems/mruby-print/src/print.c \ diff --git a/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt index 0f79347aa73..e52bb1d195c 100644 --- a/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt @@ -34,12 +34,23 @@ if(GRN_WITH_ONIGMO) ac_check_sizeof(int) ac_check_sizeof(long) + add_definitions(-DHAVE_STDARG_H) + add_definitions(-DHAVE_STDINT_H) + add_definitions(-DHAVE_STDLIB_H) + add_definitions(-DHAVE_STRING_H) + add_definitions(-DHAVE_SYS_TYPES_H) + + add_definitions(-DSTDC_HEADERS) + if(MSVC) add_definitions(-Dinline=__inline) add_definitions(-D_CRT_SECURE_NO_WARNINGS) + else() + add_definitions(-DHAVE_INTTYPES_H) endif() include_directories( + BEFORE ${ONIGMO_BINARY_DIR} ${ONIGMO_SOURCE_DIR} ) @@ -107,4 +118,6 @@ if(GRN_WITH_ONIGMO) onigmo PROPERTIES POSITION_INDEPENDENT_CODE ON) + + configure_file(config.h.cmake "${ONIGMO_BINARY_DIR}/config.h") endif() diff --git a/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am b/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am index 73632ebd3bd..cbd419d6736 100644 --- a/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am +++ b/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am @@ -1,5 +1,6 @@ EXTRA_DIST = \ configure \ + config.h.cmake \ CMakeLists.txt CONFIGURE_DEPENDENCIES = \ diff --git a/storage/mroonga/vendor/groonga/vendor/onigmo/config.h.cmake b/storage/mroonga/vendor/groonga/vendor/onigmo/config.h.cmake new file mode 100644 index 00000000000..2997587d820 --- /dev/null +++ b/storage/mroonga/vendor/groonga/vendor/onigmo/config.h.cmake @@ -0,0 +1 @@ +/* dummy */ diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md index 22a7fdb17cf..f66e285bc7d 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md @@ -1,5 +1,16 @@ # News +## 1.1.0: 2015-05-29 + +### Fixes + + * Fixed a bug that full-width space isn't treated as blank character. + [groonga-dev,03215] [Reported by Shota Mitsui] + +### Thanks + + * Shota Mitsui + ## 1.0.9: 2015-03-29 ### Improves diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt index db8ffedb082..bddda0a9295 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt @@ -18,9 +18,21 @@ set(NORMALIZERS_DIR "${GROONGA_PLUGINS_DIR}/normalizers") read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mysql_sources.am MYSQL_SOURCES) if(GROONGA_NORMALIZER_MYSQL_EMBED) - add_convenience_library(mysql_normalizer ${MYSQL_SOURCES}) + add_library(mysql_normalizer STATIC ${MYSQL_SOURCES}) set_property(TARGET mysql_normalizer APPEND PROPERTY COMPILE_DEFINITIONS "GROONGA_NORMALIZER_MYSQL_EMBED") + set_target_properties( + mysql_normalizer + PROPERTIES + POSITION_INDEPENDENT_CODE ON) + if(NOT DEFINED CMAKE_C_COMPILE_OPTIONS_PIC) + # For old CMake + if(CMAKE_COMPILER_IS_GNUCXX) + set_source_files_properties(${MYSQL_SOURCES} + PROPERTIES + COMPILE_FLAGS "-fPIC") + endif() + endif() else() add_library(mysql_normalizer MODULE ${MYSQL_SOURCES}) set_target_properties(mysql_normalizer PROPERTIES diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c index c7eb102d0e1..e7961ee41f8 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c @@ -364,41 +364,50 @@ normalize(grn_ctx *ctx, grn_obj *string, rest_length = original_length_in_bytes; while (rest_length > 0) { int character_length; + grn_bool custom_normalized = GRN_FALSE; + unsigned int normalized_character_length; + unsigned int previous_normalized_length_in_bytes = + normalized_length_in_bytes; + unsigned int previous_normalized_n_characters = + normalized_n_characters; character_length = grn_plugin_charlen(ctx, rest, rest_length, encoding); if (character_length == 0) { break; } - if (remove_blank_p && character_length == 1 && rest[0] == ' ') { + if (custom_normalizer) { + custom_normalized = custom_normalizer(ctx, + rest, + &character_length, + rest_length - character_length, + normalize_table, + normalized, + &normalized_character_length, + &normalized_length_in_bytes, + &normalized_n_characters); + } + if (!custom_normalized) { + normalize_character(rest, character_length, + normalize_table, normalize_table_size, + normalized, + &normalized_character_length, + &normalized_length_in_bytes, + &normalized_n_characters); + } + + if (remove_blank_p && + normalized_character_length == 1 && + normalized[previous_normalized_length_in_bytes] == ' ') { if (current_type > types) { current_type[-1] |= GRN_CHAR_BLANK; } if (current_check) { current_check[0]++; } + normalized_length_in_bytes = previous_normalized_length_in_bytes; + normalized_n_characters = previous_normalized_n_characters; } else { - grn_bool custom_normalized = GRN_FALSE; - unsigned int normalized_character_length; - if (custom_normalizer) { - custom_normalized = custom_normalizer(ctx, - rest, - &character_length, - rest_length - character_length, - normalize_table, - normalized, - &normalized_character_length, - &normalized_length_in_bytes, - &normalized_n_characters); - } - if (!custom_normalized) { - normalize_character(rest, character_length, - normalize_table, normalize_table_size, - normalized, - &normalized_character_length, - &normalized_length_in_bytes, - &normalized_n_characters); - } if (current_type && normalized_character_length > 0) { char *current_normalized; current_normalized = diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh index fdfc8f52f03..a0a28b0d29b 100755 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh @@ -22,8 +22,8 @@ case "${distribution}" in debian) component=main run cat <<EOF > /etc/apt/sources.list.d/groonga.list -deb http://packages.groonga.org/debian/ wheezy main -deb-src http://packages.groonga.org/debian/ wheezy main +deb http://packages.groonga.org/debian/ ${code_name} main +deb-src http://packages.groonga.org/debian/ ${code_name} main EOF run apt-get update run apt-get install -y --allow-unauthenticated groonga-keyring @@ -54,4 +54,4 @@ run cd - package_initial=$(echo "${PACKAGE}" | sed -e 's/\(.\).*/\1/') pool_dir="/vagrant/repositories/${distribution}/pool/${code_name}/${component}/${package_initial}/${PACKAGE}" run mkdir -p "${pool_dir}/" -run cp *.tar.gz *.dsc *.deb "${pool_dir}/" +run cp *.tar.* *.dsc *.deb "${pool_dir}/" diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog index 7fa8d1e17f0..ea07d115215 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog @@ -1,3 +1,9 @@ +groonga-normalizer-mysql (1.1.0-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou <kou@clear-code.com> Fri, 29 May 2015 00:00:00 +0900 + groonga-normalizer-mysql (1.0.9-1) unstable; urgency=low * New upstream release. diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in index 4084576a704..f78794f1973 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in @@ -52,6 +52,9 @@ rm $RPM_BUILD_ROOT%{_libdir}/groonga/plugins/*/*.la %{_libdir}/pkgconfig/groonga-normalizer-mysql.pc %changelog +* Fri May 29 2015 Kouhei Sutou <kou@clear-code.com> - 1.1.0-1 +- new upstream release. + * Sun Mar 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 1.0.9-1 - new upstream release. diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in index 974b7c31649..8cf379086a6 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in @@ -51,6 +51,9 @@ rm $RPM_BUILD_ROOT%{_libdir}/groonga/plugins/*/*.la %{_libdir}/pkgconfig/groonga-normalizer-mysql.pc %changelog +* Fri May 29 2015 Kouhei Sutou <kou@clear-code.com> - 1.1.0-1 +- new upstream release. + * Sun Mar 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 1.0.9-1 - new upstream release. diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version index e5a4a5e7d84..1cc5f657e05 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version @@ -1 +1 @@ -1.0.9
\ No newline at end of file +1.1.0
\ No newline at end of file diff --git a/storage/mroonga/version b/storage/mroonga/version index 760b908bf87..c22ec448710 100644 --- a/storage/mroonga/version +++ b/storage/mroonga/version @@ -1 +1 @@ -5.02
\ No newline at end of file +5.04
\ No newline at end of file diff --git a/storage/mroonga/version_in_hex b/storage/mroonga/version_in_hex index 7716095f96c..b2bfc453d0e 100644 --- a/storage/mroonga/version_in_hex +++ b/storage/mroonga/version_in_hex @@ -1 +1 @@ -0x0502
\ No newline at end of file +0x0504
\ No newline at end of file diff --git a/storage/mroonga/version_micro b/storage/mroonga/version_micro index d8263ee9860..bf0d87ab1b2 100644 --- a/storage/mroonga/version_micro +++ b/storage/mroonga/version_micro @@ -1 +1 @@ -2
\ No newline at end of file +4
\ No newline at end of file |