diff options
author | Kentoku SHIBA <kentokushiba@gmail.com> | 2015-04-30 04:44:30 +0900 |
---|---|---|
committer | Kentoku SHIBA <kentokushiba@gmail.com> | 2015-04-30 04:44:30 +0900 |
commit | a0fdb258a435290980993ae025a7fc19c09d2cdb (patch) | |
tree | 67023cf51c542ed78443d68e9c61b28b39583245 /storage/mroonga/vendor/groonga/lib | |
parent | 060ec5b6b9384456695b6fc903ccfeb8c7ccd298 (diff) | |
download | mariadb-git-a0fdb258a435290980993ae025a7fc19c09d2cdb.tar.gz |
Update Mroonga to the latest version on 2015-04-30T04:44:30+0900
Diffstat (limited to 'storage/mroonga/vendor/groonga/lib')
100 files changed, 6674 insertions, 3470 deletions
diff --git a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt index 2103436545f..8959f883ca3 100644 --- a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt @@ -19,6 +19,7 @@ add_definitions( include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/dat + ${ONIGMO_INCLUDE_DIRS} ${MRUBY_INCLUDE_DIRS} ${LIBLZ4_INCLUDE_DIRS}) link_directories( @@ -42,10 +43,13 @@ set_source_files_properties(dat.cpp ${LIBGRNDAT_SOURCES} set(GRN_ALL_SOURCES ${LIBGROONGA_SOURCES} ${LIBGRNDAT_SOURCES} - ${LIBGRNMRB_SOURCES} - ${MRUBY_LIBS}) + ${LIBGRNMRB_SOURCES}) if(GRN_EMBED) add_library(libgroonga STATIC ${GRN_ALL_SOURCES}) + set_target_properties( + libgroonga + PROPERTIES + POSITION_INDEPENDENT_CODE ON) else() add_library(libgroonga SHARED ${GRN_ALL_SOURCES}) endif() @@ -59,7 +63,9 @@ set(GRN_ALL_LIBRARIES ${LIBLZ4_LIBRARIES} ${DL_LIBS} ${M_LIBS} - ${WS2_32_LIBS}) + ${WS2_32_LIBS} + ${MRUBY_LIBS} + ${ONIGMO_LIBS}) if(GRN_EMBED) target_link_libraries(libgroonga ${GRN_ALL_LIBRARIES} @@ -73,7 +79,7 @@ else() RUNTIME DESTINATION "${BIN_DIR}") endif() -if(GRN_WITH_MRUBY AND NOT GRN_EMBED) +if(GRN_WITH_MRUBY) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/sources.am RUBY_SCRIPTS) string(REGEX REPLACE "([^;]+)" "mrb/scripts/\\1" @@ -81,4 +87,36 @@ if(GRN_WITH_MRUBY AND NOT GRN_EMBED) install( FILES ${RUBY_SCRIPTS} DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}") + + read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/command_line/sources.am + COMMANE_LINE_RUBY_SCRIPTS) + string(REGEX REPLACE "([^;]+)" "mrb/scripts/command_line/\\1" + COMMANE_LINE_RUBY_SCRIPTS "${COMMANE_LINE_RUBY_SCRIPTS}") + install( + FILES ${COMMANE_LINE_RUBY_SCRIPTS} + DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/command_line") + + read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/context/sources.am + CONTEXT_RUBY_SCRIPTS) + string(REGEX REPLACE "([^;]+)" "mrb/scripts/context/\\1" + CONTEXT_RUBY_SCRIPTS "${CONTEXT_RUBY_SCRIPTS}") + install( + FILES ${CONTEXT_RUBY_SCRIPTS} + DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/context") + + read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/initialize/sources.am + INITIALIZE_RUBY_SCRIPTS) + string(REGEX REPLACE "([^;]+)" "mrb/scripts/initialize/\\1" + INITIALIZE_RUBY_SCRIPTS "${INITIALIZE_RUBY_SCRIPTS}") + install( + FILES ${INITIALIZE_RUBY_SCRIPTS} + DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/initialize") + + read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/logger/sources.am + LOGGER_RUBY_SCRIPTS) + string(REGEX REPLACE "([^;]+)" "mrb/scripts/logger/\\1" + LOGGER_RUBY_SCRIPTS "${LOGGER_RUBY_SCRIPTS}") + install( + FILES ${LOGGER_RUBY_SCRIPTS} + DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/logger") endif() diff --git a/storage/mroonga/vendor/groonga/lib/com.c b/storage/mroonga/vendor/groonga/lib/com.c index a17d3a931de..eb1cacfd4c1 100644 --- a/storage/mroonga/vendor/groonga/lib/com.c +++ b/storage/mroonga/vendor/groonga/lib/com.c @@ -328,10 +328,10 @@ grn_com_event_fin(grn_ctx *ctx, grn_com_event *ev) #ifndef USE_SELECT if (ev->events) { GRN_FREE(ev->events); } # ifdef USE_EPOLL - GRN_CLOSE(ev->epfd); + grn_close(ev->epfd); # endif /* USE_EPOLL */ # ifdef USE_KQUEUE - GRN_CLOSE(ev->kqfd); + grn_close(ev->kqfd); # endif /* USE_KQUEUE*/ #endif /* USE_SELECT */ return GRN_SUCCESS; @@ -528,7 +528,7 @@ grn_com_receiver(grn_ctx *ctx, grn_com *com) grn_msg *msg = (grn_msg *)grn_msg_open(ctx, com, &ev->recv_old); grn_com_recv(ctx, msg->u.peer, &msg->header, (grn_obj *)msg); if (msg->u.peer /* is_edge_request(msg)*/) { - memcpy(&msg->edge_id, &ev->curr_edge_id, sizeof(grn_com_addr)); + grn_memcpy(&msg->edge_id, &ev->curr_edge_id, sizeof(grn_com_addr)); if (!com->has_sid) { com->has_sid = 1; com->sid = ev->curr_edge_id.sid++; @@ -560,11 +560,26 @@ grn_com_event_poll(grn_ctx *ctx, grn_com_event *ev, int timeout) FD_ZERO(&wfds); ctx->errlvl = GRN_OK; ctx->rc = GRN_SUCCESS; - GRN_HASH_EACH(ctx, ev->hash, eh, &pfd, &dummy, &com, { - if ((com->events & GRN_COM_POLLIN)) { FD_SET(*pfd, &rfds); } - if ((com->events & GRN_COM_POLLOUT)) { FD_SET(*pfd, &wfds); } - if (*pfd > nfds) { nfds = *pfd; } - }); + { + grn_hash_cursor *cursor; + cursor = grn_hash_cursor_open(ctx, ev->hash, NULL, 0, NULL, 0, 0, -1, 0); + if (cursor) { + grn_id id; + while ((id = grn_hash_cursor_next(ctx, cursor))) { + grn_hash_cursor_get_key_value(ctx, + cursor, + (void **)(&pfd), + &dummy, + (void **)(&com)); + if ((com->events & GRN_COM_POLLIN)) { FD_SET(*pfd, &rfds); } + if ((com->events & GRN_COM_POLLOUT)) { FD_SET(*pfd, &wfds); } +# ifndef WIN32 + if (*pfd > nfds) { nfds = *pfd; } +# endif /* WIN32 */ + } + grn_hash_cursor_close(ctx, cursor); + } + } nevents = select(nfds + 1, &rfds, &wfds, NULL, (timeout >= 0) ? &tv : NULL); if (nevents < 0) { SOERR("select"); @@ -926,7 +941,8 @@ grn_com_copen(grn_ctx *ctx, grn_com_event *ev, const char *dest, int port) #ifdef AI_NUMERICSERV hints.ai_flags = AI_NUMERICSERV; #endif - snprintf(port_string, sizeof(port_string), "%d", port); + grn_snprintf(port_string, sizeof(port_string), sizeof(port_string), + "%d", port); getaddrinfo_result = getaddrinfo(dest, port_string, &hints, &addrinfo_list); if (getaddrinfo_result != 0) { @@ -1034,7 +1050,8 @@ grn_com_sopen(grn_ctx *ctx, grn_com_event *ev, if (!bind_address) { bind_address = "0.0.0.0"; } - snprintf(port_string, sizeof(port_string), "%d", port); + grn_snprintf(port_string, sizeof(port_string), sizeof(port_string), + "%d", port); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -1069,7 +1086,7 @@ grn_com_sopen(grn_ctx *ctx, grn_com_event *ev, SOERR("socket"); goto exit; } - memcpy(&ev->curr_edge_id.addr, he->h_addr, he->h_length); + grn_memcpy(&ev->curr_edge_id.addr, he->h_addr, he->h_length); ev->curr_edge_id.port = htons(port); ev->curr_edge_id.sid = 0; { diff --git a/storage/mroonga/vendor/groonga/lib/command.c b/storage/mroonga/vendor/groonga/lib/command.c index b0f75229744..e4be0d1ff92 100644 --- a/storage/mroonga/vendor/groonga/lib/command.c +++ b/storage/mroonga/vendor/groonga/lib/command.c @@ -57,7 +57,7 @@ grn_command_input_close(grn_ctx *ctx, grn_command_input *input) GRN_API_ENTER; /* TODO: Free input->arguments by self. */ - grn_expr_clear_vars(ctx, input->command); + /* grn_expr_clear_vars(ctx, input->command); */ GRN_FREE(input); GRN_API_RETURN(ctx->rc); diff --git a/storage/mroonga/vendor/groonga/lib/ctx.c b/storage/mroonga/vendor/groonga/lib/ctx.c index 5408832dfcc..85878036dc2 100644 --- a/storage/mroonga/vendor/groonga/lib/ctx.c +++ b/storage/mroonga/vendor/groonga/lib/ctx.c @@ -27,13 +27,26 @@ #include "grn_output.h" #include "grn_normalizer.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> +# include <netinet/in.h> #endif /* HAVE_NETINET_IN_H */ +#ifdef WIN32 +# include <share.h> +#endif /* WIN32 */ + +#if defined(HAVE__LOCALTIME64_S) && defined(__GNUC__) +# ifdef _WIN64 +# define localtime_s(tm, time) _localtime64_s(tm, time) +# else /* _WIN64 */ +# define localtime_s(tm, time) _localtime32_s(tm, time) +# endif /* _WIN64 */ +#endif /* defined(HAVE__LOCALTIME64_S) && defined(__GNUC__) */ + #define GRN_CTX_INITIALIZER(enc) \ { GRN_SUCCESS, 0, enc, 0, GRN_LOG_NOTICE,\ GRN_CTX_FIN, 0, 0, 0, 0, {0}, NULL, NULL, NULL, NULL, NULL } @@ -129,34 +142,48 @@ grn_time_now(grn_ctx *ctx, grn_obj *obj) GRN_TIME_NSEC_TO_USEC(tv.tv_nsec))); } -grn_rc -grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf) +struct tm * +grn_timeval2tm(grn_ctx *ctx, grn_timeval *tv, struct tm *tm_buffer) { struct tm *ltm; const char *function_name; #ifdef HAVE__LOCALTIME64_S - struct tm tm; time_t t = tv->tv_sec; function_name = "localtime_s"; - ltm = (localtime_s(&tm, &t) == 0) ? &tm : NULL; + ltm = (localtime_s(tm_buffer, &t) == 0) ? tm_buffer : NULL; #else /* HAVE__LOCALTIME64_S */ # ifdef HAVE_LOCALTIME_R - struct tm tm; time_t t = tv->tv_sec; function_name = "localtime_r"; - ltm = localtime_r(&t, &tm); + ltm = localtime_r(&t, tm_buffer); # else /* HAVE_LOCALTIME_R */ time_t tvsec = (time_t) tv->tv_sec; function_name = "localtime"; ltm = localtime(&tvsec); # endif /* HAVE_LOCALTIME_R */ #endif /* HAVE__LOCALTIME64_S */ - if (!ltm) { SERR(function_name); } - snprintf(buf, GRN_TIMEVAL_STR_SIZE - 1, GRN_TIMEVAL_STR_FORMAT, - ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, - ltm->tm_hour, ltm->tm_min, ltm->tm_sec, - (int)(GRN_TIME_NSEC_TO_USEC(tv->tv_nsec))); - buf[GRN_TIMEVAL_STR_SIZE - 1] = '\0'; + if (!ltm) { + SERR(function_name); + } + return ltm; +} + +grn_rc +grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf, size_t buf_size) +{ + struct tm tm; + struct tm *ltm; + ltm = grn_timeval2tm(ctx, tv, &tm); + grn_snprintf(buf, buf_size, GRN_TIMEVAL_STR_SIZE, + GRN_TIMEVAL_STR_FORMAT, + ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, + ltm->tm_hour, ltm->tm_min, ltm->tm_sec, + (int)(GRN_TIME_NSEC_TO_USEC(tv->tv_nsec))); + if (buf_size > GRN_TIMEVAL_STR_SIZE) { + buf[GRN_TIMEVAL_STR_SIZE - 1] = '\0'; + } else { + buf[buf_size - 1] = '\0'; + } return ctx->rc; } @@ -235,7 +262,7 @@ grn_alloc_info_set_backtrace(char *buffer, size_t size) if (symbol_length + 2 > rest) { break; } - memcpy(buffer, symbols[i], symbol_length); + grn_memcpy(buffer, symbols[i], symbol_length); buffer += symbol_length; rest -= symbol_length; buffer[0] = '\n'; @@ -453,7 +480,7 @@ grn_ctx_loader_clear(grn_ctx *ctx) #ifdef GRN_WITH_MESSAGE_PACK static int -grn_msgpack_buffer_write(void *data, const char *buf, unsigned int len) +grn_msgpack_buffer_write(void *data, const char *buf, msgpack_size_t len) { grn_ctx *ctx = (grn_ctx *)data; return grn_bulk_write(ctx, ctx->impl->outbuf, buf, len); @@ -550,7 +577,7 @@ grn_ctx_set_next_expr(grn_ctx *ctx, grn_obj *expr) } static void -grn_ctx_impl_clear_n_same_error_mssagges(grn_ctx *ctx) +grn_ctx_impl_clear_n_same_error_messagges(grn_ctx *ctx) { if (ctx->impl->n_same_error_messages == 0) { return; @@ -583,8 +610,8 @@ grn_ctx_impl_set_current_error_message(grn_ctx *ctx) return; } - grn_ctx_impl_clear_n_same_error_mssagges(ctx); - strcpy(ctx->impl->previous_errbuf, ctx->errbuf); + grn_ctx_impl_clear_n_same_error_messagges(ctx); + grn_strcpy(ctx->impl->previous_errbuf, GRN_CTX_MSGSIZE, ctx->errbuf); } static grn_rc @@ -594,8 +621,14 @@ grn_ctx_init_internal(grn_ctx *ctx, int flags) // if (ctx->stat != GRN_CTX_FIN) { return GRN_INVALID_ARGUMENT; } ERRCLR(ctx); ctx->flags = flags; - if (getenv("GRN_CTX_PER_DB") && strcmp(getenv("GRN_CTX_PER_DB"), "yes") == 0) { - ctx->flags |= GRN_CTX_PER_DB; + { + 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 (ERRP(ctx, GRN_ERROR)) { return ctx->rc; } ctx->stat = GRN_CTX_INITED; @@ -661,7 +694,7 @@ grn_ctx_fin(grn_ctx *ctx) CRITICAL_SECTION_LEAVE(grn_glock); } if (ctx->impl) { - grn_ctx_impl_clear_n_same_error_mssagges(ctx); + grn_ctx_impl_clear_n_same_error_messagges(ctx); if (ctx->impl->finalizer) { ctx->impl->finalizer(ctx, 0, NULL, &(ctx->user_data)); } @@ -756,474 +789,12 @@ grn_ctx_set_finalizer(grn_ctx *ctx, grn_proc_func *finalizer) grn_timeval grn_starttime; -static char *default_logger_path = NULL; -static FILE *default_logger_file = NULL; -static grn_critical_section default_logger_lock; - -static void -default_logger_log(grn_ctx *ctx, grn_log_level level, - const char *timestamp, const char *title, - const char *message, const char *location, void *user_data) -{ - const char slev[] = " EACewnid-"; - if (default_logger_path) { - CRITICAL_SECTION_ENTER(default_logger_lock); - if (!default_logger_file) { - default_logger_file = fopen(default_logger_path, "a"); - } - if (default_logger_file) { - if (location && *location) { - fprintf(default_logger_file, "%s|%c|%s %s %s\n", - timestamp, *(slev + level), title, message, location); - } else { - fprintf(default_logger_file, "%s|%c|%s %s\n", timestamp, - *(slev + level), title, message); - } - fflush(default_logger_file); - } - CRITICAL_SECTION_LEAVE(default_logger_lock); - } -} - -static void -default_logger_reopen(grn_ctx *ctx, void *user_data) -{ - GRN_LOG(ctx, GRN_LOG_NOTICE, "log will be closed."); - CRITICAL_SECTION_ENTER(default_logger_lock); - if (default_logger_file) { - fclose(default_logger_file); - default_logger_file = NULL; - } - CRITICAL_SECTION_LEAVE(default_logger_lock); - GRN_LOG(ctx, GRN_LOG_NOTICE, "log opened."); -} - -static void -default_logger_fin(grn_ctx *ctx, void *user_data) -{ - CRITICAL_SECTION_ENTER(default_logger_lock); - if (default_logger_file) { - fclose(default_logger_file); - default_logger_file = NULL; - } - CRITICAL_SECTION_LEAVE(default_logger_lock); -} - -static grn_logger default_logger = { - GRN_LOG_DEFAULT_LEVEL, - GRN_LOG_TIME|GRN_LOG_MESSAGE, - NULL, - default_logger_log, - default_logger_reopen, - default_logger_fin -}; - -static grn_logger current_logger = { - GRN_LOG_DEFAULT_LEVEL, - GRN_LOG_TIME|GRN_LOG_MESSAGE, - NULL, - NULL, - NULL, - NULL -}; - -void -grn_default_logger_set_max_level(grn_log_level max_level) -{ - default_logger.max_level = max_level; - if (current_logger.log == default_logger_log) { - current_logger.max_level = max_level; - } -} - -grn_log_level -grn_default_logger_get_max_level(void) -{ - return default_logger.max_level; -} - -void -grn_default_logger_set_path(const char *path) -{ - if (default_logger_path) { - free(default_logger_path); - } - - if (path) { - default_logger_path = strdup(path); - } else { - default_logger_path = NULL; - } -} - -const char * -grn_default_logger_get_path(void) -{ - return default_logger_path; -} - -void -grn_logger_reopen(grn_ctx *ctx) -{ - if (current_logger.reopen) { - current_logger.reopen(ctx, current_logger.user_data); - } -} - -static void -grn_logger_fin(grn_ctx *ctx) -{ - if (current_logger.fin) { - current_logger.fin(ctx, current_logger.user_data); - } -} - -static void -logger_info_func_wrapper(grn_ctx *ctx, grn_log_level level, - const char *timestamp, const char *title, - const char *message, const char *location, - void *user_data) -{ - grn_logger_info *info = user_data; - info->func(level, timestamp, title, message, location, info->func_arg); -} - -/* Deprecated since 2.1.2. */ -grn_rc -grn_logger_info_set(grn_ctx *ctx, const grn_logger_info *info) -{ - if (info) { - grn_logger logger; - - memset(&logger, 0, sizeof(grn_logger)); - logger.max_level = info->max_level; - logger.flags = info->flags; - if (info->func) { - logger.log = logger_info_func_wrapper; - logger.user_data = (grn_logger_info *)info; - } else { - logger.log = default_logger_log; - logger.reopen = default_logger_reopen; - logger.fin = default_logger_fin; - } - return grn_logger_set(ctx, &logger); - } else { - return grn_logger_set(ctx, NULL); - } -} - -grn_rc -grn_logger_set(grn_ctx *ctx, const grn_logger *logger) -{ - grn_logger_fin(ctx); - if (logger) { - current_logger = *logger; - } else { - current_logger = default_logger; - } - return GRN_SUCCESS; -} - -void -grn_logger_set_max_level(grn_ctx *ctx, grn_log_level max_level) -{ - current_logger.max_level = max_level; -} - -grn_log_level -grn_logger_get_max_level(grn_ctx *ctx) -{ - return current_logger.max_level; -} - -grn_bool -grn_logger_pass(grn_ctx *ctx, grn_log_level level) -{ - return level <= current_logger.max_level; -} - -#define TBUFSIZE GRN_TIMEVAL_STR_SIZE -#define MBUFSIZE 0x1000 -#define LBUFSIZE 0x400 - -void -grn_logger_put(grn_ctx *ctx, grn_log_level level, - const char *file, int line, const char *func, const char *fmt, ...) -{ - if (level <= current_logger.max_level && current_logger.log) { - char tbuf[TBUFSIZE]; - char mbuf[MBUFSIZE]; - char lbuf[LBUFSIZE]; - tbuf[0] = '\0'; - if (current_logger.flags & GRN_LOG_TIME) { - grn_timeval tv; - grn_timeval_now(ctx, &tv); - grn_timeval2str(ctx, &tv, tbuf); - } - if (current_logger.flags & GRN_LOG_MESSAGE) { - va_list argp; - va_start(argp, fmt); - vsnprintf(mbuf, MBUFSIZE - 1, fmt, argp); - va_end(argp); - mbuf[MBUFSIZE - 1] = '\0'; - } else { - mbuf[0] = '\0'; - } - if (current_logger.flags & GRN_LOG_LOCATION) { - snprintf(lbuf, LBUFSIZE - 1, "%d %s:%d %s()", getpid(), file, line, func); - lbuf[LBUFSIZE - 1] = '\0'; - } else { - lbuf[0] = '\0'; - } - current_logger.log(ctx, level, tbuf, "", mbuf, lbuf, - current_logger.user_data); - } -} - -static void -logger_init(void) -{ - if (!default_logger_path) { - default_logger_path = strdup(GRN_LOG_PATH); - } - memcpy(¤t_logger, &default_logger, sizeof(grn_logger)); - CRITICAL_SECTION_INIT(default_logger_lock); -} - -static void -logger_fin(grn_ctx *ctx) -{ - grn_logger_fin(ctx); - if (default_logger_path) { - free(default_logger_path); - default_logger_path = NULL; - } - CRITICAL_SECTION_FIN(default_logger_lock); -} - - -static char *default_query_logger_path = NULL; -static FILE *default_query_logger_file = NULL; -static grn_critical_section default_query_logger_lock; - -static void -default_query_logger_log(grn_ctx *ctx, unsigned int flag, - const char *timestamp, const char *info, - const char *message, void *user_data) -{ - if (default_query_logger_path) { - CRITICAL_SECTION_ENTER(default_query_logger_lock); - if (!default_query_logger_file) { - default_query_logger_file = fopen(default_query_logger_path, "a"); - } - if (default_query_logger_file) { - fprintf(default_query_logger_file, "%s|%s%s\n", timestamp, info, message); - fflush(default_query_logger_file); - } - CRITICAL_SECTION_LEAVE(default_query_logger_lock); - } -} - -static void -default_query_logger_close(grn_ctx *ctx, void *user_data) -{ - GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ", - "query log will be closed: <%s>", default_query_logger_path); - CRITICAL_SECTION_ENTER(default_query_logger_lock); - if (default_query_logger_file) { - fclose(default_query_logger_file); - default_query_logger_file = NULL; - } - CRITICAL_SECTION_LEAVE(default_query_logger_lock); -} - -static void -default_query_logger_reopen(grn_ctx *ctx, void *user_data) -{ - default_query_logger_close(ctx, user_data); - if (default_query_logger_path) { - GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ", - "query log is opened: <%s>", default_query_logger_path); - } -} - -static void -default_query_logger_fin(grn_ctx *ctx, void *user_data) -{ - if (default_query_logger_file) { - default_query_logger_close(ctx, user_data); - } -} - -static grn_query_logger default_query_logger = { - GRN_QUERY_LOG_DEFAULT, - NULL, - default_query_logger_log, - default_query_logger_reopen, - default_query_logger_fin -}; - -static grn_query_logger current_query_logger = { - GRN_QUERY_LOG_DEFAULT, - NULL, - NULL, - NULL, - NULL -}; - -void -grn_default_query_logger_set_flags(unsigned int flags) -{ - default_query_logger.flags = flags; - if (current_query_logger.log == default_query_logger_log) { - current_query_logger.flags = flags; - } -} - -unsigned int -grn_default_query_logger_get_flags(void) -{ - return default_query_logger.flags; -} - -void -grn_default_query_logger_set_path(const char *path) -{ - if (default_query_logger_path) { - free(default_query_logger_path); - } - - if (path) { - default_query_logger_path = strdup(path); - } else { - default_query_logger_path = NULL; - } -} - -const char * -grn_default_query_logger_get_path(void) -{ - return default_query_logger_path; -} - -void -grn_query_logger_reopen(grn_ctx *ctx) -{ - if (current_query_logger.reopen) { - current_query_logger.reopen(ctx, current_query_logger.user_data); - } -} - -static void -grn_query_logger_fin(grn_ctx *ctx) -{ - if (current_query_logger.fin) { - current_query_logger.fin(ctx, current_query_logger.user_data); - } -} - -grn_rc -grn_query_logger_set(grn_ctx *ctx, const grn_query_logger *logger) -{ - grn_query_logger_fin(ctx); - if (logger) { - current_query_logger = *logger; - } else { - current_query_logger = default_query_logger; - } - return GRN_SUCCESS; -} - -grn_bool -grn_query_logger_pass(grn_ctx *ctx, unsigned int flag) -{ - return current_query_logger.flags & flag; -} - -#define TIMESTAMP_BUFFER_SIZE TBUFSIZE -/* 8+a(%p) + 1(|) + 1(mark) + 15(elapsed time) = 25+a */ -#define INFO_BUFFER_SIZE 40 - -void -grn_query_logger_put(grn_ctx *ctx, unsigned int flag, const char *mark, - const char *format, ...) -{ - char timestamp[TIMESTAMP_BUFFER_SIZE]; - char info[INFO_BUFFER_SIZE]; - grn_obj *message = &ctx->impl->query_log_buf; - - if (!current_query_logger.log) { - return; - } - - { - grn_timeval tv; - timestamp[0] = '\0'; - grn_timeval_now(ctx, &tv); - grn_timeval2str(ctx, &tv, timestamp); - } - - if (flag & (GRN_QUERY_LOG_COMMAND | GRN_QUERY_LOG_DESTINATION)) { - snprintf(info, INFO_BUFFER_SIZE - 1, "%p|%s", ctx, mark); - info[INFO_BUFFER_SIZE - 1] = '\0'; - } else { - grn_timeval tv; - uint64_t elapsed_time; - grn_timeval_now(ctx, &tv); - elapsed_time = - (uint64_t)(tv.tv_sec - ctx->impl->tv.tv_sec) * GRN_TIME_NSEC_PER_SEC + - (tv.tv_nsec - ctx->impl->tv.tv_nsec); - - snprintf(info, INFO_BUFFER_SIZE - 1, - "%p|%s%015" GRN_FMT_INT64U " ", ctx, mark, elapsed_time); - info[INFO_BUFFER_SIZE - 1] = '\0'; - } - - { - va_list args; - - va_start(args, format); - GRN_BULK_REWIND(message); - grn_text_vprintf(ctx, message, format, args); - va_end(args); - GRN_TEXT_PUTC(ctx, message, '\0'); - } - - current_query_logger.log(ctx, flag, timestamp, info, GRN_TEXT_VALUE(message), - current_query_logger.user_data); -} - -static void -query_logger_init(void) -{ - memcpy(¤t_query_logger, &default_query_logger, sizeof(grn_query_logger)); - CRITICAL_SECTION_INIT(default_query_logger_lock); -} - -static void -query_logger_fin(grn_ctx *ctx) -{ - grn_query_logger_fin(ctx); - if (default_query_logger_path) { - free(default_query_logger_path); - } - CRITICAL_SECTION_FIN(default_query_logger_lock); -} - -void -grn_log_reopen(grn_ctx *ctx) -{ - grn_logger_reopen(ctx); - grn_query_logger_reopen(ctx); -} - - static void check_overcommit_memory(grn_ctx *ctx) { FILE *file; int value; - file = fopen("/proc/sys/vm/overcommit_memory", "r"); + file = grn_fopen("/proc/sys/vm/overcommit_memory", "r"); if (!file) { return; } value = fgetc(file); if (value != '1') { @@ -1245,25 +816,13 @@ check_overcommit_memory(grn_ctx *ctx) fclose(file); } -static void -check_grn_ja_skip_same_value_put(grn_ctx *ctx) -{ - const char *grn_ja_skip_same_value_put_env; - - grn_ja_skip_same_value_put_env = getenv("GRN_JA_SKIP_SAME_VALUE_PUT"); - if (grn_ja_skip_same_value_put_env && - strcmp(grn_ja_skip_same_value_put_env, "no") == 0) { - grn_ja_skip_same_value_put = GRN_FALSE; - } -} - grn_rc grn_init(void) { grn_rc rc; grn_ctx *ctx = &grn_gctx; - logger_init(); - query_logger_init(); + grn_logger_init(); + grn_query_logger_init(); CRITICAL_SECTION_INIT(grn_glock); grn_gtick = 0; ctx->next = ctx; @@ -1288,22 +847,50 @@ grn_init(void) } // expand_stack(); #ifdef USE_FAIL_MALLOC - if (getenv("GRN_FMALLOC_PROB")) { - grn_fmalloc_prob = strtod(getenv("GRN_FMALLOC_PROB"), 0) * RAND_MAX; - if (getenv("GRN_FMALLOC_SEED")) { - srand((unsigned int)atoi(getenv("GRN_FMALLOC_SEED"))); - } else { - srand((unsigned int)time(NULL)); + { + char grn_fmalloc_prob_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_FMALLOC_PROB", + grn_fmalloc_prob_env, + GRN_ENV_BUFFER_SIZE); + if (grn_fmalloc_prob_env[0]) { + char grn_fmalloc_seed_env[GRN_ENV_BUFFER_SIZE]; + grn_fmalloc_prob = strtod(grn_fmalloc_prob_env, 0) * RAND_MAX; + grn_getenv("GRN_FMALLOC_SEED", + grn_fmalloc_seed_env, + GRN_ENV_BUFFER_SIZE); + if (grn_fmalloc_seed_env[0]) { + srand((unsigned int)atoi(grn_fmalloc_seed_env)); + } else { + srand((unsigned int)time(NULL)); + } } } - if (getenv("GRN_FMALLOC_FUNC")) { - grn_fmalloc_func = getenv("GRN_FMALLOC_FUNC"); + { + static char grn_fmalloc_func_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_FMALLOC_FUNC", + grn_fmalloc_func_env, + GRN_ENV_BUFFER_SIZE); + if (grn_fmalloc_func_env[0]) { + grn_fmalloc_func = grn_fmalloc_func_env; + } } - if (getenv("GRN_FMALLOC_FILE")) { - grn_fmalloc_file = getenv("GRN_FMALLOC_FILE"); + { + static char grn_fmalloc_file_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_FMALLOC_FILE", + grn_fmalloc_file_env, + GRN_ENV_BUFFER_SIZE); + if (grn_fmalloc_file_env[0]) { + grn_fmalloc_file = grn_fmalloc_file_env; + } } - if (getenv("GRN_FMALLOC_LINE")) { - grn_fmalloc_line = atoi(getenv("GRN_FMALLOC_LINE")); + { + char grn_fmalloc_line_env[GRN_ENV_BUFFER_SIZE]; + grn_getenv("GRN_FMALLOC_LINE", + grn_fmalloc_line_env, + GRN_ENV_BUFFER_SIZE); + if (grn_fmalloc_line_env[0]) { + grn_fmalloc_line = atoi(grn_fmalloc_line_env); + } } #endif /* USE_FAIL_MALLOC */ if ((rc = grn_com_init())) { @@ -1343,7 +930,6 @@ grn_init(void) } GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_init"); check_overcommit_memory(ctx); - check_grn_ja_skip_same_value_put(ctx); return rc; } @@ -1426,7 +1012,7 @@ grn_fin(void) GRN_GFREE(ctx); } } - query_logger_fin(ctx); + grn_query_logger_fin(ctx); grn_request_canceler_fin(); grn_cache_fin(); grn_tokenizers_fin(); @@ -1436,7 +1022,7 @@ grn_fin(void) grn_ctx_fin(ctx); grn_com_fin(); GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_fin (%d)", alloc_count); - logger_fin(ctx); + grn_logger_fin(ctx); CRITICAL_SECTION_FIN(grn_glock); return GRN_SUCCESS; } @@ -1511,6 +1097,26 @@ grn_ctx_set_output_type(grn_ctx *ctx, grn_content_type type) if (ctx->impl) { ctx->impl->output_type = type; + switch (ctx->impl->output_type) { + case GRN_CONTENT_NONE : + ctx->impl->mime_type = "application/octet-stream"; + break; + case GRN_CONTENT_TSV : + ctx->impl->mime_type = "text/tab-separated-values"; + break; + case GRN_CONTENT_JSON : + ctx->impl->mime_type = "application/json"; + break; + case GRN_CONTENT_XML : + ctx->impl->mime_type = "text/xml"; + break; + case GRN_CONTENT_MSGPACK : + ctx->impl->mime_type = "application/x-msgpack"; + break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + ctx->impl->mime_type = "text/x-groonga-command-list"; + break; + } } else { rc = GRN_INVALID_ARGUMENT; } @@ -1630,7 +1236,7 @@ get_content_mime_type(grn_ctx *ctx, const char *p, const char *pe) ctx->impl->mime_type = "text/plain"; } else if (p + 3 == pe && !memcmp(p, "tsv", 3)) { ctx->impl->output_type = GRN_CONTENT_TSV; - ctx->impl->mime_type = "text/plain"; + ctx->impl->mime_type = "text/tab-separated-values"; } break; case 'x': @@ -1870,6 +1476,7 @@ grn_rc grn_ctx_sendv(grn_ctx *ctx, int argc, char **argv, int flags) { grn_obj buf; + GRN_API_ENTER; GRN_TEXT_INIT(&buf, 0); while (argc--) { // todo : encode into json like syntax @@ -1879,7 +1486,7 @@ grn_ctx_sendv(grn_ctx *ctx, int argc, char **argv, int flags) } grn_ctx_send(ctx, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf), flags); GRN_OBJ_FIN(ctx, &buf); - return ctx->rc; + GRN_API_RETURN(ctx->rc); } static int @@ -2103,7 +1710,7 @@ grn_cache_open(grn_ctx *ctx) cache->next = (grn_cache_entry *)cache; cache->prev = (grn_cache_entry *)cache; - cache->hash = grn_hash_create(&grn_gctx, NULL, GRN_TABLE_MAX_KEY_SIZE, + cache->hash = grn_hash_create(&grn_gctx, NULL, GRN_CACHE_MAX_KEY_SIZE, sizeof(grn_cache_entry), GRN_OBJ_KEY_VAR_SIZE); MUTEX_INIT(cache->mutex); cache->max_nentries = GRN_CACHE_DEFAULT_MAX_N_ENTRIES; @@ -2157,10 +1764,18 @@ grn_cache_init(void) grn_rc grn_cache_set_max_n_entries(grn_ctx *ctx, grn_cache *cache, unsigned int n) { + uint32_t current_max_n_entries; + if (!cache) { return GRN_INVALID_ARGUMENT; } + + current_max_n_entries = cache->max_nentries; cache->max_nentries = n; + if (n < current_max_n_entries) { + grn_cache_expire(cache, current_max_n_entries - n); + } + return GRN_SUCCESS; } @@ -2412,7 +2027,7 @@ grn_ctx_realloc(grn_ctx *ctx, void *ptr, size_t size, if (res && ptr) { int32_t *header = &((int32_t *)ptr)[-2]; size_t size_ = header[1]; - memcpy(res, ptr, size_ > size ? size : size_); + grn_memcpy(res, ptr, size_ > size ? size : size_); grn_ctx_free(ctx, ptr, file, line, func); } } else { @@ -2428,7 +2043,7 @@ grn_ctx_strdup(grn_ctx *ctx, const char *s, const char* file, int line, const ch if (s) { size_t size = strlen(s) + 1; if ((res = grn_ctx_alloc(ctx, size, 0, file, line, func))) { - memcpy(res, s, size); + grn_memcpy(res, s, size); } } return res; @@ -2669,6 +2284,20 @@ grn_ctx_set_strdup(grn_ctx *ctx, grn_strdup_func strdup_func) ctx->impl->strdup_func = strdup_func; } +grn_free_func +grn_ctx_get_free(grn_ctx *ctx) +{ + if (!ctx || !ctx->impl) { return NULL; } + return ctx->impl->free_func; +} + +void +grn_ctx_set_free(grn_ctx *ctx, grn_free_func free_func) +{ + if (!ctx || !ctx->impl) { return; } + ctx->impl->free_func = free_func; +} + void * grn_malloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func) { @@ -2708,6 +2337,16 @@ grn_strdup(grn_ctx *ctx, const char *string, const char* file, int line, const c return grn_strdup_default(ctx, string, file, line, func); } } + +void +grn_free(grn_ctx *ctx, void *ptr, const char* file, int line, const char *func) +{ + if (ctx && ctx->impl && ctx->impl->free_func) { + return ctx->impl->free_func(ctx, ptr, file, line, func); + } else { + return grn_free_default(ctx, ptr, file, line, func); + } +} #endif void * @@ -2810,12 +2449,12 @@ grn_strdup_default(grn_ctx *ctx, const char *s, const char* file, int line, cons { if (!ctx) { return NULL; } { - char *res = strdup(s); + char *res = grn_strdup_raw(s); if (res) { GRN_ADD_ALLOC_COUNT(1); grn_alloc_info_add(res, file, line, func); } else { - if (!(res = strdup(s))) { + if (!(res = grn_strdup_raw(s))) { MERR("strdup(%p)=%p (%s:%d) <%d>", s, res, file, line, alloc_count); } else { GRN_ADD_ALLOC_COUNT(1); @@ -2847,7 +2486,8 @@ grn_malloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const cha if (grn_fail_malloc_check(size, file, line, func)) { return grn_malloc_default(ctx, size, file, line, func); } else { - MERR("fail_malloc (%d) (%s:%d@%s) <%d>", size, file, line, func, alloc_count); + MERR("fail_malloc (%" GRN_FMT_SIZE ") (%s:%d@%s) <%d>", + size, file, line, func, alloc_count); return NULL; } } @@ -2858,7 +2498,8 @@ grn_calloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const cha if (grn_fail_malloc_check(size, file, line, func)) { return grn_calloc_default(ctx, size, file, line, func); } else { - MERR("fail_calloc (%d) (%s:%d@%s) <%d>", size, file, line, func, alloc_count); + MERR("fail_calloc (%" GRN_FMT_SIZE ") (%s:%d@%s) <%d>", + size, file, line, func, alloc_count); return NULL; } } diff --git a/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c index 05692eee13e..4c1a2a3b4f9 100644 --- a/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c +++ b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c @@ -33,6 +33,7 @@ # include "mrb/mrb_void.h" # include "mrb/mrb_bulk.h" # include "mrb/mrb_object.h" +# include "mrb/mrb_object_flags.h" # include "mrb/mrb_database.h" # include "mrb/mrb_table.h" # include "mrb/mrb_array.h" @@ -52,6 +53,7 @@ # include "mrb/mrb_command_input.h" # include "mrb/mrb_table_cursor.h" # include "mrb/mrb_table_cursor_flags.h" +# include "mrb/mrb_content_type.h" # include "mrb/mrb_writer.h" # include <mruby/array.h> @@ -116,6 +118,7 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx) grn_mrb_void_init(ctx); grn_mrb_bulk_init(ctx); grn_mrb_object_init(ctx); + grn_mrb_object_flags_init(ctx); grn_mrb_database_init(ctx); grn_mrb_table_init(ctx); grn_mrb_array_init(ctx); @@ -135,6 +138,7 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx) grn_mrb_command_input_init(ctx); grn_mrb_table_cursor_init(ctx); grn_mrb_table_cursor_flags_init(ctx); + grn_mrb_content_type_init(ctx); grn_mrb_writer_init(ctx); grn_mrb_load(ctx, "initialize/post.rb"); @@ -143,9 +147,11 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx) void grn_ctx_impl_mrb_init(grn_ctx *ctx) { - const char *grn_mruby_enabled; - grn_mruby_enabled = getenv("GRN_MRUBY_ENABLED"); - if (grn_mruby_enabled && strcmp(grn_mruby_enabled, "no") == 0) { + 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) { ctx->impl->mrb.state = NULL; ctx->impl->mrb.base_directory[0] = '\0'; ctx->impl->mrb.module = NULL; @@ -153,6 +159,7 @@ grn_ctx_impl_mrb_init(grn_ctx *ctx) ctx->impl->mrb.checked_procs = NULL; ctx->impl->mrb.registered_plugins = NULL; ctx->impl->mrb.builtin.time_class = NULL; + ctx->impl->mrb.groonga.operator_class = NULL; } else { mrb_state *mrb; diff --git a/storage/mroonga/vendor/groonga/lib/dat.cpp b/storage/mroonga/vendor/groonga/lib/dat.cpp index 4a3db12d67d..60588d55710 100644 --- a/storage/mroonga/vendor/groonga/lib/dat.cpp +++ b/storage/mroonga/vendor/groonga/lib/dat.cpp @@ -70,7 +70,7 @@ bool grn_dat_remove_file(grn_ctx *ctx, const char *path) { struct stat stat; - return !::stat(path, &stat) && !unlink(path); + return !::stat(path, &stat) && !grn_unlink(path); } grn_rc @@ -144,7 +144,7 @@ grn_dat_generate_trie_path(const char *base_path, char *trie_path, uint32_t file return; } const size_t len = std::strlen(base_path); - std::memcpy(trie_path, base_path, len); + grn_memcpy(trie_path, base_path, len); trie_path[len] = '.'; grn_itoh(file_id % (1U << (4 * FILE_ID_LENGTH)), trie_path + len + 1, FILE_ID_LENGTH); @@ -502,7 +502,7 @@ grn_dat_get_key(grn_ctx *ctx, grn_dat *dat, grn_id id, void *keybuf, int bufsize return 0; } if (keybuf && (bufsize >= (int)key.length())) { - std::memcpy(keybuf, key.ptr(), key.length()); + grn_memcpy(keybuf, key.ptr(), key.length()); } return (int)key.length(); } diff --git a/storage/mroonga/vendor/groonga/lib/dat/dat.hpp b/storage/mroonga/vendor/groonga/lib/dat/dat.hpp index d2b2264752b..c941bf25523 100644 --- a/storage/mroonga/vendor/groonga/lib/dat/dat.hpp +++ b/storage/mroonga/vendor/groonga/lib/dat/dat.hpp @@ -42,6 +42,12 @@ # endif // WIN32 #endif // GRN_DAT_API +#ifdef WIN32 +# define grn_memcpy(dest, src, n) ::memcpy_s((dest), (n), (src), (n)) +#else // WIN32 +# define grn_memcpy(dest, src, n) std::memcpy((dest), (src), (n)) +#endif // WIN32 + namespace grn { namespace dat { diff --git a/storage/mroonga/vendor/groonga/lib/dat/key-cursor.cpp b/storage/mroonga/vendor/groonga/lib/dat/key-cursor.cpp index 90ba25eca53..6bf864dba55 100644 --- a/storage/mroonga/vendor/groonga/lib/dat/key-cursor.cpp +++ b/storage/mroonga/vendor/groonga/lib/dat/key-cursor.cpp @@ -133,7 +133,7 @@ void KeyCursor::ascending_init(const String &min_str, const String &max_str) { if (max_str.ptr() != NULL) { if (max_str.length() != 0) { end_buf_ = new UInt8[max_str.length()]; - std::memcpy(end_buf_, max_str.ptr(), max_str.length()); + grn_memcpy(end_buf_, max_str.ptr(), max_str.length()); end_str_.assign(end_buf_, max_str.length()); } } @@ -206,7 +206,7 @@ void KeyCursor::descending_init(const String &min_str, const String &max_str) { if (min_str.ptr() != NULL) { if (min_str.length() != 0) { end_buf_ = new UInt8[min_str.length()]; - std::memcpy(end_buf_, min_str.ptr(), min_str.length()); + grn_memcpy(end_buf_, min_str.ptr(), min_str.length()); end_str_.assign(end_buf_, min_str.length()); } } diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c index b9cea065a6a..357df82e314 100644 --- a/storage/mroonga/vendor/groonga/lib/db.c +++ b/storage/mroonga/vendor/groonga/lib/db.c @@ -32,7 +32,6 @@ #include "grn_normalizer.h" #include "grn_util.h" #include <string.h> -#include <float.h> typedef struct { grn_id id; @@ -90,7 +89,7 @@ inline static void gen_pathname(const char *path, char *buffer, int fno) { size_t len = strlen(path); - memcpy(buffer, path, len); + grn_memcpy(buffer, path, len); if (fno >= 0) { buffer[len] = '.'; grn_itoh(fno, buffer + len + 1, 7); @@ -156,11 +155,15 @@ 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; - if (getenv("GRN_DB_KEY")) { - if (!strcmp(getenv("GRN_DB_KEY"), "pat")) { + 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")) { use_default_db_key = GRN_FALSE; use_pat_as_db_keys = GRN_TRUE; - } else if (!strcmp(getenv("GRN_DB_KEY"), "dat")) { + } else if (!strcmp(grn_db_key_env, "dat")) { use_default_db_key = GRN_FALSE; } } @@ -1919,9 +1922,11 @@ grn_table_truncate(grn_ctx *ctx, grn_obj *table) } grn_hash_close(ctx, cols); } - grn_table_get_info(ctx, table, NULL, NULL, &tokenizer, &normalizer, NULL); - GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_ID_NIL); - grn_obj_get_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters); + if (table->header.type != GRN_TABLE_NO_KEY) { + grn_table_get_info(ctx, table, NULL, NULL, &tokenizer, &normalizer, NULL); + GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_ID_NIL); + grn_obj_get_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters); + } switch (table->header.type) { case GRN_TABLE_PAT_KEY : for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; hooks; hooks = hooks->next) { @@ -1954,10 +1959,12 @@ grn_table_truncate(grn_ctx *ctx, grn_obj *table) rc = grn_array_truncate(ctx, (grn_array *)table); break; } - grn_obj_set_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER, tokenizer); - grn_obj_set_info(ctx, table, GRN_INFO_NORMALIZER, normalizer); - grn_obj_set_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters); - GRN_OBJ_FIN(ctx, &token_filters); + if (table->header.type != GRN_TABLE_NO_KEY) { + grn_obj_set_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER, tokenizer); + grn_obj_set_info(ctx, table, GRN_INFO_NORMALIZER, normalizer); + grn_obj_set_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters); + GRN_OBJ_FIN(ctx, &token_filters); + } if (rc == GRN_SUCCESS) { grn_obj_touch(ctx, table, NULL); } @@ -2060,7 +2067,7 @@ subrecs_push(byte *subrecs, int size, int n_subrecs, double score, void *body, i } v = subrecs + n * (GRN_RSET_SCORE_SIZE + size); *((double *)v) = score; - memcpy(v + GRN_RSET_SCORE_SIZE, body, size); + grn_memcpy(v + GRN_RSET_SCORE_SIZE, body, size); } inline static void @@ -2094,8 +2101,8 @@ subrecs_replace_min(byte *subrecs, int size, int n_subrecs, double score, void * } } v = subrecs + n * (GRN_RSET_SCORE_SIZE + size); - memcpy(v, &score, GRN_RSET_SCORE_SIZE); - memcpy(v + GRN_RSET_SCORE_SIZE, body, size); + grn_memcpy(v, &score, GRN_RSET_SCORE_SIZE); + grn_memcpy(v + GRN_RSET_SCORE_SIZE, body, size); } inline static void @@ -2784,16 +2791,8 @@ grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep, { grn_id *tid; - grn_obj *domain; grn_obj *next_res; - grn_search_optarg next_optarg; grn_rset_recinfo *recinfo; - if (optarg) { - next_optarg = *optarg; - next_optarg.mode = GRN_OP_EXACT; - } else { - memset(&next_optarg, 0, sizeof(grn_search_optarg)); - } { grn_obj *range = grn_ctx_at(ctx, DB_OBJ(index)->range); next_res = grn_table_create(ctx, NULL, 0, NULL, @@ -2808,29 +2807,33 @@ grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep, break; } } - domain = grn_ctx_at(ctx, index->header.domain); GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, { - next_optarg.weight_vector = NULL; - next_optarg.vector_size = recinfo->score; - if (domain->header.type == GRN_TABLE_NO_KEY) { - rc = grn_ii_sel(ctx, (grn_ii *)index, - (const char *)tid, sizeof(grn_id), - (grn_hash *)next_res, GRN_OP_OR, - &next_optarg); - } else { - char key[GRN_TABLE_MAX_KEY_SIZE]; - int key_len; - key_len = grn_table_get_key(ctx, domain, *tid, - key, GRN_TABLE_MAX_KEY_SIZE); - rc = grn_ii_sel(ctx, (grn_ii *)index, key, key_len, - (grn_hash *)next_res, GRN_OP_OR, - &next_optarg); + 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 (rc != GRN_SUCCESS) { break; } }); - grn_obj_unlink(ctx, domain); if (current_res != base_res) { grn_obj_unlink(ctx, current_res); } @@ -3789,7 +3792,7 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj * GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, { if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, &added)) { if (added) { - memcpy(value1, value2, value_size); + grn_memcpy(value1, value2, value_size); } else { grn_rset_recinfo *ri1 = value1; grn_rset_recinfo *ri2 = value2; @@ -3800,7 +3803,7 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj * } else { GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, { if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, NULL)) { - memcpy(value1, value2, value_size); + grn_memcpy(value1, value2, value_size); } }); } @@ -3832,7 +3835,7 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj * case GRN_OP_ADJUST : GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, { if (grn_table_get_v(ctx, table1, key, key_size, &value1)) { - memcpy(value1, value2, value_size); + grn_memcpy(value1, value2, value_size); } }); break; @@ -3881,7 +3884,7 @@ grn_obj_column_(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int nam if (len) { buf[len++] = GRN_DB_DELIMITER; if (len + name_size <= GRN_TABLE_MAX_KEY_SIZE) { - memcpy(buf + len, name, name_size); + grn_memcpy(buf + len, name, name_size); column = grn_ctx_get(ctx, buf, len + name_size); } else { ERR(GRN_INVALID_ARGUMENT, "name is too long"); @@ -4027,7 +4030,7 @@ grn_column_create(grn_ctx *ctx, grn_obj *table, goto exit; } fullname[len] = GRN_DB_DELIMITER; - memcpy(fullname + len + 1, name, name_size); + grn_memcpy(fullname + len + 1, name, name_size); name_size += len + 1; } else { ERR(GRN_FUNCTION_NOT_IMPLEMENTED, @@ -4155,7 +4158,7 @@ grn_column_open(grn_ctx *ctx, grn_obj *table, goto exit; } fullname[len] = GRN_DB_DELIMITER; - memcpy(fullname + len + 1, name, name_size); + grn_memcpy(fullname + len + 1, name, name_size); name_size += len + 1; } else { ERR(GRN_INVALID_ARGUMENT, "todo : not supported yet"); @@ -4219,7 +4222,7 @@ default_column_set_value(grn_ctx *ctx, grn_proc_ctx *pctx, grn_obj *in, grn_obj ERR(GRN_NO_MEMORY_AVAILABLE, "ra get failed"); return GRN_NO_MEMORY_AVAILABLE; } - memcpy(v, in->u.p.ptr, value_size); + grn_memcpy(v, in->u.p.ptr, value_size); grn_ra_unref(ctx, (grn_ra *)pctx->obj, arg->id); } break; @@ -5240,7 +5243,11 @@ grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj) if (GRN_BULK_VSIZE(p_key)) {\ id = addp ? grn_table_add_by_key(ctx, table, p_key, NULL)\ : grn_table_get_by_key(ctx, table, p_key);\ - if (id) { GRN_RECORD_SET(ctx, dest, id); }\ + if (id) {\ + GRN_RECORD_SET(ctx, dest, id);\ + } else {\ + rc = GRN_INVALID_ARGUMENT;\ + }\ } else {\ GRN_RECORD_SET(ctx, dest, GRN_ID_NIL);\ }\ @@ -5250,7 +5257,11 @@ grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj) GRN_UINT32_INIT(&record_id, 0);\ grn_obj_cast(ctx, src, &record_id, GRN_TRUE);\ id = GRN_UINT32_VALUE(&record_id);\ - if (id) { GRN_RECORD_SET(ctx, dest, id); }\ + if (id) {\ + GRN_RECORD_SET(ctx, dest, id);\ + } else {\ + rc = GRN_INVALID_ARGUMENT;\ + }\ }\ } else {\ rc = GRN_FUNCTION_NOT_IMPLEMENTED;\ @@ -6605,13 +6616,13 @@ grn_obj_set_value_column_fix_size(grn_ctx *ctx, grn_obj *obj, grn_id id, } else { void *b; if ((b = GRN_CALLOC(element_size))) { - memcpy(b, v, s); - memcpy(p, b, element_size); + grn_memcpy(b, v, s); + grn_memcpy(p, b, element_size); GRN_FREE(b); } } } else { - memcpy(p, v, s); + grn_memcpy(p, v, s); } rc = GRN_SUCCESS; break; @@ -7197,6 +7208,7 @@ build_index(grn_ctx *ctx, grn_obj *obj) break; default : use_grn_ii_build = GRN_FALSE; + break; } if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { use_grn_ii_build = GRN_FALSE; @@ -7214,10 +7226,14 @@ build_index(grn_ctx *ctx, grn_obj *obj) } if (use_grn_ii_build) { uint64_t sparsity = 10; - if (getenv("GRN_INDEX_SPARSITY")) { + 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(getenv("GRN_INDEX_SPARSITY"), NULL, 0); + v = strtoull(grn_index_sparsity_env, NULL, 0); if (!errno) { sparsity = v; } } grn_ii_build(ctx, ii, sparsity); @@ -7385,7 +7401,7 @@ grn_hook_unpack(grn_ctx *ctx, grn_db_obj *obj, const char *buf, uint32_t buf_siz new->proc = NULL; } if ((new->hld_size = hld_size)) { - memcpy(NEXT_ADDR(new), p, hld_size); + grn_memcpy(NEXT_ADDR(new), p, hld_size); p += hld_size; } *last = new; @@ -7482,8 +7498,10 @@ grn_obj_set_info_source_validate_report_error(grn_ctx *ctx, source_name, GRN_TABLE_MAX_KEY_SIZE); if (GRN_OBJ_TABLEP(source)) { source_name[source_name_size] = '\0'; - strncat(source_name, "._key", - GRN_TABLE_MAX_KEY_SIZE - source_name_size - 1); + grn_strncat(source_name, + GRN_TABLE_MAX_KEY_SIZE, + "._key", + GRN_TABLE_MAX_KEY_SIZE - source_name_size - 1); source_name_size = strlen(source_name); } table_domain_name_size = grn_obj_name(ctx, table_domain, @@ -7496,7 +7514,10 @@ grn_obj_set_info_source_validate_report_error(grn_ctx *ctx, GRN_TABLE_MAX_KEY_SIZE); grn_obj_unlink(ctx, source_type); } else { - strncpy(source_type_name, "(nil)", GRN_TABLE_MAX_KEY_SIZE); + grn_strncpy(source_type_name, + GRN_TABLE_MAX_KEY_SIZE, + "(nil)", + GRN_TABLE_MAX_KEY_SIZE); source_type_name_size = strlen(source_type_name); } ERR(GRN_INVALID_ARGUMENT, @@ -7619,7 +7640,7 @@ grn_obj_set_info_source_update(grn_ctx *ctx, grn_obj *obj, grn_obj *value) if (!v2) { return ctx->rc; } - memcpy(v2, v, s); + grn_memcpy(v2, v, s); if (DB_OBJ(obj)->source) { GRN_FREE(DB_OBJ(obj)->source); } DB_OBJ(obj)->source = v2; DB_OBJ(obj)->source_size = s; @@ -7741,7 +7762,7 @@ grn_obj_set_info(grn_ctx *ctx, grn_obj *obj, grn_info_type type, grn_obj *value) switch (DB_OBJ(obj)->header.type) { case GRN_TABLE_HASH_KEY : ((grn_hash *)obj)->tokenizer = value; - ((grn_hash *)obj)->header->tokenizer = grn_obj_id(ctx, value); + ((grn_hash *)obj)->header.common->tokenizer = grn_obj_id(ctx, value); rc = GRN_SUCCESS; break; case GRN_TABLE_PAT_KEY : @@ -7762,7 +7783,7 @@ grn_obj_set_info(grn_ctx *ctx, grn_obj *obj, grn_info_type type, grn_obj *value) switch (DB_OBJ(obj)->header.type) { case GRN_TABLE_HASH_KEY : ((grn_hash *)obj)->normalizer = value; - ((grn_hash *)obj)->header->normalizer = grn_obj_id(ctx, value); + ((grn_hash *)obj)->header.common->normalizer = grn_obj_id(ctx, value); rc = GRN_SUCCESS; break; case GRN_TABLE_PAT_KEY : @@ -7839,7 +7860,7 @@ grn_obj_add_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry, new->proc = (grn_proc *)proc; new->hld_size = hld_size; if (hld_size) { - memcpy(NEXT_ADDR(new), hld_value, hld_size); + grn_memcpy(NEXT_ADDR(new), hld_value, hld_size); } for (i = 0; i != offset && *last; i++) { last = &(*last)->next; } new->next = *last; @@ -8347,7 +8368,8 @@ _grn_obj_remove(grn_ctx *ctx, grn_obj *obj) const char *n = _grn_table_key(ctx, ctx->impl->db, DB_OBJ(obj)->id, &s); GRN_LOG(ctx, GRN_LOG_NOTICE, "DDL:obj_remove %.*s", s, n); } - if ((io_path = grn_obj_path(ctx, obj)) && *io_path != '\0') { + if (obj->header.type != GRN_PROC && + (io_path = grn_obj_path(ctx, obj)) && *io_path != '\0') { if (!(path = GRN_STRDUP(io_path))) { ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%s>", io_path); return; @@ -8495,7 +8517,7 @@ grn_table_rename(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int na if (!(rc = grn_obj_rename(ctx, table, name, name_size))) { grn_id *key; char fullname[GRN_TABLE_MAX_KEY_SIZE]; - memcpy(fullname, name, name_size); + grn_memcpy(fullname, name, name_size); fullname[name_size] = GRN_DB_DELIMITER; GRN_HASH_EACH(ctx, cols, id, &key, NULL, NULL, { grn_obj *col = grn_ctx_at(ctx, *key); @@ -8536,7 +8558,7 @@ grn_column_rename(grn_ctx *ctx, grn_obj *column, const char *name, unsigned int goto exit; } fullname[len] = GRN_DB_DELIMITER; - memcpy(fullname + len + 1, name, name_size); + grn_memcpy(fullname + len + 1, name, name_size); name_size += len + 1; rc = grn_obj_rename(ctx, column, fullname, name_size); } @@ -8678,7 +8700,7 @@ grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj) NULL,\ NULL);\ if (size > PATH_MAX) { ERR(GRN_FILENAME_TOO_LONG, "too long path"); }\ - memcpy(buffer, path, size);\ + grn_memcpy(buffer, path, size);\ buffer[size] = '\0';\ } else {\ gen_pathname(grn_obj_io(s->keys)->path, buffer, id); \ @@ -8700,7 +8722,7 @@ grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj) NULL);\ if (size) {\ if ((r->source = GRN_MALLOC(size))) {\ - memcpy(r->source, p, size);\ + grn_memcpy(r->source, p, size);\ r->source_size = size;\ }\ }\ @@ -9308,7 +9330,7 @@ grn_column_name(grn_ctx *ctx, grn_obj *obj, char *namebuf, int buf_size) } len = pe - p0; if (len && len <= buf_size) { - memcpy(namebuf, p0, len); + grn_memcpy(namebuf, p0, len); } } } @@ -9354,7 +9376,7 @@ grn_column_name(grn_ctx *ctx, grn_obj *obj, char *namebuf, int buf_size) if (name) { len = strlen(name); if (len <= buf_size) { - memcpy(namebuf, name, len); + grn_memcpy(namebuf, name, len); } } } @@ -10450,18 +10472,24 @@ grn_db_init_builtin_types(grn_ctx *ctx) #define MULTI_COLUMN_INDEXP(i) (DB_OBJ(i)->source_size > sizeof(grn_id)) static inline int -grn_column_index_column_equal(grn_ctx *ctx, grn_obj *obj, grn_operator op, - grn_obj **indexbuf, int buf_size, int *section) +grn_column_find_index_data_column_equal(grn_ctx *ctx, grn_obj *obj, + grn_operator op, + grn_index_datum *index_data, + unsigned int n_index_data, + grn_obj **index_buf, int buf_size, + int *section_buf) { int n = 0; - grn_obj **ip = indexbuf; + grn_obj **ip = index_buf; grn_hook *hooks; for (hooks = DB_OBJ(obj)->hooks[GRN_HOOK_SET]; hooks; hooks = hooks->next) { default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks); grn_obj *target = grn_ctx_at(ctx, data->target); + int section; if (target->header.type != GRN_COLUMN_INDEX) { continue; } - if (section) { *section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0; } + section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0; + if (section_buf) { *section_buf = section; } if (obj->header.type != GRN_COLUMN_FIX_SIZE) { grn_obj *tokenizer, *lexicon = grn_ctx_at(ctx, target->header.domain); if (!lexicon) { continue; } @@ -10471,18 +10499,47 @@ grn_column_index_column_equal(grn_ctx *ctx, grn_obj *obj, grn_operator op, if (n < buf_size) { *ip++ = target; } + if (n < n_index_data) { + index_data[n].index = target; + index_data[n].section = section; + } n++; } return n; } +static inline grn_bool +is_valid_regexp_index(grn_ctx *ctx, grn_obj *index_column) +{ + grn_obj *tokenizer; + grn_obj *lexicon; + + lexicon = grn_ctx_at(ctx, index_column->header.domain); + if (!lexicon) { + return GRN_FALSE; + } + + grn_table_get_info(ctx, lexicon, NULL, NULL, &tokenizer, NULL, NULL); + grn_obj_unlink(ctx, lexicon); + if (!tokenizer) { + return GRN_FALSE; + } + + /* TODO: Restrict to TokenRegexp? */ + return GRN_TRUE; +} + static inline int -grn_column_index_column_match(grn_ctx *ctx, grn_obj *obj, grn_operator op, - grn_obj **indexbuf, int buf_size, int *section) +grn_column_find_index_data_column_match(grn_ctx *ctx, grn_obj *obj, + grn_operator op, + grn_index_datum *index_data, + unsigned int n_index_data, + grn_obj **index_buf, int buf_size, + int *section_buf) { int n = 0; - grn_obj **ip = indexbuf; + grn_obj **ip = index_buf; grn_hook_entry hook_entry; grn_hook *hooks; @@ -10501,11 +10558,20 @@ grn_column_index_column_match(grn_ctx *ctx, grn_obj *obj, grn_operator op, for (hooks = DB_OBJ(obj)->hooks[hook_entry]; hooks; hooks = hooks->next) { default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks); grn_obj *target = grn_ctx_at(ctx, data->target); + int section; if (target->header.type != GRN_COLUMN_INDEX) { continue; } - if (section) { *section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0; } + if (op == GRN_OP_REGEXP && !is_valid_regexp_index(ctx, target)) { + continue; + } + section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0; + if (section_buf) { *section_buf = section; } if (n < buf_size) { *ip++ = target; } + if (n < n_index_data) { + index_data[n].index = target; + index_data[n].section = section; + } n++; } @@ -10513,11 +10579,15 @@ grn_column_index_column_match(grn_ctx *ctx, grn_obj *obj, grn_operator op, } static inline int -grn_column_index_column_range(grn_ctx *ctx, grn_obj *obj, grn_operator op, - grn_obj **indexbuf, int buf_size, int *section) +grn_column_find_index_data_column_range(grn_ctx *ctx, grn_obj *obj, + grn_operator op, + grn_index_datum *index_data, + unsigned int n_index_data, + grn_obj **index_buf, int buf_size, + int *section_buf) { int n = 0; - grn_obj **ip = indexbuf; + grn_obj **ip = index_buf; grn_hook_entry hook_entry; grn_hook *hooks; @@ -10536,8 +10606,10 @@ grn_column_index_column_range(grn_ctx *ctx, grn_obj *obj, grn_operator op, for (hooks = DB_OBJ(obj)->hooks[hook_entry]; hooks; hooks = hooks->next) { default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks); grn_obj *target = grn_ctx_at(ctx, data->target); + int section; if (target->header.type != GRN_COLUMN_INDEX) { continue; } - if (section) { *section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0; } + section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0; + if (section_buf) { *section_buf = section; } { grn_obj *tokenizer, *lexicon = grn_ctx_at(ctx, target->header.domain); if (!lexicon) { continue; } @@ -10549,6 +10621,10 @@ grn_column_index_column_range(grn_ctx *ctx, grn_obj *obj, grn_operator op, if (n < buf_size) { *ip++ = target; } + if (n < n_index_data) { + index_data[n].index = target; + index_data[n].section = section; + } n++; } @@ -10599,6 +10675,9 @@ is_valid_index(grn_ctx *ctx, grn_obj *index_column, grn_operator op) case GRN_OP_CALL : return is_valid_range_index(ctx, index_column); break; + case GRN_OP_REGEXP : + return is_valid_regexp_index(ctx, index_column); + break; default : return GRN_FALSE; break; @@ -10629,12 +10708,16 @@ find_section(grn_ctx *ctx, grn_obj *index_column, grn_obj *indexed_column) } static int -grn_column_index_accessor_index_column(grn_ctx *ctx, grn_accessor *a, - grn_operator op, - grn_obj **indexbuf, int buf_size, - int *section) +grn_column_find_index_data_accessor_index_column(grn_ctx *ctx, grn_accessor *a, + grn_operator op, + grn_index_datum *index_data, + unsigned int n_index_data, + grn_obj **index_buf, + int buf_size, + int *section_buf) { grn_obj *index_column = a->obj; + int section = 0; if (!is_valid_index(ctx, index_column, op)) { return 0; @@ -10651,23 +10734,32 @@ grn_column_index_accessor_index_column(grn_ctx *ctx, grn_accessor *a, if (is_invalid_section) { return 0; } - if (section) { - *section = specified_section; + section = specified_section; + if (section_buf) { + *section_buf = section; } } if (buf_size > 0) { - *indexbuf = index_column; + *index_buf = index_column; + } + if (n_index_data > 0) { + index_data[0].index = index_column; + index_data[0].section = section; } return 1; } static inline int -grn_column_index_accessor(grn_ctx *ctx, grn_obj *obj, grn_operator op, - grn_obj **indexbuf, int buf_size, int *section) +grn_column_find_index_data_accessor_match(grn_ctx *ctx, grn_obj *obj, + grn_operator op, + grn_index_datum *index_data, + unsigned n_index_data, + grn_obj **index_buf, int buf_size, + int *section_buf) { int n = 0; - grn_obj **ip = indexbuf; + grn_obj **ip = index_buf; grn_accessor *a = (grn_accessor *)obj; while (a) { @@ -10677,8 +10769,12 @@ grn_column_index_accessor(grn_ctx *ctx, grn_obj *obj, grn_operator op, if (a->action == GRN_ACCESSOR_GET_COLUMN_VALUE && GRN_OBJ_INDEX_COLUMNP(a->obj)) { - return grn_column_index_accessor_index_column(ctx, a, op, indexbuf, - buf_size, section); + return grn_column_find_index_data_accessor_index_column(ctx, a, op, + index_data, + n_index_data, + index_buf, + buf_size, + section_buf); } switch (a->action) { @@ -10704,16 +10800,23 @@ grn_column_index_accessor(grn_ctx *ctx, grn_obj *obj, grn_operator op, found = GRN_TRUE; if (!a->next) { + int section; + if (!is_valid_index(ctx, target, op)) { continue; } - if (section) { - *section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0; + section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0; + if (section_buf) { + *section_buf = section; } if (n < buf_size) { *ip++ = target; } + if (n < n_index_data) { + index_data[n].index = target; + index_data[n].section = section; + } n++; } } @@ -10727,17 +10830,102 @@ grn_column_index_accessor(grn_ctx *ctx, grn_obj *obj, grn_operator op, return n; } +static inline int +grn_column_find_index_data_accessor(grn_ctx *ctx, grn_obj *obj, + grn_operator op, + grn_index_datum *index_data, + unsigned n_index_data, + grn_obj **index_buf, int buf_size, + int *section_buf) +{ + int n = 0; + + if (section_buf) { + *section_buf = 0; + } + switch (op) { + case GRN_OP_EQUAL : + case GRN_OP_TERM_EXTRACT : + if (buf_size > 0) { + index_buf[n] = obj; + } + if (n_index_data > 0) { + index_data[n].index = obj; + index_data[n].section = 0; + } + n++; + break; + case GRN_OP_PREFIX : + { + grn_accessor *a = (grn_accessor *)obj; + if (a->action == GRN_ACCESSOR_GET_KEY) { + if (a->obj->header.type == GRN_TABLE_PAT_KEY) { + if (buf_size > 0) { + index_buf[n] = obj; + } + if (n_index_data > 0) { + index_data[n].index = obj; + index_data[n].section = 0; + } + n++; + } + /* FIXME: GRN_TABLE_DAT_KEY should be supported */ + } + } + break; + case GRN_OP_SUFFIX : + { + grn_accessor *a = (grn_accessor *)obj; + if (a->action == GRN_ACCESSOR_GET_KEY) { + if (a->obj->header.type == GRN_TABLE_PAT_KEY && + a->obj->header.flags & GRN_OBJ_KEY_WITH_SIS) { + if (buf_size > 0) { + index_buf[n] = obj; + } + if (n_index_data > 0) { + index_data[n].index = obj; + index_data[n].section = 0; + } + n++; + } + } + } + break; + case GRN_OP_MATCH : + case GRN_OP_NEAR : + case GRN_OP_NEAR2 : + case GRN_OP_SIMILAR : + case GRN_OP_LESS : + case GRN_OP_GREATER : + case GRN_OP_LESS_EQUAL : + case GRN_OP_GREATER_EQUAL : + case GRN_OP_CALL : + case GRN_OP_REGEXP : + n = grn_column_find_index_data_accessor_match(ctx, obj, op, + index_data, n_index_data, + index_buf, buf_size, + section_buf); + break; + default : + break; + } + + return n; +} + int grn_column_index(grn_ctx *ctx, grn_obj *obj, grn_operator op, - grn_obj **indexbuf, int buf_size, int *section) + grn_obj **index_buf, int buf_size, int *section_buf) { int n = 0; GRN_API_ENTER; if (GRN_DB_OBJP(obj)) { switch (op) { case GRN_OP_EQUAL : - n = grn_column_index_column_equal(ctx, obj, op, - indexbuf, buf_size, section); + n = grn_column_find_index_data_column_equal(ctx, obj, op, + NULL, 0, + index_buf, buf_size, + section_buf); break; case GRN_OP_PREFIX : case GRN_OP_SUFFIX : @@ -10745,68 +10933,75 @@ grn_column_index(grn_ctx *ctx, grn_obj *obj, grn_operator op, case GRN_OP_NEAR : case GRN_OP_NEAR2 : case GRN_OP_SIMILAR : - n = grn_column_index_column_match(ctx, obj, op, - indexbuf, buf_size, section); + case GRN_OP_REGEXP : + n = grn_column_find_index_data_column_match(ctx, obj, op, + NULL, 0, + index_buf, buf_size, + section_buf); break; case GRN_OP_LESS : case GRN_OP_GREATER : case GRN_OP_LESS_EQUAL : case GRN_OP_GREATER_EQUAL : case GRN_OP_CALL : - n = grn_column_index_column_range(ctx, obj, op, - indexbuf, buf_size, section); + n = grn_column_find_index_data_column_range(ctx, obj, op, + NULL, 0, + index_buf, buf_size, + section_buf); break; default : break; } } else if (GRN_ACCESSORP(obj)) { - if (section) { - *section = 0; - } + n = grn_column_find_index_data_accessor(ctx, obj, op, + NULL, 0, + index_buf, buf_size, + section_buf); + } + GRN_API_RETURN(n); +} + +unsigned int +grn_column_find_index_data(grn_ctx *ctx, grn_obj *obj, grn_operator op, + grn_index_datum *index_data, + unsigned int n_index_data) +{ + unsigned int n = 0; + GRN_API_ENTER; + if (GRN_DB_OBJP(obj)) { switch (op) { case GRN_OP_EQUAL : - case GRN_OP_TERM_EXTRACT : - if (buf_size) { indexbuf[n] = obj; } - n++; + n = grn_column_find_index_data_column_equal(ctx, obj, op, + index_data, n_index_data, + NULL, 0, NULL); break; case GRN_OP_PREFIX : - { - grn_accessor *a = (grn_accessor *)obj; - if (a->action == GRN_ACCESSOR_GET_KEY) { - if (a->obj->header.type == GRN_TABLE_PAT_KEY) { - if (buf_size) { indexbuf[n] = obj; } - n++; - } - /* FIXME: GRN_TABLE_DAT_KEY should be supported */ - } - } - break; case GRN_OP_SUFFIX : - { - grn_accessor *a = (grn_accessor *)obj; - if (a->action == GRN_ACCESSOR_GET_KEY) { - if (a->obj->header.type == GRN_TABLE_PAT_KEY && - a->obj->header.flags & GRN_OBJ_KEY_WITH_SIS) { - if (buf_size) { indexbuf[n] = obj; } - n++; - } - } - } - break; case GRN_OP_MATCH : case GRN_OP_NEAR : case GRN_OP_NEAR2 : case GRN_OP_SIMILAR : + case GRN_OP_REGEXP : + n = grn_column_find_index_data_column_match(ctx, obj, op, + index_data, n_index_data, + NULL, 0, NULL); + break; case GRN_OP_LESS : case GRN_OP_GREATER : case GRN_OP_LESS_EQUAL : case GRN_OP_GREATER_EQUAL : case GRN_OP_CALL : - n = grn_column_index_accessor(ctx, obj, op, indexbuf, buf_size, section); + n = grn_column_find_index_data_column_range(ctx, obj, op, + index_data, n_index_data, + NULL, 0, NULL); break; default : break; } + } else if (GRN_ACCESSORP(obj)) { + n = grn_column_find_index_data_accessor(ctx, obj, op, + index_data, n_index_data, + NULL, 0, NULL); } GRN_API_RETURN(n); } @@ -11659,7 +11854,6 @@ json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned int str_le case GRN_LOADER_BEGIN : if ((len = grn_isspace(str, ctx->encoding))) { str += len; - c = *str; continue; } switch (c) { @@ -11679,7 +11873,6 @@ json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned int str_le case GRN_LOADER_TOKEN : if ((len = grn_isspace(str, ctx->encoding))) { str += len; - c = *str; continue; } switch (c) { @@ -12073,6 +12266,7 @@ grn_load_(grn_ctx *ctx, grn_content_type input_type, case GRN_CONTENT_TSV : case GRN_CONTENT_XML : case GRN_CONTENT_MSGPACK : + case GRN_CONTENT_GROONGA_COMMAND_LIST : ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "unsupported input_type"); // todo break; diff --git a/storage/mroonga/vendor/groonga/lib/expr.c b/storage/mroonga/vendor/groonga/lib/expr.c index ef477eb77ee..f13502a0f14 100644 --- a/storage/mroonga/vendor/groonga/lib/expr.c +++ b/storage/mroonga/vendor/groonga/lib/expr.c @@ -19,12 +19,10 @@ #include "grn_db.h" #include "grn_ctx_impl.h" #include <string.h> -#include <float.h> #include "grn_ii.h" #include "grn_geo.h" #include "grn_expr.h" #include "grn_util.h" -#include "grn_normalizer.h" #include "grn_mrb.h" #include "mrb/mrb_expr.h" @@ -357,7 +355,7 @@ grn_expr_open(grn_ctx *ctx, grn_obj_spec *spec, const uint8_t *p, const uint8_t { grn_expr *expr = NULL; if ((expr = GRN_MALLOCN(grn_expr, 1))) { - int size = 256; + int size = GRN_STACK_SIZE; expr->consts = NULL; expr->nconsts = 0; GRN_TEXT_INIT(&expr->name_buf, 0); @@ -722,6 +720,21 @@ grn_expr_get_var_by_offset(grn_ctx *ctx, grn_obj *expr, unsigned int offset) DFI_PUT(e, type, domain, code); \ } while (0) +static void +grn_expr_append_obj_resolve_const(grn_ctx *ctx, + grn_obj *obj, + grn_id to_domain) +{ + grn_obj dest; + + GRN_OBJ_INIT(&dest, GRN_BULK, 0, to_domain); + if (!grn_obj_cast(ctx, obj, &dest, GRN_FALSE)) { + grn_obj_reinit(ctx, obj, to_domain, 0); + grn_bulk_write(ctx, obj, GRN_BULK_HEAD(&dest), GRN_BULK_VSIZE(&dest)); + } + GRN_OBJ_FIN(ctx, &dest); +} + grn_obj * grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op, int nargs) { @@ -854,26 +867,14 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op, if (CONSTP(y)) { /* todo */ } else { - grn_obj dest; if (xd != yd) { - GRN_OBJ_INIT(&dest, GRN_BULK, 0, yd); - if (!grn_obj_cast(ctx, x, &dest, GRN_FALSE)) { - grn_obj_reinit(ctx, x, yd, 0); - grn_bulk_write(ctx, x, GRN_BULK_HEAD(&dest), GRN_BULK_VSIZE(&dest)); - } - GRN_OBJ_FIN(ctx, &dest); + grn_expr_append_obj_resolve_const(ctx, x, yd); } } } else { if (CONSTP(y)) { - grn_obj dest; if (xd != yd) { - GRN_OBJ_INIT(&dest, GRN_BULK, 0, xd); - if (!grn_obj_cast(ctx, y, &dest, GRN_FALSE)) { - grn_obj_reinit(ctx, y, xd, 0); - grn_bulk_write(ctx, y, GRN_BULK_HEAD(&dest), GRN_BULK_VSIZE(&dest)); - } - GRN_OBJ_FIN(ctx, &dest); + grn_expr_append_obj_resolve_const(ctx, y, xd); } } } @@ -908,6 +909,7 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op, case GRN_OP_GET_REF : case GRN_OP_ADJUST : case GRN_OP_TERM_EXTRACT : + case GRN_OP_REGEXP : PUSH_CODE(e, op, obj, nargs, code); if (nargs) { int i = nargs - 1; @@ -2223,274 +2225,6 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller) } \ } while (0) -static grn_bool -string_is_contained(grn_ctx *ctx, - const char *text, unsigned int text_len, - const char *sub_text, unsigned int sub_text_len) -{ - /* TODO: Use more fast algorithm such as Boyer-Moore algorithm that - * is used in snip.c. */ - const char *text_end = text + text_len; - unsigned int sub_text_current = 0; - - for (; text < text_end; text++) { - if (text[0] == sub_text[sub_text_current]) { - sub_text_current++; - if (sub_text_current == sub_text_len) { - return GRN_TRUE; - } - } else { - sub_text_current = 0; - } - } - - return GRN_FALSE; -} - -static grn_bool -pseudo_query_scan_raw_text_raw_text(grn_ctx *ctx, - const char *x, unsigned int x_len, - const char *y, unsigned int y_len) -{ - grn_obj *normalizer; - grn_obj *norm_x; - grn_obj *norm_y; - const char *norm_x_raw; - const char *norm_y_raw; - unsigned int norm_x_raw_length_in_bytes; - unsigned int norm_y_raw_length_in_bytes; - grn_bool matched = GRN_FALSE; - - if (x_len == 0 || y_len == 0) { - return GRN_FALSE; - } - - normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1); - norm_x = grn_string_open(ctx, x, x_len, normalizer, 0); - norm_y = grn_string_open(ctx, y, y_len, normalizer, 0); - grn_string_get_normalized(ctx, norm_x, - &norm_x_raw, &norm_x_raw_length_in_bytes, - NULL); - grn_string_get_normalized(ctx, norm_y, - &norm_y_raw, &norm_y_raw_length_in_bytes, - NULL); - matched = string_is_contained(ctx, - norm_x_raw, norm_x_raw_length_in_bytes, - norm_y_raw, norm_y_raw_length_in_bytes); - - grn_obj_close(ctx, norm_x); - grn_obj_close(ctx, norm_y); - grn_obj_unlink(ctx, normalizer); - - return matched; -} - -static grn_bool -pseudo_query_scan_record_text(grn_ctx *ctx, grn_obj *record, grn_obj *table, - grn_obj *y) -{ - grn_obj *normalizer; - char x_key[GRN_TABLE_MAX_KEY_SIZE]; - int x_key_len; - grn_bool matched = GRN_FALSE; - - if (table->header.domain != GRN_DB_SHORT_TEXT) { - return GRN_FALSE; - } - - x_key_len = grn_table_get_key(ctx, table, GRN_RECORD_VALUE(record), - x_key, GRN_TABLE_MAX_KEY_SIZE); - grn_table_get_info(ctx, table, NULL, NULL, NULL, &normalizer, NULL); - if (normalizer) { - grn_obj *norm_y; - const char *norm_y_raw; - unsigned int norm_y_raw_length_in_bytes; - norm_y = grn_string_open(ctx, GRN_TEXT_VALUE(y), GRN_TEXT_LEN(y), - normalizer, 0); - grn_string_get_normalized(ctx, norm_y, - &norm_y_raw, &norm_y_raw_length_in_bytes, - NULL); - matched = string_is_contained(ctx, - x_key, x_key_len, - norm_y_raw, norm_y_raw_length_in_bytes); - grn_obj_close(ctx, norm_y); - } else { - matched = pseudo_query_scan_raw_text_raw_text(ctx, - x_key, - x_key_len, - GRN_TEXT_VALUE(y), - GRN_TEXT_LEN(y)); - } - - return matched; -} - -static grn_bool -pseudo_query_scan_text_text(grn_ctx *ctx, grn_obj *x, grn_obj *y) -{ - return pseudo_query_scan_raw_text_raw_text(ctx, - GRN_TEXT_VALUE(x), - GRN_TEXT_LEN(x), - GRN_TEXT_VALUE(y), - GRN_TEXT_LEN(y)); -} - -static grn_bool -pseudo_query_scan(grn_ctx *ctx, grn_obj *x, grn_obj *y) -{ - switch (x->header.domain) { - case GRN_DB_SHORT_TEXT : - case GRN_DB_TEXT : - case GRN_DB_LONG_TEXT : - switch (y->header.domain) { - case GRN_DB_SHORT_TEXT : - case GRN_DB_TEXT : - case GRN_DB_LONG_TEXT : - return pseudo_query_scan_text_text(ctx, x, y); - default : - break; - } - return GRN_FALSE; - default: - { - grn_obj *domain; - domain = grn_ctx_at(ctx, x->header.domain); - if (GRN_OBJ_TABLEP(domain)) { - switch (y->header.domain) { - case GRN_DB_SHORT_TEXT : - case GRN_DB_TEXT : - case GRN_DB_LONG_TEXT : - return pseudo_query_scan_record_text(ctx, x, domain, y); - default : - break; - } - } - } - return GRN_FALSE; - } -} - -static grn_bool -pseudo_prefix_search_match(grn_ctx *ctx, - const char *x, unsigned int x_len, - const char *y, unsigned int y_len) -{ - return (x_len >= y_len && strncmp(x, y, y_len) == 0); -} - -static grn_bool -pseudo_prefix_search_raw_text_raw_text(grn_ctx *ctx, - const char *x, unsigned int x_len, - const char *y, unsigned int y_len) -{ - grn_obj *normalizer; - grn_obj *norm_x; - grn_obj *norm_y; - const char *norm_x_raw; - const char *norm_y_raw; - unsigned int norm_x_raw_len; - unsigned int norm_y_raw_len; - grn_bool matched = GRN_FALSE; - - normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1); - norm_x = grn_string_open(ctx, x, x_len, normalizer, 0); - norm_y = grn_string_open(ctx, y, y_len, normalizer, 0); - grn_string_get_normalized(ctx, norm_x, &norm_x_raw, &norm_x_raw_len, NULL); - grn_string_get_normalized(ctx, norm_y, &norm_y_raw, &norm_y_raw_len, NULL); - matched = pseudo_prefix_search_match(ctx, - norm_x_raw, norm_x_raw_len, - norm_y_raw, norm_y_raw_len); - - grn_obj_close(ctx, norm_x); - grn_obj_close(ctx, norm_y); - grn_obj_unlink(ctx, normalizer); - - return matched; -} - -static grn_bool -pseudo_prefix_search_record_text(grn_ctx *ctx, grn_obj *record, grn_obj *table, - grn_obj *y) -{ - grn_obj *normalizer; - char x_key[GRN_TABLE_MAX_KEY_SIZE]; - int x_key_len; - grn_bool matched = GRN_FALSE; - - if (table->header.domain != GRN_DB_SHORT_TEXT) { - return GRN_FALSE; - } - - x_key_len = grn_table_get_key(ctx, table, GRN_RECORD_VALUE(record), - x_key, GRN_TABLE_MAX_KEY_SIZE); - grn_table_get_info(ctx, table, NULL, NULL, NULL, &normalizer, NULL); - if (normalizer) { - grn_obj *norm_y; - const char *norm_y_raw; - unsigned int norm_y_raw_len; - norm_y = grn_string_open(ctx, GRN_TEXT_VALUE(y), GRN_TEXT_LEN(y), - normalizer, 0); - grn_string_get_normalized(ctx, norm_y, &norm_y_raw, &norm_y_raw_len, NULL); - matched = pseudo_prefix_search_match(ctx, - x_key, x_key_len, - norm_y_raw, norm_y_raw_len); - grn_obj_close(ctx, norm_y); - } else { - matched = pseudo_prefix_search_raw_text_raw_text(ctx, - x_key, - x_key_len, - GRN_TEXT_VALUE(y), - GRN_TEXT_LEN(y)); - } - - return matched; -} - -static grn_bool -pseudo_prefix_search_text_text(grn_ctx *ctx, grn_obj *x, grn_obj *y) -{ - return pseudo_prefix_search_raw_text_raw_text(ctx, - GRN_TEXT_VALUE(x), - GRN_TEXT_LEN(x), - GRN_TEXT_VALUE(y), - GRN_TEXT_LEN(y)); -} - -static grn_bool -pseudo_prefix_search(grn_ctx *ctx, grn_obj *x, grn_obj *y) -{ - switch (x->header.domain) { - case GRN_DB_SHORT_TEXT : - case GRN_DB_TEXT : - case GRN_DB_LONG_TEXT : - switch (y->header.domain) { - case GRN_DB_SHORT_TEXT : - case GRN_DB_TEXT : - case GRN_DB_LONG_TEXT : - return pseudo_prefix_search_text_text(ctx, x, y); - default : - break; - } - return GRN_FALSE; - default: - { - grn_obj *domain; - domain = grn_ctx_at(ctx, x->header.domain); - if (GRN_OBJ_TABLEP(domain)) { - switch (y->header.domain) { - case GRN_DB_SHORT_TEXT : - case GRN_DB_TEXT : - case GRN_DB_LONG_TEXT : - return pseudo_prefix_search_record_text(ctx, x, domain, y); - default : - break; - } - } - } - return GRN_FALSE; - } -} - inline static void grn_expr_exec_get_member(grn_ctx *ctx, grn_obj *expr, @@ -2534,12 +2268,45 @@ grn_expr_exec_get_member(grn_ctx *ctx, GRN_OBJ_FIN(ctx, &values); } +static inline grn_bool +grn_expr_exec_is_simple_expr(grn_ctx *ctx, grn_obj *expr) +{ + grn_expr *e = (grn_expr *)expr; + + if (expr->header.type != GRN_EXPR) { + return GRN_FALSE; + } + + if (e->codes_curr != 1) { + return GRN_FALSE; + } + + switch (e->codes[0].op) { + case GRN_OP_PUSH : + return GRN_TRUE; + default : + return GRN_FALSE; + } +} + +static inline grn_obj * +grn_expr_exec_simple(grn_ctx *ctx, grn_obj *expr) +{ + grn_expr *e = (grn_expr *)expr; + + return e->codes[0].value; +} + grn_obj * grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) { grn_obj *val = NULL; uint32_t stack_curr = ctx->impl->stack_curr; GRN_API_ENTER; + if (grn_expr_exec_is_simple_expr(ctx, expr)) { + val = grn_expr_exec_simple(ctx, expr); + GRN_API_RETURN(val); + } if (expr->header.type == GRN_PROC) { grn_proc *proc = (grn_proc *)expr; if (proc->type == GRN_PROC_COMMAND) { @@ -3170,7 +2937,7 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) POP1(y); POP1(x); WITH_SPSAVE({ - matched = pseudo_query_scan(ctx, x, y); + matched = grn_operator_exec_match(ctx, x, y); }); ALLOC1(res); grn_obj_reinit(ctx, res, GRN_DB_INT32, 0); @@ -3207,7 +2974,7 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) POP1(y); POP1(x); WITH_SPSAVE({ - matched = pseudo_prefix_search(ctx, x, y); + matched = grn_operator_exec_prefix(ctx, x, y); }); ALLOC1(res); grn_obj_reinit(ctx, res, GRN_DB_INT32, 0); @@ -3697,6 +3464,21 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) code++; } break; + case GRN_OP_REGEXP : + { + grn_obj *target, *pattern; + grn_bool matched; + POP1(pattern); + POP1(target); + WITH_SPSAVE({ + matched = grn_operator_exec_regexp(ctx, target, pattern); + }); + ALLOC1(res); + grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0); + GRN_BOOL_SET(ctx, res, matched); + } + code++; + break; default : ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "not implemented operator assigned"); goto exit; @@ -3753,12 +3535,17 @@ struct _grn_scan_info { grn_obj *args[GRN_SCAN_INFO_MAX_N_ARGS]; int max_interval; int similarity_threshold; - grn_obj *scorer; + grn_obj scorers; + grn_obj scorer_args_exprs; + grn_obj scorer_args_expr_offsets; }; #define SI_FREE(si) do {\ GRN_OBJ_FIN(ctx, &(si)->wv);\ GRN_OBJ_FIN(ctx, &(si)->index);\ + GRN_OBJ_FIN(ctx, &(si)->scorers);\ + GRN_OBJ_FIN(ctx, &(si)->scorer_args_exprs);\ + GRN_OBJ_FIN(ctx, &(si)->scorer_args_expr_offsets);\ GRN_FREE(si);\ } while (0) @@ -3777,7 +3564,9 @@ struct _grn_scan_info { (si)->max_interval = DEFAULT_MAX_INTERVAL;\ (si)->similarity_threshold = DEFAULT_SIMILARITY_THRESHOLD;\ (si)->start = (st);\ - (si)->scorer = NULL;\ + GRN_PTR_INIT(&(si)->scorers, GRN_OBJ_VECTOR, GRN_ID_NIL);\ + GRN_PTR_INIT(&(si)->scorer_args_exprs, GRN_OBJ_VECTOR, GRN_ID_NIL);\ + GRN_UINT32_INIT(&(si)->scorer_args_expr_offsets, GRN_OBJ_VECTOR);\ } while (0) static scan_info ** @@ -3821,9 +3610,9 @@ put_logical_op(grn_ctx *ctx, scan_info **sis, int *ip, grn_operator op, int star } else { s_->flags &= ~SCAN_PUSH; s_->logical_op = op; - memcpy(&sis[i], &sis[j], sizeof(scan_info *) * (r - j)); - memmove(&sis[j], &sis[r], sizeof(scan_info *) * (i - r)); - memcpy(&sis[i + j - r], &sis[i], sizeof(scan_info *) * (r - j)); + grn_memcpy(&sis[i], &sis[j], sizeof(scan_info *) * (r - j)); + grn_memmove(&sis[j], &sis[r], sizeof(scan_info *) * (i - r)); + grn_memcpy(&sis[i + j - r], &sis[i], sizeof(scan_info *) * (r - j)); } break; } @@ -4003,11 +3792,18 @@ grn_expr_inspect_internal(grn_ctx *ctx, grn_obj *buf, grn_obj *expr) static void -scan_info_put_index(grn_ctx *ctx, scan_info *si, grn_obj *index, uint32_t sid, int32_t weight) +scan_info_put_index(grn_ctx *ctx, scan_info *si, + grn_obj *index, uint32_t sid, int32_t weight, + grn_obj *scorer, + grn_obj *scorer_args_expr, + uint32_t scorer_args_expr_offset) { GRN_PTR_PUT(ctx, &si->index, index); GRN_UINT32_PUT(ctx, &si->wv, sid); GRN_INT32_PUT(ctx, &si->wv, weight); + GRN_PTR_PUT(ctx, &si->scorers, scorer); + GRN_PTR_PUT(ctx, &si->scorer_args_exprs, scorer_args_expr); + GRN_UINT32_PUT(ctx, &si->scorer_args_expr_offsets, scorer_args_expr_offset); { int i, ni = (GRN_BULK_VSIZE(&si->index) / sizeof(grn_obj *)) - 1; grn_obj **pi = &GRN_PTR_VALUE_AT(&si->index, ni); @@ -4015,10 +3811,10 @@ scan_info_put_index(grn_ctx *ctx, scan_info *si, grn_obj *index, uint32_t sid, i if (index == pi[-1]) { if (i) { int32_t *pw = &GRN_INT32_VALUE_AT(&si->wv, (ni - i) * 2); - memmove(pw + 2, pw, sizeof(int32_t) * 2 * i); + grn_memmove(pw + 2, pw, sizeof(int32_t) * 2 * i); pw[0] = (int32_t) sid; pw[1] = weight; - memmove(pi + 1, pi, sizeof(grn_obj *) * i); + grn_memmove(pi + 1, pi, sizeof(grn_obj *) * i); pi[0] = index; } return; @@ -4028,10 +3824,13 @@ scan_info_put_index(grn_ctx *ctx, scan_info *si, grn_obj *index, uint32_t sid, i } static int32_t -get_weight(grn_ctx *ctx, grn_expr_code *ec) +get_weight(grn_ctx *ctx, grn_expr_code *ec, uint32_t *offset) { if (ec->modify == 2 && ec[2].op == GRN_OP_STAR && ec[1].value && ec[1].value->header.type == GRN_BULK) { + if (offset) { + *offset = 2; + } if (ec[1].value->header.domain == GRN_DB_INT32 || ec[1].value->header.domain == GRN_DB_UINT32) { return GRN_INT32_VALUE(ec[1].value); @@ -4046,6 +3845,9 @@ get_weight(grn_ctx *ctx, grn_expr_code *ec) return weight; } } else { + if (offset) { + *offset = 0; + } return 1; } } @@ -4067,7 +3869,9 @@ grn_scan_info_open(grn_ctx *ctx, int start) si->max_interval = DEFAULT_MAX_INTERVAL; si->similarity_threshold = DEFAULT_SIMILARITY_THRESHOLD; si->start = start; - si->scorer = NULL; + GRN_PTR_INIT(&si->scorers, GRN_OBJ_VECTOR, GRN_ID_NIL); + GRN_PTR_INIT(&si->scorer_args_exprs, GRN_OBJ_VECTOR, GRN_ID_NIL); + GRN_UINT32_INIT(&si->scorer_args_expr_offsets, GRN_OBJ_VECTOR); return si; } @@ -4079,9 +3883,16 @@ grn_scan_info_close(grn_ctx *ctx, scan_info *si) } void -grn_scan_info_put_index(grn_ctx *ctx, scan_info *si, grn_obj *index, uint32_t sid, int32_t weight) +grn_scan_info_put_index(grn_ctx *ctx, scan_info *si, + grn_obj *index, uint32_t sid, int32_t weight, + grn_obj *scorer, + grn_obj *scorer_args_expr, + uint32_t scorer_args_expr_offset) { - scan_info_put_index(ctx, si, index, sid, weight); + scan_info_put_index(ctx, si, index, sid, weight, + scorer, + scorer_args_expr, + scorer_args_expr_offset); } scan_info ** @@ -4092,9 +3903,9 @@ grn_scan_info_put_logical_op(grn_ctx *ctx, scan_info **sis, int *ip, } int32_t -grn_expr_code_get_weight(grn_ctx *ctx, grn_expr_code *ec) +grn_expr_code_get_weight(grn_ctx *ctx, grn_expr_code *ec, uint32_t *offset) { - return get_weight(ctx, ec); + return get_weight(ctx, ec, offset); } int @@ -4169,18 +3980,6 @@ grn_scan_info_set_similarity_threshold(scan_info *si, int similarity_threshold) si->similarity_threshold = similarity_threshold; } -grn_obj * -grn_scan_info_get_scorer(scan_info *si) -{ - return si->scorer; -} - -void -grn_scan_info_set_scorer(scan_info *si, grn_obj *scorer) -{ - si->scorer = scorer; -} - grn_bool grn_scan_info_push_arg(scan_info *si, grn_obj *arg) { @@ -4202,32 +4001,64 @@ grn_scan_info_get_arg(grn_ctx *ctx, scan_info *si, int i) } static uint32_t -scan_info_build_find_index_column_index(grn_ctx *ctx, - scan_info *si, - grn_expr_code *ec, - uint32_t n_rest_codes, - grn_operator op) +scan_info_build_match_expr_codes_find_index(grn_ctx *ctx, scan_info *si, + grn_expr *expr, uint32_t i, + grn_obj **index, + int *sid) { - uint32_t offset = 0; - grn_obj *index; - int sid = 0; - int32_t weight; - - index = ec->value; - if (n_rest_codes >= 2 && - ec[1].value && - (ec[1].value->header.domain == GRN_DB_INT32 || - ec[1].value->header.domain == GRN_DB_UINT32) && - ec[2].op == GRN_OP_GET_MEMBER) { - if (ec[1].value->header.domain == GRN_DB_INT32) { - sid = GRN_INT32_VALUE(ec[1].value) + 1; - } else { - sid = GRN_UINT32_VALUE(ec[1].value) + 1; + grn_expr_code *ec; + uint32_t offset = 1; + grn_index_datum index_datum; + unsigned int n_index_data = 0; + + ec = &(expr->codes[i]); + switch (ec->value->header.type) { + case GRN_ACCESSOR : + n_index_data = grn_column_find_index_data(ctx, ec->value, si->op, + &index_datum, 1); + if (n_index_data > 0) { + grn_accessor *a = (grn_accessor *)(ec->value); + *sid = index_datum.section; + if (a->next && a->obj != index_datum.index) { + *index = ec->value; + } else { + *index = index_datum.index; + } + } + break; + case GRN_COLUMN_FIX_SIZE : + case GRN_COLUMN_VAR_SIZE : + n_index_data = grn_column_find_index_data(ctx, ec->value, si->op, + &index_datum, 1); + if (n_index_data > 0) { + *index = index_datum.index; + *sid = index_datum.section; + } + break; + case GRN_COLUMN_INDEX : + { + uint32_t n_rest_codes; + + *index = ec->value; + + n_rest_codes = expr->codes_curr - i; + if (n_rest_codes >= 2 && + ec[1].value && + (ec[1].value->header.domain == GRN_DB_INT32 || + ec[1].value->header.domain == GRN_DB_UINT32) && + ec[2].op == GRN_OP_GET_MEMBER) { + if (ec[1].value->header.domain == GRN_DB_INT32) { + *sid = GRN_INT32_VALUE(ec[1].value) + 1; + } else { + *sid = GRN_UINT32_VALUE(ec[1].value) + 1; + } + offset += 2; + } } - offset = 2; + break; + default : + break; } - weight = get_weight(ctx, ec + offset); - scan_info_put_index(ctx, si, index, sid, weight); return offset; } @@ -4237,8 +4068,9 @@ scan_info_build_match_expr_codes(grn_ctx *ctx, scan_info *si, grn_expr *expr, uint32_t i) { grn_expr_code *ec; - grn_obj *index; - int sid; + grn_obj *index = NULL; + int sid = 0; + uint32_t offset = 0; ec = &(expr->codes[i]); if (!ec->value) { @@ -4247,29 +4079,19 @@ scan_info_build_match_expr_codes(grn_ctx *ctx, scan_info *si, switch (ec->value->header.type) { case GRN_ACCESSOR : - if (grn_column_index(ctx, ec->value, si->op, &index, 1, &sid)) { - int32_t weight = get_weight(ctx, ec); - si->flags |= SCAN_ACCESSOR; - if (((grn_accessor *)ec->value)->next) { - scan_info_put_index(ctx, si, ec->value, sid, weight); - } else { - scan_info_put_index(ctx, si, index, sid, weight); - } - } - break; case GRN_COLUMN_FIX_SIZE : case GRN_COLUMN_VAR_SIZE : - if (grn_column_index(ctx, ec->value, si->op, &index, 1, &sid)) { - scan_info_put_index(ctx, si, index, sid, get_weight(ctx, ec)); - } - break; case GRN_COLUMN_INDEX : - { - uint32_t n_rest_codes; - uint32_t offset; - n_rest_codes = expr->codes_curr - i; - offset = scan_info_build_find_index_column_index(ctx, si, ec, - n_rest_codes, si->op); + offset = scan_info_build_match_expr_codes_find_index(ctx, si, expr, i, + &index, &sid); + i += offset - 1; + if (index) { + if (ec->value->header.type == GRN_ACCESSOR) { + si->flags |= SCAN_ACCESSOR; + } + scan_info_put_index(ctx, si, index, sid, + get_weight(ctx, &(expr->codes[i]), &offset), + NULL, NULL, 0); i += offset; } break; @@ -4285,24 +4107,27 @@ scan_info_build_match_expr_codes(grn_ctx *ctx, scan_info *si, GRN_OBJ_FIN(ctx, &inspected); return expr->codes_curr; } - si->scorer = ec->value; - i = scan_info_build_match_expr_codes(ctx, si, expr, i + 1); - if (expr->codes[i].op != GRN_OP_CALL) { - grn_obj inspected; - GRN_TEXT_INIT(&inspected, 0); - grn_inspect(ctx, &inspected, si->scorer); - ERR(GRN_INVALID_ARGUMENT, - "scorer must have only one argument: <%.*s>", - (int)GRN_TEXT_LEN(&inspected), - GRN_TEXT_VALUE(&inspected)); - GRN_OBJ_FIN(ctx, &inspected); - return expr->codes_curr; + i++; + offset = scan_info_build_match_expr_codes_find_index(ctx, si, expr, i, + &index, &sid); + i += offset; + if (index) { + uint32_t scorer_args_expr_offset = 0; + if (expr->codes[i].op != GRN_OP_CALL) { + scorer_args_expr_offset = i; + } + while (i < expr->codes_curr && expr->codes[i].op != GRN_OP_CALL) { + i++; + } + scan_info_put_index(ctx, si, index, sid, + get_weight(ctx, &(expr->codes[i]), &offset), + ec->value, + (grn_obj *)expr, + scorer_args_expr_offset); + i += offset; } break; - case GRN_TABLE_NO_KEY : - case GRN_TABLE_HASH_KEY : - case GRN_TABLE_PAT_KEY : - case GRN_TABLE_DAT_KEY : + default : { char name[GRN_TABLE_MAX_KEY_SIZE]; int name_size; @@ -4328,26 +4153,144 @@ scan_info_build_match_expr(grn_ctx *ctx, scan_info *si, grn_expr *expr) } } +static grn_bool +is_index_searchable_regexp(grn_ctx *ctx, grn_obj *regexp) +{ + const char *regexp_raw; + const char *regexp_raw_end; + grn_bool escaping = GRN_FALSE; + + if (!(regexp->header.domain == GRN_DB_SHORT_TEXT || + regexp->header.domain == GRN_DB_TEXT || + regexp->header.domain == GRN_DB_LONG_TEXT)) { + return GRN_FALSE; + } + + regexp_raw = GRN_TEXT_VALUE(regexp); + regexp_raw_end = regexp_raw + GRN_TEXT_LEN(regexp); + + while (regexp_raw < regexp_raw_end) { + unsigned int char_len; + + char_len = grn_charlen(ctx, regexp_raw, regexp_raw_end); + if (char_len == 0) { + return GRN_FALSE; + } + + if (char_len == 1) { + if (escaping) { + escaping = GRN_FALSE; + switch (regexp_raw[0]) { + case 'Z' : + case 'b' : + case 'B' : + case 'd' : + case 'D' : + case 'h' : + case 'H' : + case 'p' : + case 's' : + case 'S' : + case 'w' : + case 'W' : + case 'X' : + case 'k' : + case 'g' : + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + case '8' : + case '9' : + return GRN_FALSE; + default : + break; + } + } else { + switch (regexp_raw[0]) { + case '.' : + case '[' : + case ']' : + case '|' : + case '?' : + case '+' : + case '*' : + case '{' : + case '}' : + case '^' : + case '$' : + case '(' : + case ')' : + escaping = GRN_FALSE; + return GRN_FALSE; + case '\\' : + escaping = GRN_TRUE; + break; + default : + escaping = GRN_FALSE; + break; + } + } + } else { + escaping = GRN_FALSE; + } + + regexp_raw += char_len; + } + + return GRN_TRUE; +} + static void scan_info_build_match(grn_ctx *ctx, scan_info *si) { - int sid; - grn_obj *index, **p = si->args, **pe = si->args + si->nargs; + grn_obj **p, **pe; + + if (si->op == GRN_OP_REGEXP) { + p = si->args; + pe = si->args + si->nargs; + for (; p < pe; p++) { + if ((*p)->header.type == GRN_BULK && + !is_index_searchable_regexp(ctx, *p)) { + return; + } + } + } + + p = si->args; + pe = si->args + si->nargs; for (; p < pe; p++) { if ((*p)->header.type == GRN_EXPR) { scan_info_build_match_expr(ctx, si, (grn_expr *)(*p)); } else if (GRN_DB_OBJP(*p)) { - if (grn_column_index(ctx, *p, si->op, &index, 1, &sid)) { - scan_info_put_index(ctx, si, index, sid, 1); + grn_index_datum index_datum; + unsigned int n_index_data; + n_index_data = grn_column_find_index_data(ctx, *p, si->op, + &index_datum, 1); + if (n_index_data > 0) { + scan_info_put_index(ctx, si, + index_datum.index, index_datum.section, 1, + NULL, NULL, 0); } } else if (GRN_ACCESSORP(*p)) { + grn_index_datum index_datum; + unsigned int n_index_data; si->flags |= SCAN_ACCESSOR; - if (grn_column_index(ctx, *p, si->op, &index, 1, &sid)) { + n_index_data = grn_column_find_index_data(ctx, *p, si->op, + &index_datum, 1); + if (n_index_data > 0) { + grn_obj *index; if (((grn_accessor *)(*p))->next) { - scan_info_put_index(ctx, si, *p, sid, 1); + index = *p; } else { - scan_info_put_index(ctx, si, index, sid, 1); + index = index_datum.index; } + scan_info_put_index(ctx, si, + index, index_datum.section, 1, + NULL, NULL, 0); } } else { switch (si->op) { @@ -4412,6 +4355,7 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, case GRN_OP_GEO_WITHINP6 : case GRN_OP_GEO_WITHINP8 : case GRN_OP_TERM_EXTRACT : + case GRN_OP_REGEXP : if (stat < SCAN_COL1 || SCAN_CONST < stat) { return NULL; } stat = SCAN_START; m++; @@ -4492,6 +4436,7 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, case GRN_OP_GEO_WITHINP6 : case GRN_OP_GEO_WITHINP8 : case GRN_OP_TERM_EXTRACT : + case GRN_OP_REGEXP : stat = SCAN_START; si->op = c->op; si->end = c - e->codes; @@ -4572,17 +4517,28 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, sis[i++] = si; /* better index resolving framework for functions should be implemented */ { - int sid; - grn_obj *index, **p = si->args, **pe = si->args + si->nargs; + grn_obj **p = si->args, **pe = si->args + si->nargs; for (; p < pe; p++) { if (GRN_DB_OBJP(*p)) { - if (grn_column_index(ctx, *p, c->op, &index, 1, &sid)) { - scan_info_put_index(ctx, si, index, sid, 1); + grn_index_datum index_datum; + unsigned int n_index_data; + n_index_data = grn_column_find_index_data(ctx, *p, c->op, + &index_datum, 1); + if (n_index_data > 0) { + scan_info_put_index(ctx, si, + index_datum.index, index_datum.section, 1, + NULL, NULL, 0); } } else if (GRN_ACCESSORP(*p)) { + grn_index_datum index_datum; + unsigned int n_index_data; si->flags |= SCAN_ACCESSOR; - if (grn_column_index(ctx, *p, c->op, &index, 1, &sid)) { - scan_info_put_index(ctx, si, index, sid, 1); + n_index_data = grn_column_find_index_data(ctx, *p, c->op, + &index_datum, 1); + if (n_index_data > 0) { + scan_info_put_index(ctx, si, + index_datum.index, index_datum.section, 1, + NULL, NULL, 0); } } else { si->query = *p; @@ -4924,10 +4880,18 @@ grn_table_select_index_range_accessor(grn_ctx *ctx, grn_obj *table, accessor = (grn_accessor *)GRN_PTR_VALUE_AT(accessor_stack, i - 1); target = accessor->obj; - if (grn_column_index(ctx, target, GRN_OP_EQUAL, &index, 1, §ion) == 0) { - grn_obj_unlink(ctx, current_res); - current_res = NULL; - break; + { + grn_index_datum index_datum; + unsigned int n_index_data; + n_index_data = grn_column_find_index_data(ctx, target, GRN_OP_EQUAL, + &index_datum, 1); + if (n_index_data == 0) { + grn_obj_unlink(ctx, current_res); + current_res = NULL; + break; + } + index = index_datum.index; + section = index_datum.section; } if (section > 0) { @@ -5100,7 +5064,10 @@ grn_table_select_index(grn_ctx *ctx, grn_obj *table, scan_info *si, GRN_BULK_HEAD(si->query), GRN_BULK_VSIZE(si->query)); } - grn_ii_at(ctx, (grn_ii *)index, tid, (grn_hash *)res, si->logical_op); + if (tid != GRN_ID_NIL) { + grn_ii_at(ctx, (grn_ii *)index, tid, (grn_hash *)res, + si->logical_op); + } } grn_ii_resolve_sel_and(ctx, (grn_hash *)res, si->logical_op); processed = GRN_TRUE; @@ -5188,9 +5155,11 @@ grn_table_select_index(grn_ctx *ctx, grn_obj *table, scan_info *si, case GRN_OP_NEAR : case GRN_OP_NEAR2 : case GRN_OP_SIMILAR : + case GRN_OP_REGEXP : { grn_obj wv, **ip = &GRN_PTR_VALUE(&si->index); - int j = GRN_BULK_VSIZE(&si->index)/sizeof(grn_obj *); + int j; + int n_indexes = GRN_BULK_VSIZE(&si->index)/sizeof(grn_obj *); int32_t *wp = &GRN_INT32_VALUE(&si->wv); grn_search_optarg optarg; GRN_INT32_INIT(&wv, GRN_OBJ_VECTOR); @@ -5217,21 +5186,31 @@ grn_table_select_index(grn_ctx *ctx, grn_obj *table, scan_info *si, optarg.vector_size = 1; optarg.proc = NULL; optarg.max_size = 0; - optarg.scorer = si->scorer; ctx->flags |= GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND; - for (; j--; ip++, wp += 2) { + for (j = 0; j < n_indexes; j++, ip++, wp += 2) { uint32_t sid = (uint32_t) wp[0]; int32_t weight = wp[1]; if (sid) { int weight_index = sid - 1; - GRN_INT32_SET_AT(ctx, &wv, weight_index, weight); + int current_vector_size; + current_vector_size = GRN_BULK_VSIZE(&wv)/sizeof(int32_t); + if (weight_index < current_vector_size) { + ((int *)GRN_BULK_HEAD(&wv))[weight_index] = weight; + } else { + GRN_INT32_SET_AT(ctx, &wv, weight_index, weight); + } optarg.weight_vector = &GRN_INT32_VALUE(&wv); optarg.vector_size = GRN_BULK_VSIZE(&wv)/sizeof(int32_t); } else { optarg.weight_vector = NULL; optarg.vector_size = weight; } - if (j) { + optarg.scorer = GRN_PTR_VALUE_AT(&(si->scorers), j); + optarg.scorer_args_expr = + GRN_PTR_VALUE_AT(&(si->scorer_args_exprs), j); + optarg.scorer_args_expr_offset = + GRN_UINT32_VALUE_AT(&(si->scorer_args_expr_offsets), j); + if (j < n_indexes - 1) { if (sid && ip[0] == ip[1]) { continue; } } else { ctx->flags &= ~GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND; @@ -5475,239 +5454,6 @@ skip_space(grn_ctx *ctx, efs_info *q) } } -static grn_rc get_expr(grn_ctx *ctx, efs_info *q, grn_obj *column, grn_operator mode); -static grn_rc get_token(grn_ctx *ctx, efs_info *q, efs_op *op, grn_obj *column, grn_operator mode); - -static grn_rc -get_phrase(grn_ctx *ctx, efs_info *q, grn_obj *column, int mode, int option) -{ - const char *start, *s; - start = s = q->cur; - GRN_BULK_REWIND(&q->buf); - while (1) { - unsigned int len; - if (s >= q->str_end) { - q->cur = s; - break; - } - len = grn_charlen(ctx, s, q->str_end); - if (len == 0) { - /* invalid string containing malformed multibyte char */ - return GRN_END_OF_DATA; - } else if (len == 1) { - if (*s == GRN_QUERY_QUOTER) { - q->cur = s + 1; - break; - } else if (*s == GRN_QUERY_ESCAPE && s + 1 < q->str_end) { - s++; - len = grn_charlen(ctx, s, q->str_end); - } - } - GRN_TEXT_PUT(ctx, &q->buf, s, len); - s += len; - } - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, column, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GET_VALUE, 2); - grn_expr_append_const(ctx, q->e, &q->buf, GRN_OP_PUSH, 1); - if (mode == GRN_OP_MATCH || mode == GRN_OP_EXACT) { - grn_expr_append_op(ctx, q->e, mode, 2); - } else { - grn_expr_append_const_int(ctx, q->e, option, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, mode, 3); - } - return GRN_SUCCESS; -} - -static grn_rc -get_geocond(grn_ctx *ctx, efs_info *q, grn_obj *longitude, grn_obj *latitude) -{ - unsigned int len; - const char *start = q->cur, *end; - for (end = q->cur;; ) { - /* null check and length check */ - if (!(len = grn_charlen(ctx, end, q->str_end))) { - q->cur = q->str_end; - break; - } - if (grn_isspace(end, ctx->encoding) || - *end == GRN_QUERY_PARENR) { - q->cur = end; - break; - } - } - { - const char *tokbuf[8]; - int32_t lng0, lat0, lng1, lat1, lng2, lat2, r; - int32_t n = grn_str_tok((char *)start, end - start, ',', tokbuf, 8, NULL); - switch (n) { - case 3 : - lng0 = grn_atoi(start, tokbuf[0], NULL); - lat0 = grn_atoi(tokbuf[0] + 1, tokbuf[1], NULL); - r = grn_atoi(tokbuf[1] + 1, tokbuf[2], NULL); - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, longitude, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GET_VALUE, 2); - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, latitude, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GET_VALUE, 2); - grn_expr_append_const_int(ctx, q->e, lng0, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lat0, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, r, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GEO_WITHINP5, 5); - break; - case 4 : - lng0 = grn_atoi(start, tokbuf[0], NULL); - lat0 = grn_atoi(tokbuf[0] + 1, tokbuf[1], NULL); - lng1 = grn_atoi(tokbuf[1] + 1, tokbuf[2], NULL); - lat1 = grn_atoi(tokbuf[2] + 1, tokbuf[3], NULL); - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, longitude, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GET_VALUE, 2); - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, latitude, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GET_VALUE, 2); - grn_expr_append_const_int(ctx, q->e, lng0, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lat0, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lng1, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lat1, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GEO_WITHINP6, 6); - break; - case 6 : - lng0 = grn_atoi(start, tokbuf[0], NULL); - lat0 = grn_atoi(tokbuf[0] + 1, tokbuf[1], NULL); - lng1 = grn_atoi(tokbuf[1] + 1, tokbuf[2], NULL); - lat1 = grn_atoi(tokbuf[2] + 1, tokbuf[3], NULL); - lng2 = grn_atoi(tokbuf[3] + 1, tokbuf[4], NULL); - lat2 = grn_atoi(tokbuf[4] + 1, tokbuf[5], NULL); - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, longitude, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GET_VALUE, 2); - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, latitude, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GET_VALUE, 2); - grn_expr_append_const_int(ctx, q->e, lng0, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lat0, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lng1, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lat1, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lng2, GRN_OP_PUSH, 1); - grn_expr_append_const_int(ctx, q->e, lat2, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GEO_WITHINP8, 8); - break; - default : - ERR(GRN_INVALID_ARGUMENT, "invalid geocond"); - break; - } - } - return ctx->rc; -} - -static grn_rc -get_word(grn_ctx *ctx, efs_info *q, grn_obj *column, int mode, int option) -{ - const char *start = q->cur, *end; - unsigned int len; - for (end = q->cur;; ) { - /* null check and length check */ - if (!(len = grn_charlen(ctx, end, q->str_end))) { - q->cur = q->str_end; - break; - } - if (grn_isspace(end, ctx->encoding) || - *end == GRN_QUERY_PARENR) { - q->cur = end; - break; - } - if (*end == GRN_QUERY_COLUMN) { - grn_obj *c = grn_obj_column(ctx, q->table, start, end - start); - if (c && end + 1 < q->str_end) { - efs_op op; - switch (end[1]) { - case '!' : - mode = GRN_OP_NOT_EQUAL; - q->cur = end + 2; - break; - case '=' : - if (q->flags & GRN_EXPR_ALLOW_UPDATE) { - mode = GRN_OP_ASSIGN; - q->cur = end + 2; - } else { - get_token(ctx, q, &op, c, mode); - } - break; - case '<' : - if (end + 2 < q->str_end && end[2] == '=') { - mode = GRN_OP_LESS_EQUAL; - q->cur = end + 3; - } else { - mode = GRN_OP_LESS; - q->cur = end + 2; - } - break; - case '>' : - if (end + 2 < q->str_end && end[2] == '=') { - mode = GRN_OP_GREATER_EQUAL; - q->cur = end + 3; - } else { - mode = GRN_OP_GREATER; - q->cur = end + 2; - } - break; - case '%' : - mode = GRN_OP_MATCH; - q->cur = end + 2; - break; - case '@' : - q->cur = end + 2; - return get_geocond(ctx, q, column, c); - break; - default : - mode = GRN_OP_EQUAL; - q->cur = end + 1; - break; - } - return get_token(ctx, q, &op, c, mode); - } else { - ERR(GRN_INVALID_ARGUMENT, "column lookup failed"); - return ctx->rc; - } - } else if (*end == GRN_QUERY_PREFIX) { - mode = GRN_OP_PREFIX; - q->cur = end + 1; - break; - } - end += len; - } - if (!column) { - ERR(GRN_INVALID_ARGUMENT, "column missing"); - return ctx->rc; - } - if (mode == GRN_OP_ASSIGN) { - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, column, GRN_OP_PUSH, 1); - grn_expr_append_const_str(ctx, q->e, start, end - start, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_ASSIGN, 2); - } else { - grn_expr_append_obj(ctx, q->e, q->v, GRN_OP_PUSH, 1); - grn_expr_append_const(ctx, q->e, column, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, GRN_OP_GET_VALUE, 2); - grn_expr_append_const_str(ctx, q->e, start, end - start, GRN_OP_PUSH, 1); - switch (mode) { - case GRN_OP_NEAR : - case GRN_OP_NEAR2 : - case GRN_OP_SIMILAR : - case GRN_OP_TERM_EXTRACT : - grn_expr_append_const_int(ctx, q->e, option, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, mode, 3); - break; - default : - grn_expr_append_op(ctx, q->e, mode, 2); - break; - } - } - return GRN_SUCCESS; -} - static grn_bool get_op(efs_info *q, efs_op *op, grn_operator *mode, int *option) { @@ -5756,90 +5502,6 @@ get_op(efs_info *q, efs_op *op, grn_operator *mode, int *option) return found; } -static grn_rc -get_token(grn_ctx *ctx, efs_info *q, efs_op *op, grn_obj *column, grn_operator mode) -{ - int option = 0; - op->op = q->default_op; - op->weight = DEFAULT_WEIGHT; - for (;;) { - skip_space(ctx, q); - if (q->cur >= q->str_end) { return GRN_END_OF_DATA; } - switch (*q->cur) { - case '\0' : - return GRN_END_OF_DATA; - break; - case GRN_QUERY_PARENR : - q->cur++; - return GRN_END_OF_DATA; - break; - case GRN_QUERY_QUOTEL : - q->cur++; - return get_phrase(ctx, q, column, mode, option); - break; - case GRN_QUERY_PREFIX : - q->cur++; - get_op(q, op, &mode, &option); - break; - case GRN_QUERY_AND : - q->cur++; - op->op = GRN_OP_AND; - break; - case GRN_QUERY_AND_NOT : - q->cur++; - op->op = GRN_OP_AND_NOT; - break; - case GRN_QUERY_ADJ_INC : - q->cur++; - if (op->weight < 127) { op->weight++; } - op->op = GRN_OP_ADJUST; - break; - case GRN_QUERY_ADJ_DEC : - q->cur++; - if (op->weight > -128) { op->weight--; } - op->op = GRN_OP_ADJUST; - break; - case GRN_QUERY_ADJ_NEG : - q->cur++; - op->op = GRN_OP_ADJUST; - op->weight = -1; - break; - case GRN_QUERY_PARENL : - q->cur++; - return get_expr(ctx, q, column, mode); - break; - case 'O' : - if (q->cur[1] == 'R' && q->cur[2] == ' ') { - q->cur += 2; - op->op = GRN_OP_OR; - break; - } - /* fallthru */ - default : - return get_word(ctx, q, column, mode, option); - break; - } - } - return GRN_SUCCESS; -} - -static grn_rc -get_expr(grn_ctx *ctx, efs_info *q, grn_obj *column, grn_operator mode) -{ - efs_op op; - grn_rc rc = get_token(ctx, q, &op, column, mode); - if (rc) { return rc; } - while (!(rc = get_token(ctx, q, &op, column, mode))) { - if (op.op == GRN_OP_ADJUST) { - grn_expr_append_const_int(ctx, q->e, op.weight, GRN_OP_PUSH, 1); - grn_expr_append_op(ctx, q->e, op.op, 3); - } else { - grn_expr_append_op(ctx, q->e, op.op, 2); - } - } - return rc; -} - #define DISABLE_UNUSED_CODE 1 #ifndef DISABLE_UNUSED_CODE static const char * @@ -6090,6 +5752,10 @@ get_word_(grn_ctx *ctx, efs_info *q) mode = GRN_OP_SUFFIX; q->cur = end + 2; break; + case '~' : + mode = GRN_OP_REGEXP; + q->cur = end + 2; + break; default : mode = GRN_OP_EQUAL; q->cur = end + 1; @@ -6502,6 +6168,10 @@ parse_script(grn_ctx *ctx, efs_info *q) PARSE(GRN_EXPR_TOKEN_SUFFIX); q->cur += 2; break; + case '~' : + PARSE(GRN_EXPR_TOKEN_REGEXP); + q->cur += 2; + break; default : PARSE(GRN_EXPR_TOKEN_MATCH); q->cur++; @@ -7195,3 +6865,42 @@ grn_expr_dump_plan(grn_ctx *ctx, grn_obj *expr, grn_obj *buffer) } GRN_API_RETURN(GRN_SUCCESS); } + +static unsigned int +grn_expr_estimate_size_raw(grn_ctx *ctx, grn_obj *expr, grn_obj *table) +{ + return grn_table_size(ctx, table); +} + +unsigned int +grn_expr_estimate_size(grn_ctx *ctx, grn_obj *expr) +{ + grn_obj *table; + grn_obj *variable; + unsigned int size; + + variable = grn_expr_get_var_by_offset(ctx, expr, 0); + if (!variable) { + ERR(GRN_INVALID_ARGUMENT, "at least one variable must be defined"); + return 0; + } + + table = grn_ctx_at(ctx, variable->header.domain); + if (!table) { + ERR(GRN_INVALID_ARGUMENT, + "variable refers unknown domain: <%u>", variable->header.domain); + return 0; + } + + GRN_API_ENTER; +#ifdef GRN_WITH_MRUBY + if (ctx->impl->mrb.state) { + size = grn_mrb_expr_estimate_size(ctx, expr, table); + } else { + size = grn_expr_estimate_size_raw(ctx, expr, table); + } +#else + size = grn_expr_estimate_size_raw(ctx, expr, table); +#endif + GRN_API_RETURN(size); +} diff --git a/storage/mroonga/vendor/groonga/lib/geo.c b/storage/mroonga/vendor/groonga/lib/geo.c index 21b50c4a1a4..d2eb049ce21 100644 --- a/storage/mroonga/vendor/groonga/lib/geo.c +++ b/storage/mroonga/vendor/groonga/lib/geo.c @@ -91,18 +91,18 @@ compute_min_and_max_key(uint8_t *key_base, int diff_bit, diff_bit_mask = 0xff >> (diff_bit % 8); if (diff_byte == sizeof(grn_geo_point)) { - if (key_min) { memcpy(key_min, key_base, diff_byte); } - if (key_max) { memcpy(key_max, key_base, diff_byte); } + if (key_min) { grn_memcpy(key_min, key_base, diff_byte); } + if (key_max) { grn_memcpy(key_max, key_base, diff_byte); } } else { if (key_min) { - memcpy(key_min, key_base, diff_byte + 1); + grn_memcpy(key_min, key_base, diff_byte + 1); key_min[diff_byte] &= ~diff_bit_mask; memset(key_min + diff_byte + 1, 0, sizeof(grn_geo_point) - diff_byte - 1); } if (key_max) { - memcpy(key_max, key_base, diff_byte + 1); + grn_memcpy(key_max, key_base, diff_byte + 1); key_max[diff_byte] |= diff_bit_mask; memset(key_max + diff_byte + 1, 0xff, sizeof(grn_geo_point) - diff_byte - 1); @@ -274,7 +274,7 @@ grn_geo_table_sort_detect_far_point(grn_ctx *ctx, grn_obj *table, grn_obj *index grn_gton(geo_key_curr, base_point, sizeof(grn_geo_point)); *diff_bit = sizeof(grn_geo_point) * 8; diff_bit_current = sizeof(grn_geo_point) * 8; - memcpy(&point, base_point, sizeof(grn_geo_point)); + grn_memcpy(&point, base_point, sizeof(grn_geo_point)); ep = entries; inspect_mesh(ctx, &point, *diff_bit, -1); while ((tid = grn_pat_cursor_next(ctx, pc))) { @@ -862,7 +862,7 @@ grn_geo_select_in_circle(grn_ctx *ctx, grn_obj *index, name_size = grn_obj_name(ctx, domain_object, name, GRN_TABLE_MAX_KEY_SIZE); grn_obj_unlink(ctx, domain_object); } else { - strcpy(name, "(null)"); + grn_strcpy(name, GRN_TABLE_MAX_KEY_SIZE, "(null)"); name_size = strlen(name); } ERR(GRN_INVALID_ARGUMENT, @@ -1034,7 +1034,7 @@ in_rectangle_data_fill(grn_ctx *ctx, grn_obj *index, name_size = grn_obj_name(ctx, domain_object, name, GRN_TABLE_MAX_KEY_SIZE); grn_obj_unlink(ctx, domain_object); } else { - strcpy(name, "(null)"); + grn_strcpy(name, GRN_TABLE_MAX_KEY_SIZE, "(null)"); name_size = strlen(name); } ERR(GRN_INVALID_ARGUMENT, @@ -1419,8 +1419,8 @@ grn_geo_cursor_area_init(grn_ctx *ctx, } area->current_entry = 0; - memcpy(&(area->top_left), &area_top_left, sizeof(grn_geo_point)); - memcpy(&(area->bottom_right), &area_bottom_right, sizeof(grn_geo_point)); + grn_memcpy(&(area->top_left), &area_top_left, sizeof(grn_geo_point)); + grn_memcpy(&(area->bottom_right), &area_bottom_right, sizeof(grn_geo_point)); grn_gton(area->top_left_key, &area_top_left, sizeof(grn_geo_point)); grn_gton(area->bottom_right_key, &area_bottom_right, sizeof(grn_geo_point)); @@ -1430,7 +1430,7 @@ grn_geo_cursor_area_init(grn_ctx *ctx, &area_bottom_right, &data); entry->target_bit = data.rectangle_common_bit; - memcpy(entry->key, data.rectangle_common_key, sizeof(grn_geo_point)); + grn_memcpy(entry->key, data.rectangle_common_key, sizeof(grn_geo_point)); entry->status_flags = GRN_GEO_CURSOR_ENTRY_STATUS_TOP_INCLUDED | GRN_GEO_CURSOR_ENTRY_STATUS_BOTTOM_INCLUDED | @@ -1474,8 +1474,8 @@ grn_geo_cursor_open_in_rectangle(grn_ctx *ctx, cursor->pat = data.pat; cursor->index = index; - memcpy(&(cursor->top_left), data.top_left, sizeof(grn_geo_point)); - memcpy(&(cursor->bottom_right), data.bottom_right, sizeof(grn_geo_point)); + grn_memcpy(&(cursor->top_left), data.top_left, sizeof(grn_geo_point)); + grn_memcpy(&(cursor->bottom_right), data.bottom_right, sizeof(grn_geo_point)); cursor->pat_cursor = NULL; cursor->ii_cursor = NULL; cursor->offset = offset; @@ -1494,10 +1494,12 @@ grn_geo_cursor_open_in_rectangle(grn_ctx *ctx, } } { - const char *minimum_reduce_bit_env; + char minimum_reduce_bit_env[GRN_ENV_BUFFER_SIZE]; cursor->minimum_reduce_bit = 0; - minimum_reduce_bit_env = getenv("GRN_GEO_IN_RECTANGLE_MINIMUM_REDUCE_BIT"); - if (minimum_reduce_bit_env) { + grn_getenv("GRN_GEO_IN_RECTANGLE_MINIMUM_REDUCE_BIT", + minimum_reduce_bit_env, + GRN_ENV_BUFFER_SIZE); + if (minimum_reduce_bit_env[0]) { cursor->minimum_reduce_bit = atoi(minimum_reduce_bit_env); } if (cursor->minimum_reduce_bit < 1) { @@ -1544,7 +1546,7 @@ grn_geo_cursor_entry_next_push(grn_ctx *ctx, grn_geo_cursor_area *area; area = &(cursor->areas[cursor->current_area]); next_entry = &(area->entries[++area->current_entry]); - memcpy(next_entry, entry, sizeof(grn_geo_cursor_entry)); + grn_memcpy(next_entry, entry, sizeof(grn_geo_cursor_entry)); pushed = GRN_TRUE; } grn_table_cursor_close(ctx, pat_cursor); @@ -1578,9 +1580,9 @@ grn_geo_cursor_entry_next(grn_ctx *ctx, top_left_key = area->top_left_key; bottom_right_key = area->bottom_right_key; - memcpy(entry, - &(area->entries[area->current_entry--]), - sizeof(grn_geo_cursor_entry)); + grn_memcpy(entry, + &(area->entries[area->current_entry--]), + sizeof(grn_geo_cursor_entry)); while (GRN_TRUE) { grn_geo_cursor_entry next_entry0, next_entry1; grn_bool pushed = GRN_FALSE; @@ -1663,9 +1665,9 @@ grn_geo_cursor_entry_next(grn_ctx *ctx, break; } - memcpy(&next_entry0, entry, sizeof(grn_geo_cursor_entry)); + grn_memcpy(&next_entry0, entry, sizeof(grn_geo_cursor_entry)); next_entry0.target_bit++; - memcpy(&next_entry1, entry, sizeof(grn_geo_cursor_entry)); + grn_memcpy(&next_entry1, entry, sizeof(grn_geo_cursor_entry)); next_entry1.target_bit++; SET_N_BIT(next_entry1.key, next_entry1.target_bit); @@ -1767,9 +1769,9 @@ grn_geo_cursor_entry_next(grn_ctx *ctx, print_key_mark(ctx, stack_entry->target_bit); } #endif - memcpy(entry, - &(area->entries[area->current_entry--]), - sizeof(grn_geo_cursor_entry)); + grn_memcpy(entry, + &(area->entries[area->current_entry--]), + sizeof(grn_geo_cursor_entry)); #ifdef GEO_DEBUG printf("%d: pop entry\n", entry->target_bit); #endif @@ -1979,7 +1981,7 @@ geo_point_get(grn_ctx *ctx, grn_obj *pat, int flags, grn_geo_point *geo_point) void *key; int key_size; key_size = grn_table_cursor_get_key(ctx, cursor, &key); - memcpy(geo_point, key, key_size); + grn_memcpy(geo_point, key, key_size); } exit: diff --git a/storage/mroonga/vendor/groonga/lib/grn.h b/storage/mroonga/vendor/groonga/lib/grn.h index c33ad7f7ec4..f4ee6e962a9 100644 --- a/storage/mroonga/vendor/groonga/lib/grn.h +++ b/storage/mroonga/vendor/groonga/lib/grn.h @@ -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 @@ -23,6 +23,10 @@ # include <config.h> #endif /* HAVE_CONFIG_H */ +#if defined(WIN32) && defined(__GNUC__) +# define __MINGW_MSVC_COMPAT_WARNINGS +#endif /* defined(WIN32) && defined(__GNUC__) */ + #ifdef __cplusplus # define __STDC_LIMIT_MACROS #endif @@ -67,30 +71,6 @@ # define GRN_VAR extern #endif -#ifdef HAVE_OPEN -# define GRN_OPEN(pathname, ...) open(pathname, __VA_ARGS__) -#else -# define GRN_OPEN(pathname, ...) _open(pathname, __VA_ARGS__) -#endif /* HAVE_OPEN */ - -#ifdef HAVE_CLOSE -# define GRN_CLOSE(fd) close(fd) -#else -# define GRN_CLOSE(fd) _close(fd) -#endif /* HAVE_CLOSE */ - -#ifdef HAVE_READ -# define GRN_READ(fd, buf, count) read(fd, buf, count) -#else -# define GRN_READ(fd, buf, count) _read(fd, buf, count) -#endif /* HAVE_READ */ - -#ifdef HAVE_WRITE -# define GRN_WRITE(fd, buf, count) write(fd, buf, count) -#else -# define GRN_WRITE(fd, buf, count) _write(fd, buf, count) -#endif /* HAVE_WRITE */ - #ifdef WIN32 # if defined(__GNUC__) && !defined(WINVER) @@ -116,15 +96,9 @@ # endif # endif -# ifndef __GNUC__ -# define snprintf(str, size, ...) _snprintf(str, size, __VA_ARGS__) -# endif /* __GNUC__ */ # if !defined(__GNUC__) && _MSC_VER < 1500 # define vsnprintf(str, size, format, ap) _vsnprintf(str, size, format, ap) # endif /* !defined(__GNUC__) && _MSC_VER < 1500 */ -# ifndef HAVE_UNLINK -# define unlink(pathname) _unlink(pathname) -# endif # define getpid() _getpid() # if !defined(__GNUC__) && _MSC_VER < 1400 # define fstat(fd, buf) _fstat(fd, buf) @@ -479,12 +453,14 @@ typedef int grn_cond; # else /* WIN64 */ # define GRN_FMT_SOCKET "u" # endif /* WIN64 */ +# define GRN_FMT_OFF64_T GRN_FMT_LLD #else /* WIN32 */ # define GRN_FMT_LLD "lld" # define GRN_FMT_LLU "llu" # define GRN_FMT_SIZE "zu" # define GRN_FMT_SSIZE "zd" # define GRN_FMT_SOCKET "d" +# define GRN_FMT_OFF64_T "jd" #endif /* WIN32 */ #ifdef __GNUC__ @@ -549,13 +525,6 @@ typedef int grn_cond; (*(p) = (v)) # endif /* ATOMIC 64BIT SET */ -# ifdef HAVE_MKOSTEMP -# define GRN_MKOSTEMP(template,flags,mode) mkostemp(template,flags) -# else /* HAVE_MKOSTEMP */ -# define GRN_MKOSTEMP(template,flags,mode) \ - (mktemp(template), GRN_OPEN((template),((flags)|O_RDWR|O_CREAT|O_EXCL),mode)) -# endif /* HAVE_MKOSTEMP */ - #elif (defined(WIN32) || defined (_WIN64)) /* __GNUC__ */ # define GRN_ATOMIC_ADD_EX(p,i,r) \ @@ -585,9 +554,6 @@ typedef int grn_cond; # define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--) # define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r) -# define GRN_MKOSTEMP(template,flags,mode) \ - (mktemp(template), GRN_OPEN((template),((flags)|O_RDWR|O_CREAT),mode)) - #else /* __GNUC__ */ # if (defined(__sun) && defined(__SVR4)) /* ATOMIC ADD */ @@ -603,9 +569,6 @@ typedef int grn_cond; # define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--) # define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r) -# define GRN_MKOSTEMP(template,flags,mode) \ - (mktemp(template), GRN_OPEN((template),flags,mode)) - #endif /* __GNUC__ */ typedef uint8_t byte; @@ -712,7 +675,7 @@ grn_str_greater(const uint8_t *ap, uint32_t as, const uint8_t *bp, uint32_t bs) lo_ = (lo_ | (lo_ << 1)) & 0x5555555555555555ULL;\ result_ = (la_ << 1) | lo_;\ grn_hton_uint64(result_, result_);\ - memcpy(keybuf, &result_, sizeof(result_));\ + grn_memcpy(keybuf, &result_, sizeof(result_));\ } while (0) #define grn_ntog(keybuf,key,size) do {\ diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx.h b/storage/mroonga/vendor/groonga/lib/grn_ctx.h index dbf461e668e..2f052f5f1c5 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ctx.h +++ b/storage/mroonga/vendor/groonga/lib/grn_ctx.h @@ -329,6 +329,58 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx); ERR(rc, "socket error '%s' (%s)[%d]", str, m, e);\ } while (0) +#define ERRNO_ERR(str) do {\ + 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);\ + switch (errno_keep) {\ + case EPERM : rc = GRN_OPERATION_NOT_PERMITTED; break;\ + case ENOENT : rc = GRN_NO_SUCH_FILE_OR_DIRECTORY; break;\ + case ESRCH : rc = GRN_NO_SUCH_PROCESS; break;\ + case EINTR : rc = GRN_INTERRUPTED_FUNCTION_CALL; break;\ + case EIO : rc = GRN_INPUT_OUTPUT_ERROR; break;\ + case E2BIG : rc = GRN_ARG_LIST_TOO_LONG; break;\ + case ENOEXEC : rc = GRN_EXEC_FORMAT_ERROR; break;\ + case EBADF : rc = GRN_BAD_FILE_DESCRIPTOR; break;\ + case ECHILD : rc = GRN_NO_CHILD_PROCESSES; break;\ + case EAGAIN: rc = GRN_OPERATION_WOULD_BLOCK; break;\ + case ENOMEM : rc = GRN_NO_MEMORY_AVAILABLE; break;\ + case EACCES : rc = GRN_PERMISSION_DENIED; break;\ + case EFAULT : rc = GRN_BAD_ADDRESS; break;\ + case EEXIST : rc = GRN_FILE_EXISTS; break;\ + /* case EXDEV : */\ + case ENODEV : rc = GRN_NO_SUCH_DEVICE; break;\ + case ENOTDIR : rc = GRN_NOT_A_DIRECTORY; break;\ + case EISDIR : rc = GRN_IS_A_DIRECTORY; break;\ + case EINVAL : rc = GRN_INVALID_ARGUMENT; break;\ + case EMFILE : rc = GRN_TOO_MANY_OPEN_FILES; break;\ + case ENOTTY : rc = GRN_INAPPROPRIATE_I_O_CONTROL_OPERATION; break;\ + case EFBIG : rc = GRN_FILE_TOO_LARGE; break;\ + case ENOSPC : rc = GRN_NO_SPACE_LEFT_ON_DEVICE; break;\ + case ESPIPE : rc = GRN_INVALID_SEEK; break;\ + case EROFS : rc = GRN_READ_ONLY_FILE_SYSTEM; break;\ + case EMLINK : rc = GRN_TOO_MANY_LINKS; break;\ + case EPIPE : rc = GRN_BROKEN_PIPE; break;\ + case EDOM : rc = GRN_DOMAIN_ERROR; break;\ + case ERANGE : rc = GRN_RANGE_ERROR; break;\ + case EDEADLOCK : rc = GRN_RESOURCE_DEADLOCK_AVOIDED; break;\ + case ENAMETOOLONG : rc = GRN_FILENAME_TOO_LONG; break;\ + case EILSEQ : rc = GRN_ILLEGAL_BYTE_SEQUENCE; break;\ + /* case STRUNCATE : */\ + default :\ + rc = GRN_UNKNOWN_ERROR;\ + show_errno = GRN_TRUE;\ + break;\ + }\ + if (show_errno) {\ + ERR(rc, "syscall error '%s' (%s)[%d]", str, system_message, errno_keep);\ + } else {\ + ERR(rc, "syscall error '%s' (%s)", str, system_message);\ + }\ +} while (0) + #else /* WIN32 */ #define SERR(str) do {\ grn_rc rc;\ @@ -387,7 +439,7 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx); break;\ }\ if (show_errno) {\ - ERR(rc, "syscall error '%s' (%s)[%d]", str, system_message, errno_keep); \ + ERR(rc, "syscall error '%s' (%s)[%d]", str, system_message, errno_keep);\ } else {\ ERR(rc, "syscall error '%s' (%s)", str, system_message);\ }\ @@ -395,6 +447,8 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx); #define SOERR(str) SERR(str) +#define ERRNO_ERR(str) SERR(str) + #endif /* WIN32 */ #define GERR(rc,...) ERRSET(&grn_gctx, GRN_ERROR, (rc), __VA_ARGS__) @@ -450,6 +504,8 @@ typedef void *(*grn_realloc_func) (grn_ctx *ctx, void *ptr, size_t size, const char *file, int line, const char *func); typedef char *(*grn_strdup_func) (grn_ctx *ctx, const char *string, const char *file, int line, const char *func); +typedef void (*grn_free_func) (grn_ctx *ctx, void *ptr, + const char *file, int line, const char *func); grn_malloc_func grn_ctx_get_malloc(grn_ctx *ctx); void grn_ctx_set_malloc(grn_ctx *ctx, grn_malloc_func malloc_func); grn_calloc_func grn_ctx_get_calloc(grn_ctx *ctx); @@ -458,11 +514,14 @@ grn_realloc_func grn_ctx_get_realloc(grn_ctx *ctx); void grn_ctx_set_realloc(grn_ctx *ctx, grn_realloc_func realloc_func); grn_strdup_func grn_ctx_get_strdup(grn_ctx *ctx); void grn_ctx_set_strdup(grn_ctx *ctx, grn_strdup_func strdup_func); +grn_free_func grn_ctx_get_free(grn_ctx *ctx); +void grn_ctx_set_free(grn_ctx *ctx, grn_free_func free_func); void *grn_malloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func); void *grn_calloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func); void *grn_realloc(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func); char *grn_strdup(grn_ctx *ctx, const char *s, const char* file, int line, const char *func); +void grn_free(grn_ctx *ctx, void *ptr, const char *file, int line, const char *func); #else # define grn_malloc grn_malloc_default # define grn_calloc grn_calloc_default @@ -518,7 +577,8 @@ extern grn_timeval grn_starttime; #define GRN_TIME_USEC_TO_NSEC(usec) ((usec) * GRN_TIME_NSEC_PER_USEC) GRN_API grn_rc grn_timeval_now(grn_ctx *ctx, grn_timeval *tv); -GRN_API grn_rc grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf); +GRN_API grn_rc grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf, size_t buf_size); +struct tm *grn_timeval2tm(grn_ctx *ctx, grn_timeval *tv, struct tm *tm_buffer); grn_rc grn_str2timeval(const char *str, uint32_t str_len, grn_timeval *tv); GRN_API void grn_ctx_log(grn_ctx *ctx, const char *fmt, ...) GRN_ATTRIBUTE_PRINTF(2); @@ -582,6 +642,8 @@ typedef struct { /**** cache ****/ +#define GRN_CACHE_MAX_KEY_SIZE GRN_HASH_MAX_KEY_SIZE_LARGE + typedef struct { uint32_t nentries; uint32_t max_nentries; diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h index 9e0b5677497..b653f35015b 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h +++ b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h @@ -19,16 +19,14 @@ #define GRN_CTX_IMPL_H #ifndef GRN_CTX_H -#include "grn_ctx.h" +# include "grn_ctx.h" #endif /* GRN_CTX_H */ #ifndef GRN_COM_H -#include "grn_com.h" +# include "grn_com.h" #endif /* GRN_COM_H */ -#ifdef GRN_WITH_MESSAGE_PACK -#include <msgpack.h> -#endif +#include "grn_msgpack.h" #ifdef GRN_WITH_MRUBY # include <mruby.h> @@ -111,6 +109,9 @@ struct _grn_mrb_data { struct { struct RClass *time_class; } builtin; + struct { + struct RClass *operator_class; + } groonga; }; #endif @@ -129,6 +130,7 @@ struct _grn_ctx_impl { grn_calloc_func calloc_func; grn_realloc_func realloc_func; grn_strdup_func strdup_func; + grn_free_func free_func; #endif #ifdef USE_MEMORY_DEBUG diff --git a/storage/mroonga/vendor/groonga/lib/grn_db.h b/storage/mroonga/vendor/groonga/lib/grn_db.h index 0eeab145e0e..cbc2cccaf4e 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_db.h +++ b/storage/mroonga/vendor/groonga/lib/grn_db.h @@ -26,6 +26,8 @@ #include <groonga/token_filter.h> #include <groonga/scorer.h> +#include <float.h> + #ifdef __cplusplus extern "C" { #endif diff --git a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c index 80c596bc6b3..b3e4da09095 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c +++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c @@ -58,13 +58,13 @@ ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 113 +#define YYNOCODE 114 #define YYACTIONTYPE unsigned short int #define grn_expr_parserTOKENTYPE int typedef union { int yyinit; grn_expr_parserTOKENTYPE yy0; - void * yy81; + void * yy165; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -73,8 +73,8 @@ typedef union { #define grn_expr_parserARG_PDECL , efs_info *efsi #define grn_expr_parserARG_FETCH efs_info *efsi = yypParser->efsi #define grn_expr_parserARG_STORE yypParser->efsi = efsi -#define YYNSTATE 223 -#define YYNRULE 131 +#define YYNSTATE 225 +#define YYNRULE 132 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) @@ -143,392 +143,399 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ -#define YY_ACTTAB_COUNT (1610) +#define YY_ACTTAB_COUNT (1639) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 2, 70, 52, 51, 50, 220, 1, 75, 79, 123, - /* 10 */ 4, 219, 69, 355, 76, 107, 78, 150, 219, 189, - /* 20 */ 192, 213, 84, 121, 120, 133, 132, 131, 115, 85, - /* 30 */ 98, 111, 99, 178, 209, 195, 73, 188, 184, 188, - /* 40 */ 184, 220, 71, 25, 79, 138, 9, 32, 69, 64, - /* 50 */ 63, 215, 33, 28, 67, 66, 65, 62, 61, 60, - /* 60 */ 59, 58, 57, 183, 182, 181, 180, 179, 3, 75, - /* 70 */ 113, 34, 6, 219, 189, 192, 213, 84, 121, 120, - /* 80 */ 133, 132, 131, 115, 85, 98, 111, 99, 178, 209, - /* 90 */ 195, 73, 187, 105, 188, 184, 220, 1, 28, 79, - /* 100 */ 123, 4, 122, 69, 31, 30, 189, 192, 213, 84, - /* 110 */ 121, 120, 133, 132, 131, 115, 85, 98, 111, 99, - /* 120 */ 178, 209, 195, 73, 139, 127, 188, 184, 36, 35, - /* 130 */ 110, 68, 56, 55, 8, 24, 129, 197, 196, 29, - /* 140 */ 64, 63, 54, 53, 124, 67, 66, 65, 62, 61, - /* 150 */ 60, 59, 58, 57, 183, 182, 181, 180, 179, 3, - /* 160 */ 7, 26, 165, 185, 83, 142, 127, 176, 189, 166, - /* 170 */ 213, 84, 121, 120, 133, 132, 131, 115, 85, 98, - /* 180 */ 111, 99, 178, 209, 195, 73, 173, 130, 188, 184, - /* 190 */ 11, 82, 81, 80, 77, 220, 71, 148, 79, 138, - /* 200 */ 9, 171, 69, 64, 63, 174, 28, 72, 67, 66, - /* 210 */ 65, 62, 61, 60, 59, 58, 57, 183, 182, 181, - /* 220 */ 180, 179, 3, 177, 7, 194, 193, 185, 83, 106, - /* 230 */ 126, 176, 189, 144, 213, 84, 121, 120, 133, 132, - /* 240 */ 131, 115, 85, 98, 111, 99, 178, 209, 195, 73, - /* 250 */ 164, 224, 188, 184, 141, 171, 23, 171, 10, 110, - /* 260 */ 143, 226, 191, 140, 221, 28, 218, 64, 63, 125, - /* 270 */ 356, 356, 67, 66, 65, 62, 61, 60, 59, 58, - /* 280 */ 57, 183, 182, 181, 180, 179, 3, 170, 7, 122, - /* 290 */ 217, 185, 83, 189, 192, 213, 84, 121, 120, 133, - /* 300 */ 132, 131, 115, 85, 98, 111, 99, 178, 209, 195, - /* 310 */ 73, 74, 216, 188, 184, 225, 49, 48, 47, 46, - /* 320 */ 45, 44, 43, 42, 41, 40, 39, 38, 37, 5, - /* 330 */ 149, 64, 63, 146, 222, 356, 67, 66, 65, 62, - /* 340 */ 61, 60, 59, 58, 57, 183, 182, 181, 180, 179, - /* 350 */ 3, 116, 356, 145, 356, 189, 192, 213, 84, 121, - /* 360 */ 120, 133, 132, 131, 115, 85, 98, 111, 99, 178, - /* 370 */ 209, 195, 73, 113, 356, 188, 184, 189, 192, 213, - /* 380 */ 84, 121, 120, 133, 132, 131, 115, 85, 98, 111, - /* 390 */ 99, 178, 209, 195, 73, 356, 356, 188, 184, 223, - /* 400 */ 356, 356, 81, 80, 77, 220, 71, 356, 79, 138, - /* 410 */ 9, 356, 69, 189, 162, 213, 84, 121, 120, 133, - /* 420 */ 132, 131, 115, 85, 98, 111, 99, 178, 209, 195, - /* 430 */ 73, 356, 7, 188, 184, 185, 83, 356, 356, 167, - /* 440 */ 109, 189, 144, 213, 84, 121, 120, 133, 132, 131, - /* 450 */ 115, 85, 98, 111, 99, 178, 209, 195, 73, 356, - /* 460 */ 7, 188, 184, 185, 83, 356, 356, 356, 356, 147, - /* 470 */ 356, 356, 356, 356, 356, 64, 63, 356, 356, 356, - /* 480 */ 67, 66, 65, 62, 61, 60, 59, 58, 57, 183, - /* 490 */ 182, 181, 180, 179, 3, 356, 356, 356, 356, 356, - /* 500 */ 356, 356, 356, 64, 63, 356, 356, 167, 67, 66, - /* 510 */ 65, 62, 61, 60, 59, 58, 57, 183, 182, 181, - /* 520 */ 180, 179, 3, 189, 214, 213, 84, 121, 120, 133, - /* 530 */ 132, 131, 115, 85, 98, 111, 99, 178, 209, 195, - /* 540 */ 73, 356, 356, 188, 184, 189, 212, 213, 84, 121, - /* 550 */ 120, 133, 132, 131, 115, 85, 98, 111, 99, 178, - /* 560 */ 209, 195, 73, 168, 356, 188, 184, 189, 137, 213, - /* 570 */ 84, 121, 120, 133, 132, 131, 115, 85, 98, 111, - /* 580 */ 99, 178, 209, 195, 73, 356, 356, 188, 184, 356, - /* 590 */ 189, 211, 213, 84, 121, 120, 133, 132, 131, 115, - /* 600 */ 85, 98, 111, 99, 178, 209, 195, 73, 356, 356, - /* 610 */ 188, 184, 189, 172, 213, 84, 121, 120, 133, 132, - /* 620 */ 131, 115, 85, 98, 111, 99, 178, 209, 195, 73, - /* 630 */ 356, 356, 188, 184, 189, 163, 213, 84, 121, 120, - /* 640 */ 133, 132, 131, 115, 85, 98, 111, 99, 178, 209, - /* 650 */ 195, 73, 356, 356, 188, 184, 189, 161, 213, 84, - /* 660 */ 121, 120, 133, 132, 131, 115, 85, 98, 111, 99, - /* 670 */ 178, 209, 195, 73, 356, 356, 188, 184, 189, 160, - /* 680 */ 213, 84, 121, 120, 133, 132, 131, 115, 85, 98, - /* 690 */ 111, 99, 178, 209, 195, 73, 356, 356, 188, 184, - /* 700 */ 189, 159, 213, 84, 121, 120, 133, 132, 131, 115, - /* 710 */ 85, 98, 111, 99, 178, 209, 195, 73, 356, 356, - /* 720 */ 188, 184, 189, 158, 213, 84, 121, 120, 133, 132, - /* 730 */ 131, 115, 85, 98, 111, 99, 178, 209, 195, 73, - /* 740 */ 356, 356, 188, 184, 189, 157, 213, 84, 121, 120, - /* 750 */ 133, 132, 131, 115, 85, 98, 111, 99, 178, 209, - /* 760 */ 195, 73, 356, 356, 188, 184, 189, 156, 213, 84, - /* 770 */ 121, 120, 133, 132, 131, 115, 85, 98, 111, 99, - /* 780 */ 178, 209, 195, 73, 356, 356, 188, 184, 189, 155, - /* 790 */ 213, 84, 121, 120, 133, 132, 131, 115, 85, 98, - /* 800 */ 111, 99, 178, 209, 195, 73, 356, 356, 188, 184, - /* 810 */ 189, 154, 213, 84, 121, 120, 133, 132, 131, 115, - /* 820 */ 85, 98, 111, 99, 178, 209, 195, 73, 356, 356, - /* 830 */ 188, 184, 189, 153, 213, 84, 121, 120, 133, 132, - /* 840 */ 131, 115, 85, 98, 111, 99, 178, 209, 195, 73, - /* 850 */ 356, 356, 188, 184, 189, 152, 213, 84, 121, 120, - /* 860 */ 133, 132, 131, 115, 85, 98, 111, 99, 178, 209, - /* 870 */ 195, 73, 356, 356, 188, 184, 189, 151, 213, 84, - /* 880 */ 121, 120, 133, 132, 131, 115, 85, 98, 111, 99, - /* 890 */ 178, 209, 195, 73, 356, 356, 188, 184, 189, 175, - /* 900 */ 213, 84, 121, 120, 133, 132, 131, 115, 85, 98, - /* 910 */ 111, 99, 178, 209, 195, 73, 356, 356, 188, 184, - /* 920 */ 189, 169, 213, 84, 121, 120, 133, 132, 131, 115, - /* 930 */ 85, 98, 111, 99, 178, 209, 195, 73, 356, 189, - /* 940 */ 188, 184, 117, 356, 108, 133, 132, 131, 115, 85, - /* 950 */ 98, 111, 99, 178, 209, 195, 73, 356, 189, 188, - /* 960 */ 184, 117, 356, 356, 136, 132, 131, 115, 85, 98, - /* 970 */ 111, 99, 178, 209, 195, 73, 356, 356, 188, 184, - /* 980 */ 189, 356, 356, 117, 356, 356, 128, 132, 131, 115, - /* 990 */ 85, 98, 111, 99, 178, 209, 195, 73, 356, 356, - /* 1000 */ 188, 184, 189, 356, 356, 117, 356, 356, 356, 135, - /* 1010 */ 131, 115, 85, 98, 111, 99, 178, 209, 195, 73, - /* 1020 */ 356, 356, 188, 184, 356, 27, 22, 21, 20, 19, - /* 1030 */ 18, 17, 16, 15, 14, 13, 12, 189, 356, 356, - /* 1040 */ 117, 356, 356, 356, 356, 134, 115, 85, 98, 111, - /* 1050 */ 99, 178, 209, 195, 73, 356, 356, 188, 184, 356, - /* 1060 */ 189, 356, 356, 117, 356, 356, 197, 196, 356, 119, - /* 1070 */ 85, 98, 111, 99, 178, 209, 195, 73, 356, 189, - /* 1080 */ 188, 184, 117, 7, 356, 356, 185, 83, 356, 87, - /* 1090 */ 98, 111, 99, 178, 209, 195, 73, 356, 189, 188, - /* 1100 */ 184, 117, 356, 356, 356, 356, 356, 356, 86, 98, - /* 1110 */ 111, 99, 178, 209, 195, 73, 356, 189, 188, 184, - /* 1120 */ 117, 356, 356, 356, 356, 356, 356, 356, 104, 111, - /* 1130 */ 99, 178, 209, 195, 73, 356, 189, 188, 184, 117, - /* 1140 */ 183, 182, 181, 180, 179, 3, 356, 102, 111, 99, - /* 1150 */ 178, 209, 195, 73, 356, 189, 188, 184, 117, 356, - /* 1160 */ 356, 356, 356, 356, 356, 356, 100, 111, 99, 178, - /* 1170 */ 209, 195, 73, 356, 189, 188, 184, 117, 356, 356, - /* 1180 */ 356, 356, 356, 356, 356, 97, 111, 99, 178, 209, - /* 1190 */ 195, 73, 356, 189, 188, 184, 117, 356, 356, 356, - /* 1200 */ 356, 356, 356, 356, 96, 111, 99, 178, 209, 195, - /* 1210 */ 73, 356, 189, 188, 184, 117, 356, 356, 356, 356, - /* 1220 */ 356, 356, 356, 95, 111, 99, 178, 209, 195, 73, - /* 1230 */ 356, 189, 188, 184, 117, 356, 356, 356, 356, 356, - /* 1240 */ 356, 356, 94, 111, 99, 178, 209, 195, 73, 356, - /* 1250 */ 189, 188, 184, 117, 356, 356, 356, 356, 356, 356, - /* 1260 */ 356, 93, 111, 99, 178, 209, 195, 73, 356, 189, - /* 1270 */ 188, 184, 117, 356, 356, 356, 356, 356, 356, 356, - /* 1280 */ 92, 111, 99, 178, 209, 195, 73, 356, 189, 188, - /* 1290 */ 184, 117, 356, 356, 356, 356, 356, 356, 356, 91, - /* 1300 */ 111, 99, 178, 209, 195, 73, 356, 189, 188, 184, - /* 1310 */ 117, 356, 356, 356, 356, 356, 356, 356, 90, 111, - /* 1320 */ 99, 178, 209, 195, 73, 356, 189, 188, 184, 117, - /* 1330 */ 356, 356, 356, 356, 356, 356, 356, 89, 111, 99, - /* 1340 */ 178, 209, 195, 73, 356, 189, 188, 184, 117, 356, - /* 1350 */ 356, 356, 356, 356, 356, 356, 88, 111, 99, 178, - /* 1360 */ 209, 195, 73, 356, 189, 188, 184, 117, 356, 356, - /* 1370 */ 356, 356, 356, 356, 356, 356, 118, 99, 178, 209, - /* 1380 */ 195, 73, 356, 189, 188, 184, 117, 356, 356, 356, - /* 1390 */ 356, 356, 356, 356, 356, 114, 99, 178, 209, 195, - /* 1400 */ 73, 356, 189, 188, 184, 117, 356, 356, 356, 356, - /* 1410 */ 356, 356, 356, 356, 112, 99, 178, 209, 195, 73, - /* 1420 */ 356, 189, 188, 184, 117, 356, 356, 356, 356, 356, - /* 1430 */ 189, 356, 356, 117, 103, 178, 209, 195, 73, 356, - /* 1440 */ 356, 188, 184, 101, 178, 209, 195, 73, 356, 189, - /* 1450 */ 188, 184, 117, 356, 356, 356, 356, 356, 189, 356, - /* 1460 */ 356, 117, 356, 210, 209, 195, 73, 356, 189, 188, - /* 1470 */ 184, 117, 208, 209, 195, 73, 356, 189, 188, 184, - /* 1480 */ 117, 356, 207, 209, 195, 73, 356, 189, 188, 184, - /* 1490 */ 117, 206, 209, 195, 73, 356, 189, 188, 184, 117, - /* 1500 */ 356, 205, 209, 195, 73, 356, 189, 188, 184, 117, - /* 1510 */ 204, 209, 195, 73, 356, 189, 188, 184, 117, 356, - /* 1520 */ 203, 209, 195, 73, 356, 189, 188, 184, 117, 202, - /* 1530 */ 209, 195, 73, 356, 189, 188, 184, 117, 356, 201, - /* 1540 */ 209, 195, 73, 356, 356, 188, 184, 356, 200, 209, - /* 1550 */ 195, 73, 356, 189, 188, 184, 117, 356, 356, 356, - /* 1560 */ 356, 189, 356, 356, 117, 356, 356, 199, 209, 195, - /* 1570 */ 73, 356, 356, 188, 184, 198, 209, 195, 73, 356, - /* 1580 */ 189, 188, 184, 117, 356, 356, 356, 356, 189, 356, - /* 1590 */ 356, 117, 356, 356, 190, 209, 195, 73, 356, 356, - /* 1600 */ 188, 184, 186, 209, 195, 73, 356, 356, 188, 184, + /* 0 */ 2, 71, 53, 52, 51, 222, 1, 76, 80, 125, + /* 10 */ 4, 221, 70, 358, 77, 109, 28, 152, 221, 191, + /* 20 */ 194, 215, 88, 123, 122, 135, 134, 133, 117, 85, + /* 30 */ 100, 113, 101, 180, 211, 197, 74, 190, 186, 190, + /* 40 */ 186, 222, 72, 79, 80, 140, 9, 189, 70, 25, + /* 50 */ 65, 64, 217, 28, 28, 68, 67, 66, 63, 62, + /* 60 */ 61, 60, 59, 58, 185, 184, 183, 182, 181, 3, + /* 70 */ 76, 115, 6, 193, 221, 191, 194, 215, 88, 123, + /* 80 */ 122, 135, 134, 133, 117, 85, 100, 113, 101, 180, + /* 90 */ 211, 197, 74, 166, 107, 190, 186, 222, 1, 23, + /* 100 */ 80, 125, 4, 124, 70, 31, 30, 191, 194, 215, + /* 110 */ 88, 123, 122, 135, 134, 133, 117, 85, 100, 113, + /* 120 */ 101, 180, 211, 197, 74, 141, 129, 190, 186, 36, + /* 130 */ 35, 112, 69, 57, 56, 8, 32, 131, 55, 54, + /* 140 */ 34, 29, 65, 64, 176, 33, 73, 68, 67, 66, + /* 150 */ 63, 62, 61, 60, 59, 58, 185, 184, 183, 182, + /* 160 */ 181, 3, 7, 26, 128, 187, 84, 199, 198, 178, + /* 170 */ 191, 168, 215, 88, 123, 122, 135, 134, 133, 117, + /* 180 */ 85, 100, 113, 101, 180, 211, 197, 74, 144, 129, + /* 190 */ 190, 186, 11, 83, 82, 81, 78, 222, 72, 150, + /* 200 */ 80, 140, 9, 173, 70, 24, 65, 64, 228, 169, + /* 210 */ 167, 68, 67, 66, 63, 62, 61, 60, 59, 58, + /* 220 */ 185, 184, 183, 182, 181, 3, 179, 7, 196, 195, + /* 230 */ 187, 84, 108, 143, 178, 191, 146, 215, 88, 123, + /* 240 */ 122, 135, 134, 133, 117, 85, 100, 113, 101, 180, + /* 250 */ 211, 197, 74, 226, 227, 190, 186, 126, 173, 75, + /* 260 */ 173, 175, 132, 145, 142, 112, 170, 28, 5, 10, + /* 270 */ 223, 65, 64, 220, 127, 219, 68, 67, 66, 63, + /* 280 */ 62, 61, 60, 59, 58, 185, 184, 183, 182, 181, + /* 290 */ 3, 172, 7, 124, 218, 187, 84, 191, 194, 215, + /* 300 */ 88, 123, 122, 135, 134, 133, 117, 85, 100, 113, + /* 310 */ 101, 180, 211, 197, 74, 151, 224, 190, 186, 359, + /* 320 */ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, + /* 330 */ 40, 39, 38, 37, 359, 359, 65, 64, 148, 359, + /* 340 */ 359, 68, 67, 66, 63, 62, 61, 60, 59, 58, + /* 350 */ 185, 184, 183, 182, 181, 3, 118, 359, 147, 359, + /* 360 */ 191, 194, 215, 88, 123, 122, 135, 134, 133, 117, + /* 370 */ 85, 100, 113, 101, 180, 211, 197, 74, 115, 359, + /* 380 */ 190, 186, 191, 194, 215, 88, 123, 122, 135, 134, + /* 390 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74, + /* 400 */ 359, 359, 190, 186, 225, 359, 359, 82, 81, 78, + /* 410 */ 222, 72, 359, 80, 140, 9, 359, 70, 359, 191, + /* 420 */ 164, 215, 88, 123, 122, 135, 134, 133, 117, 85, + /* 430 */ 100, 113, 101, 180, 211, 197, 74, 359, 7, 190, + /* 440 */ 186, 187, 84, 359, 359, 169, 111, 191, 146, 215, + /* 450 */ 88, 123, 122, 135, 134, 133, 117, 85, 100, 113, + /* 460 */ 101, 180, 211, 197, 74, 359, 7, 190, 186, 187, + /* 470 */ 84, 359, 359, 359, 359, 149, 359, 359, 359, 359, + /* 480 */ 359, 359, 65, 64, 359, 359, 359, 68, 67, 66, + /* 490 */ 63, 62, 61, 60, 59, 58, 185, 184, 183, 182, + /* 500 */ 181, 3, 359, 359, 359, 359, 359, 359, 359, 359, + /* 510 */ 65, 64, 359, 359, 359, 68, 67, 66, 63, 62, + /* 520 */ 61, 60, 59, 58, 185, 184, 183, 182, 181, 3, + /* 530 */ 191, 216, 215, 88, 123, 122, 135, 134, 133, 117, + /* 540 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359, + /* 550 */ 190, 186, 191, 214, 215, 88, 123, 122, 135, 134, + /* 560 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74, + /* 570 */ 359, 359, 190, 186, 191, 139, 215, 88, 123, 122, + /* 580 */ 135, 134, 133, 117, 85, 100, 113, 101, 180, 211, + /* 590 */ 197, 74, 359, 359, 190, 186, 359, 359, 191, 213, + /* 600 */ 215, 88, 123, 122, 135, 134, 133, 117, 85, 100, + /* 610 */ 113, 101, 180, 211, 197, 74, 359, 359, 190, 186, + /* 620 */ 191, 174, 215, 88, 123, 122, 135, 134, 133, 117, + /* 630 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359, + /* 640 */ 190, 186, 191, 165, 215, 88, 123, 122, 135, 134, + /* 650 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74, + /* 660 */ 359, 359, 190, 186, 191, 163, 215, 88, 123, 122, + /* 670 */ 135, 134, 133, 117, 85, 100, 113, 101, 180, 211, + /* 680 */ 197, 74, 359, 359, 190, 186, 191, 162, 215, 88, + /* 690 */ 123, 122, 135, 134, 133, 117, 85, 100, 113, 101, + /* 700 */ 180, 211, 197, 74, 359, 359, 190, 186, 191, 161, + /* 710 */ 215, 88, 123, 122, 135, 134, 133, 117, 85, 100, + /* 720 */ 113, 101, 180, 211, 197, 74, 359, 359, 190, 186, + /* 730 */ 191, 160, 215, 88, 123, 122, 135, 134, 133, 117, + /* 740 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359, + /* 750 */ 190, 186, 191, 159, 215, 88, 123, 122, 135, 134, + /* 760 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74, + /* 770 */ 359, 359, 190, 186, 191, 158, 215, 88, 123, 122, + /* 780 */ 135, 134, 133, 117, 85, 100, 113, 101, 180, 211, + /* 790 */ 197, 74, 359, 359, 190, 186, 191, 157, 215, 88, + /* 800 */ 123, 122, 135, 134, 133, 117, 85, 100, 113, 101, + /* 810 */ 180, 211, 197, 74, 359, 359, 190, 186, 191, 156, + /* 820 */ 215, 88, 123, 122, 135, 134, 133, 117, 85, 100, + /* 830 */ 113, 101, 180, 211, 197, 74, 359, 359, 190, 186, + /* 840 */ 191, 155, 215, 88, 123, 122, 135, 134, 133, 117, + /* 850 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359, + /* 860 */ 190, 186, 191, 154, 215, 88, 123, 122, 135, 134, + /* 870 */ 133, 117, 85, 100, 113, 101, 180, 211, 197, 74, + /* 880 */ 359, 359, 190, 186, 191, 153, 215, 88, 123, 122, + /* 890 */ 135, 134, 133, 117, 85, 100, 113, 101, 180, 211, + /* 900 */ 197, 74, 359, 359, 190, 186, 191, 177, 215, 88, + /* 910 */ 123, 122, 135, 134, 133, 117, 85, 100, 113, 101, + /* 920 */ 180, 211, 197, 74, 359, 359, 190, 186, 191, 171, + /* 930 */ 215, 88, 123, 122, 135, 134, 133, 117, 85, 100, + /* 940 */ 113, 101, 180, 211, 197, 74, 359, 191, 190, 186, + /* 950 */ 119, 359, 110, 135, 134, 133, 117, 85, 100, 113, + /* 960 */ 101, 180, 211, 197, 74, 359, 191, 190, 186, 119, + /* 970 */ 359, 359, 138, 134, 133, 117, 85, 100, 113, 101, + /* 980 */ 180, 211, 197, 74, 359, 359, 190, 186, 191, 359, + /* 990 */ 359, 119, 359, 359, 130, 134, 133, 117, 85, 100, + /* 1000 */ 113, 101, 180, 211, 197, 74, 359, 359, 190, 186, + /* 1010 */ 191, 359, 359, 119, 359, 359, 359, 137, 133, 117, + /* 1020 */ 85, 100, 113, 101, 180, 211, 197, 74, 359, 359, + /* 1030 */ 190, 186, 359, 27, 22, 21, 20, 19, 18, 17, + /* 1040 */ 16, 15, 14, 13, 12, 191, 359, 359, 119, 359, + /* 1050 */ 359, 359, 359, 136, 117, 85, 100, 113, 101, 180, + /* 1060 */ 211, 197, 74, 359, 359, 190, 186, 359, 359, 191, + /* 1070 */ 359, 359, 119, 359, 359, 199, 198, 359, 121, 85, + /* 1080 */ 100, 113, 101, 180, 211, 197, 74, 359, 191, 190, + /* 1090 */ 186, 119, 7, 359, 359, 187, 84, 359, 87, 100, + /* 1100 */ 113, 101, 180, 211, 197, 74, 359, 191, 190, 186, + /* 1110 */ 119, 359, 359, 359, 359, 359, 359, 86, 100, 113, + /* 1120 */ 101, 180, 211, 197, 74, 359, 191, 190, 186, 119, + /* 1130 */ 359, 359, 359, 359, 359, 359, 359, 106, 113, 101, + /* 1140 */ 180, 211, 197, 74, 359, 191, 190, 186, 119, 359, + /* 1150 */ 185, 184, 183, 182, 181, 3, 104, 113, 101, 180, + /* 1160 */ 211, 197, 74, 359, 191, 190, 186, 119, 359, 359, + /* 1170 */ 359, 359, 359, 359, 359, 102, 113, 101, 180, 211, + /* 1180 */ 197, 74, 359, 191, 190, 186, 119, 359, 359, 359, + /* 1190 */ 359, 359, 359, 359, 99, 113, 101, 180, 211, 197, + /* 1200 */ 74, 359, 191, 190, 186, 119, 359, 359, 359, 359, + /* 1210 */ 359, 359, 359, 98, 113, 101, 180, 211, 197, 74, + /* 1220 */ 359, 191, 190, 186, 119, 359, 359, 359, 359, 359, + /* 1230 */ 359, 359, 97, 113, 101, 180, 211, 197, 74, 359, + /* 1240 */ 191, 190, 186, 119, 359, 359, 359, 359, 359, 359, + /* 1250 */ 359, 96, 113, 101, 180, 211, 197, 74, 359, 191, + /* 1260 */ 190, 186, 119, 359, 359, 359, 359, 359, 359, 359, + /* 1270 */ 95, 113, 101, 180, 211, 197, 74, 359, 191, 190, + /* 1280 */ 186, 119, 359, 359, 359, 359, 359, 359, 359, 94, + /* 1290 */ 113, 101, 180, 211, 197, 74, 359, 191, 190, 186, + /* 1300 */ 119, 359, 359, 359, 359, 359, 359, 359, 93, 113, + /* 1310 */ 101, 180, 211, 197, 74, 359, 191, 190, 186, 119, + /* 1320 */ 359, 359, 359, 359, 359, 359, 359, 92, 113, 101, + /* 1330 */ 180, 211, 197, 74, 359, 191, 190, 186, 119, 359, + /* 1340 */ 359, 359, 359, 359, 359, 359, 91, 113, 101, 180, + /* 1350 */ 211, 197, 74, 359, 191, 190, 186, 119, 359, 359, + /* 1360 */ 359, 359, 359, 359, 359, 90, 113, 101, 180, 211, + /* 1370 */ 197, 74, 359, 191, 190, 186, 119, 359, 359, 359, + /* 1380 */ 359, 359, 359, 359, 89, 113, 101, 180, 211, 197, + /* 1390 */ 74, 359, 191, 190, 186, 119, 359, 359, 359, 359, + /* 1400 */ 359, 359, 359, 359, 120, 101, 180, 211, 197, 74, + /* 1410 */ 359, 191, 190, 186, 119, 359, 359, 359, 359, 359, + /* 1420 */ 359, 359, 359, 116, 101, 180, 211, 197, 74, 359, + /* 1430 */ 191, 190, 186, 119, 359, 359, 359, 359, 359, 359, + /* 1440 */ 359, 359, 114, 101, 180, 211, 197, 74, 359, 191, + /* 1450 */ 190, 186, 119, 359, 359, 359, 359, 359, 191, 359, + /* 1460 */ 359, 119, 105, 180, 211, 197, 74, 359, 359, 190, + /* 1470 */ 186, 103, 180, 211, 197, 74, 359, 191, 190, 186, + /* 1480 */ 119, 359, 359, 359, 359, 359, 359, 191, 359, 359, + /* 1490 */ 119, 212, 211, 197, 74, 359, 191, 190, 186, 119, + /* 1500 */ 359, 210, 211, 197, 74, 359, 191, 190, 186, 119, + /* 1510 */ 209, 211, 197, 74, 359, 191, 190, 186, 119, 359, + /* 1520 */ 208, 211, 197, 74, 359, 191, 190, 186, 119, 207, + /* 1530 */ 211, 197, 74, 359, 191, 190, 186, 119, 359, 206, + /* 1540 */ 211, 197, 74, 359, 191, 190, 186, 119, 205, 211, + /* 1550 */ 197, 74, 359, 191, 190, 186, 119, 359, 204, 211, + /* 1560 */ 197, 74, 359, 191, 190, 186, 119, 203, 211, 197, + /* 1570 */ 74, 359, 359, 190, 186, 359, 359, 202, 211, 197, + /* 1580 */ 74, 359, 191, 190, 186, 119, 359, 359, 359, 359, + /* 1590 */ 191, 359, 359, 119, 359, 359, 201, 211, 197, 74, + /* 1600 */ 359, 359, 190, 186, 200, 211, 197, 74, 359, 191, + /* 1610 */ 190, 186, 119, 359, 359, 359, 359, 191, 359, 359, + /* 1620 */ 119, 359, 359, 192, 211, 197, 74, 359, 359, 190, + /* 1630 */ 186, 188, 211, 197, 74, 359, 359, 190, 186, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 1, 2, 47, 48, 49, 6, 7, 76, 9, 10, - /* 10 */ 11, 80, 13, 75, 76, 77, 9, 81, 80, 81, - /* 20 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - /* 30 */ 92, 93, 94, 95, 96, 97, 98, 101, 102, 101, - /* 40 */ 102, 6, 7, 28, 9, 10, 11, 29, 13, 50, - /* 50 */ 51, 12, 30, 14, 55, 56, 57, 58, 59, 60, - /* 60 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 76, - /* 70 */ 77, 31, 7, 80, 81, 82, 83, 84, 85, 86, + /* 0 */ 1, 2, 48, 49, 50, 6, 7, 77, 9, 10, + /* 10 */ 11, 81, 13, 76, 77, 78, 14, 82, 81, 82, + /* 20 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 30 */ 93, 94, 95, 96, 97, 98, 99, 102, 103, 102, + /* 40 */ 103, 6, 7, 9, 9, 10, 11, 8, 13, 28, + /* 50 */ 51, 52, 12, 14, 14, 56, 57, 58, 59, 60, + /* 60 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 70 */ 77, 78, 7, 71, 81, 82, 83, 84, 85, 86, /* 80 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - /* 90 */ 97, 98, 8, 79, 101, 102, 6, 7, 14, 9, - /* 100 */ 10, 11, 77, 13, 3, 4, 81, 82, 83, 84, + /* 90 */ 97, 98, 99, 8, 80, 102, 103, 6, 7, 14, + /* 100 */ 9, 10, 11, 78, 13, 3, 4, 82, 83, 84, /* 110 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - /* 120 */ 95, 96, 97, 98, 110, 111, 101, 102, 32, 33, - /* 130 */ 105, 52, 53, 54, 69, 28, 71, 56, 57, 5, - /* 140 */ 50, 51, 50, 51, 39, 55, 56, 57, 58, 59, - /* 150 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - /* 160 */ 7, 27, 10, 10, 11, 110, 111, 14, 81, 82, - /* 170 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 180 */ 93, 94, 95, 96, 97, 98, 106, 107, 101, 102, - /* 190 */ 103, 104, 3, 4, 5, 6, 7, 8, 9, 10, - /* 200 */ 11, 10, 13, 50, 51, 12, 14, 14, 55, 56, - /* 210 */ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - /* 220 */ 67, 68, 69, 70, 7, 99, 100, 10, 11, 78, - /* 230 */ 52, 14, 81, 82, 83, 84, 85, 86, 87, 88, - /* 240 */ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - /* 250 */ 8, 0, 101, 102, 64, 64, 14, 66, 103, 105, - /* 260 */ 109, 0, 70, 66, 80, 14, 80, 50, 51, 10, - /* 270 */ 112, 112, 55, 56, 57, 58, 59, 60, 61, 62, - /* 280 */ 63, 64, 65, 66, 67, 68, 69, 70, 7, 77, - /* 290 */ 80, 10, 11, 81, 82, 83, 84, 85, 86, 87, - /* 300 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - /* 310 */ 98, 50, 80, 101, 102, 0, 34, 35, 36, 37, - /* 320 */ 38, 39, 40, 41, 42, 43, 44, 45, 46, 14, - /* 330 */ 80, 50, 51, 52, 80, 112, 55, 56, 57, 58, - /* 340 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - /* 350 */ 69, 77, 112, 72, 112, 81, 82, 83, 84, 85, - /* 360 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - /* 370 */ 96, 97, 98, 77, 112, 101, 102, 81, 82, 83, - /* 380 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - /* 390 */ 94, 95, 96, 97, 98, 112, 112, 101, 102, 0, - /* 400 */ 112, 112, 3, 4, 5, 6, 7, 112, 9, 10, - /* 410 */ 11, 112, 13, 81, 82, 83, 84, 85, 86, 87, - /* 420 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - /* 430 */ 98, 112, 7, 101, 102, 10, 11, 112, 112, 14, - /* 440 */ 108, 81, 82, 83, 84, 85, 86, 87, 88, 89, - /* 450 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 112, - /* 460 */ 7, 101, 102, 10, 11, 112, 112, 112, 112, 109, - /* 470 */ 112, 112, 112, 112, 112, 50, 51, 112, 112, 112, - /* 480 */ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - /* 490 */ 65, 66, 67, 68, 69, 112, 112, 112, 112, 112, - /* 500 */ 112, 112, 112, 50, 51, 112, 112, 14, 55, 56, - /* 510 */ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - /* 520 */ 67, 68, 69, 81, 82, 83, 84, 85, 86, 87, - /* 530 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - /* 540 */ 98, 112, 112, 101, 102, 81, 82, 83, 84, 85, - /* 550 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - /* 560 */ 96, 97, 98, 70, 112, 101, 102, 81, 82, 83, - /* 570 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - /* 580 */ 94, 95, 96, 97, 98, 112, 112, 101, 102, 112, - /* 590 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 600 */ 91, 92, 93, 94, 95, 96, 97, 98, 112, 112, - /* 610 */ 101, 102, 81, 82, 83, 84, 85, 86, 87, 88, - /* 620 */ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - /* 630 */ 112, 112, 101, 102, 81, 82, 83, 84, 85, 86, - /* 640 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - /* 650 */ 97, 98, 112, 112, 101, 102, 81, 82, 83, 84, - /* 660 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - /* 670 */ 95, 96, 97, 98, 112, 112, 101, 102, 81, 82, - /* 680 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 690 */ 93, 94, 95, 96, 97, 98, 112, 112, 101, 102, - /* 700 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 710 */ 91, 92, 93, 94, 95, 96, 97, 98, 112, 112, - /* 720 */ 101, 102, 81, 82, 83, 84, 85, 86, 87, 88, - /* 730 */ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - /* 740 */ 112, 112, 101, 102, 81, 82, 83, 84, 85, 86, - /* 750 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - /* 760 */ 97, 98, 112, 112, 101, 102, 81, 82, 83, 84, - /* 770 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - /* 780 */ 95, 96, 97, 98, 112, 112, 101, 102, 81, 82, - /* 790 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 800 */ 93, 94, 95, 96, 97, 98, 112, 112, 101, 102, - /* 810 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 820 */ 91, 92, 93, 94, 95, 96, 97, 98, 112, 112, - /* 830 */ 101, 102, 81, 82, 83, 84, 85, 86, 87, 88, - /* 840 */ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - /* 850 */ 112, 112, 101, 102, 81, 82, 83, 84, 85, 86, - /* 860 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - /* 870 */ 97, 98, 112, 112, 101, 102, 81, 82, 83, 84, - /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - /* 890 */ 95, 96, 97, 98, 112, 112, 101, 102, 81, 82, - /* 900 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 910 */ 93, 94, 95, 96, 97, 98, 112, 112, 101, 102, - /* 920 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 930 */ 91, 92, 93, 94, 95, 96, 97, 98, 112, 81, - /* 940 */ 101, 102, 84, 112, 86, 87, 88, 89, 90, 91, - /* 950 */ 92, 93, 94, 95, 96, 97, 98, 112, 81, 101, - /* 960 */ 102, 84, 112, 112, 87, 88, 89, 90, 91, 92, - /* 970 */ 93, 94, 95, 96, 97, 98, 112, 112, 101, 102, - /* 980 */ 81, 112, 112, 84, 112, 112, 87, 88, 89, 90, - /* 990 */ 91, 92, 93, 94, 95, 96, 97, 98, 112, 112, - /* 1000 */ 101, 102, 81, 112, 112, 84, 112, 112, 112, 88, - /* 1010 */ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - /* 1020 */ 112, 112, 101, 102, 112, 15, 16, 17, 18, 19, - /* 1030 */ 20, 21, 22, 23, 24, 25, 26, 81, 112, 112, - /* 1040 */ 84, 112, 112, 112, 112, 89, 90, 91, 92, 93, - /* 1050 */ 94, 95, 96, 97, 98, 112, 112, 101, 102, 112, - /* 1060 */ 81, 112, 112, 84, 112, 112, 56, 57, 112, 90, - /* 1070 */ 91, 92, 93, 94, 95, 96, 97, 98, 112, 81, - /* 1080 */ 101, 102, 84, 7, 112, 112, 10, 11, 112, 91, - /* 1090 */ 92, 93, 94, 95, 96, 97, 98, 112, 81, 101, - /* 1100 */ 102, 84, 112, 112, 112, 112, 112, 112, 91, 92, - /* 1110 */ 93, 94, 95, 96, 97, 98, 112, 81, 101, 102, - /* 1120 */ 84, 112, 112, 112, 112, 112, 112, 112, 92, 93, - /* 1130 */ 94, 95, 96, 97, 98, 112, 81, 101, 102, 84, - /* 1140 */ 64, 65, 66, 67, 68, 69, 112, 92, 93, 94, - /* 1150 */ 95, 96, 97, 98, 112, 81, 101, 102, 84, 112, - /* 1160 */ 112, 112, 112, 112, 112, 112, 92, 93, 94, 95, - /* 1170 */ 96, 97, 98, 112, 81, 101, 102, 84, 112, 112, - /* 1180 */ 112, 112, 112, 112, 112, 92, 93, 94, 95, 96, - /* 1190 */ 97, 98, 112, 81, 101, 102, 84, 112, 112, 112, - /* 1200 */ 112, 112, 112, 112, 92, 93, 94, 95, 96, 97, - /* 1210 */ 98, 112, 81, 101, 102, 84, 112, 112, 112, 112, - /* 1220 */ 112, 112, 112, 92, 93, 94, 95, 96, 97, 98, - /* 1230 */ 112, 81, 101, 102, 84, 112, 112, 112, 112, 112, - /* 1240 */ 112, 112, 92, 93, 94, 95, 96, 97, 98, 112, - /* 1250 */ 81, 101, 102, 84, 112, 112, 112, 112, 112, 112, - /* 1260 */ 112, 92, 93, 94, 95, 96, 97, 98, 112, 81, - /* 1270 */ 101, 102, 84, 112, 112, 112, 112, 112, 112, 112, - /* 1280 */ 92, 93, 94, 95, 96, 97, 98, 112, 81, 101, - /* 1290 */ 102, 84, 112, 112, 112, 112, 112, 112, 112, 92, - /* 1300 */ 93, 94, 95, 96, 97, 98, 112, 81, 101, 102, - /* 1310 */ 84, 112, 112, 112, 112, 112, 112, 112, 92, 93, - /* 1320 */ 94, 95, 96, 97, 98, 112, 81, 101, 102, 84, - /* 1330 */ 112, 112, 112, 112, 112, 112, 112, 92, 93, 94, - /* 1340 */ 95, 96, 97, 98, 112, 81, 101, 102, 84, 112, - /* 1350 */ 112, 112, 112, 112, 112, 112, 92, 93, 94, 95, - /* 1360 */ 96, 97, 98, 112, 81, 101, 102, 84, 112, 112, - /* 1370 */ 112, 112, 112, 112, 112, 112, 93, 94, 95, 96, - /* 1380 */ 97, 98, 112, 81, 101, 102, 84, 112, 112, 112, - /* 1390 */ 112, 112, 112, 112, 112, 93, 94, 95, 96, 97, - /* 1400 */ 98, 112, 81, 101, 102, 84, 112, 112, 112, 112, - /* 1410 */ 112, 112, 112, 112, 93, 94, 95, 96, 97, 98, - /* 1420 */ 112, 81, 101, 102, 84, 112, 112, 112, 112, 112, - /* 1430 */ 81, 112, 112, 84, 94, 95, 96, 97, 98, 112, - /* 1440 */ 112, 101, 102, 94, 95, 96, 97, 98, 112, 81, - /* 1450 */ 101, 102, 84, 112, 112, 112, 112, 112, 81, 112, - /* 1460 */ 112, 84, 112, 95, 96, 97, 98, 112, 81, 101, - /* 1470 */ 102, 84, 95, 96, 97, 98, 112, 81, 101, 102, - /* 1480 */ 84, 112, 95, 96, 97, 98, 112, 81, 101, 102, - /* 1490 */ 84, 95, 96, 97, 98, 112, 81, 101, 102, 84, - /* 1500 */ 112, 95, 96, 97, 98, 112, 81, 101, 102, 84, - /* 1510 */ 95, 96, 97, 98, 112, 81, 101, 102, 84, 112, - /* 1520 */ 95, 96, 97, 98, 112, 81, 101, 102, 84, 95, - /* 1530 */ 96, 97, 98, 112, 81, 101, 102, 84, 112, 95, - /* 1540 */ 96, 97, 98, 112, 112, 101, 102, 112, 95, 96, - /* 1550 */ 97, 98, 112, 81, 101, 102, 84, 112, 112, 112, - /* 1560 */ 112, 81, 112, 112, 84, 112, 112, 95, 96, 97, - /* 1570 */ 98, 112, 112, 101, 102, 95, 96, 97, 98, 112, - /* 1580 */ 81, 101, 102, 84, 112, 112, 112, 112, 81, 112, - /* 1590 */ 112, 84, 112, 112, 95, 96, 97, 98, 112, 112, - /* 1600 */ 101, 102, 95, 96, 97, 98, 112, 112, 101, 102, + /* 120 */ 95, 96, 97, 98, 99, 111, 112, 102, 103, 32, + /* 130 */ 33, 106, 53, 54, 55, 70, 29, 72, 51, 52, + /* 140 */ 31, 5, 51, 52, 12, 30, 14, 56, 57, 58, + /* 150 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + /* 160 */ 69, 70, 7, 27, 53, 10, 11, 57, 58, 14, + /* 170 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + /* 180 */ 92, 93, 94, 95, 96, 97, 98, 99, 111, 112, + /* 190 */ 102, 103, 104, 105, 3, 4, 5, 6, 7, 8, + /* 200 */ 9, 10, 11, 10, 13, 28, 51, 52, 0, 14, + /* 210 */ 10, 56, 57, 58, 59, 60, 61, 62, 63, 64, + /* 220 */ 65, 66, 67, 68, 69, 70, 71, 7, 100, 101, + /* 230 */ 10, 11, 79, 65, 14, 82, 83, 84, 85, 86, + /* 240 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + /* 250 */ 97, 98, 99, 0, 0, 102, 103, 39, 65, 51, + /* 260 */ 67, 107, 108, 110, 67, 106, 71, 14, 14, 104, + /* 270 */ 81, 51, 52, 81, 10, 81, 56, 57, 58, 59, + /* 280 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + /* 290 */ 70, 71, 7, 78, 81, 10, 11, 82, 83, 84, + /* 300 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + /* 310 */ 95, 96, 97, 98, 99, 81, 81, 102, 103, 113, + /* 320 */ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + /* 330 */ 44, 45, 46, 47, 113, 113, 51, 52, 53, 113, + /* 340 */ 113, 56, 57, 58, 59, 60, 61, 62, 63, 64, + /* 350 */ 65, 66, 67, 68, 69, 70, 78, 113, 73, 113, + /* 360 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + /* 370 */ 92, 93, 94, 95, 96, 97, 98, 99, 78, 113, + /* 380 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89, + /* 390 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + /* 400 */ 113, 113, 102, 103, 0, 113, 113, 3, 4, 5, + /* 410 */ 6, 7, 113, 9, 10, 11, 113, 13, 113, 82, + /* 420 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 430 */ 93, 94, 95, 96, 97, 98, 99, 113, 7, 102, + /* 440 */ 103, 10, 11, 113, 113, 14, 109, 82, 83, 84, + /* 450 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + /* 460 */ 95, 96, 97, 98, 99, 113, 7, 102, 103, 10, + /* 470 */ 11, 113, 113, 113, 113, 110, 113, 113, 113, 113, + /* 480 */ 113, 113, 51, 52, 113, 113, 113, 56, 57, 58, + /* 490 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + /* 500 */ 69, 70, 113, 113, 113, 113, 113, 113, 113, 113, + /* 510 */ 51, 52, 113, 113, 113, 56, 57, 58, 59, 60, + /* 520 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 530 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + /* 540 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113, + /* 550 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89, + /* 560 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + /* 570 */ 113, 113, 102, 103, 82, 83, 84, 85, 86, 87, + /* 580 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + /* 590 */ 98, 99, 113, 113, 102, 103, 113, 113, 82, 83, + /* 600 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + /* 610 */ 94, 95, 96, 97, 98, 99, 113, 113, 102, 103, + /* 620 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + /* 630 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113, + /* 640 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89, + /* 650 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + /* 660 */ 113, 113, 102, 103, 82, 83, 84, 85, 86, 87, + /* 670 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + /* 680 */ 98, 99, 113, 113, 102, 103, 82, 83, 84, 85, + /* 690 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + /* 700 */ 96, 97, 98, 99, 113, 113, 102, 103, 82, 83, + /* 710 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + /* 720 */ 94, 95, 96, 97, 98, 99, 113, 113, 102, 103, + /* 730 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + /* 740 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113, + /* 750 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89, + /* 760 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + /* 770 */ 113, 113, 102, 103, 82, 83, 84, 85, 86, 87, + /* 780 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + /* 790 */ 98, 99, 113, 113, 102, 103, 82, 83, 84, 85, + /* 800 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + /* 810 */ 96, 97, 98, 99, 113, 113, 102, 103, 82, 83, + /* 820 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + /* 830 */ 94, 95, 96, 97, 98, 99, 113, 113, 102, 103, + /* 840 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + /* 850 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113, + /* 860 */ 102, 103, 82, 83, 84, 85, 86, 87, 88, 89, + /* 870 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + /* 880 */ 113, 113, 102, 103, 82, 83, 84, 85, 86, 87, + /* 890 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + /* 900 */ 98, 99, 113, 113, 102, 103, 82, 83, 84, 85, + /* 910 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + /* 920 */ 96, 97, 98, 99, 113, 113, 102, 103, 82, 83, + /* 930 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + /* 940 */ 94, 95, 96, 97, 98, 99, 113, 82, 102, 103, + /* 950 */ 85, 113, 87, 88, 89, 90, 91, 92, 93, 94, + /* 960 */ 95, 96, 97, 98, 99, 113, 82, 102, 103, 85, + /* 970 */ 113, 113, 88, 89, 90, 91, 92, 93, 94, 95, + /* 980 */ 96, 97, 98, 99, 113, 113, 102, 103, 82, 113, + /* 990 */ 113, 85, 113, 113, 88, 89, 90, 91, 92, 93, + /* 1000 */ 94, 95, 96, 97, 98, 99, 113, 113, 102, 103, + /* 1010 */ 82, 113, 113, 85, 113, 113, 113, 89, 90, 91, + /* 1020 */ 92, 93, 94, 95, 96, 97, 98, 99, 113, 113, + /* 1030 */ 102, 103, 113, 15, 16, 17, 18, 19, 20, 21, + /* 1040 */ 22, 23, 24, 25, 26, 82, 113, 113, 85, 113, + /* 1050 */ 113, 113, 113, 90, 91, 92, 93, 94, 95, 96, + /* 1060 */ 97, 98, 99, 113, 113, 102, 103, 113, 113, 82, + /* 1070 */ 113, 113, 85, 113, 113, 57, 58, 113, 91, 92, + /* 1080 */ 93, 94, 95, 96, 97, 98, 99, 113, 82, 102, + /* 1090 */ 103, 85, 7, 113, 113, 10, 11, 113, 92, 93, + /* 1100 */ 94, 95, 96, 97, 98, 99, 113, 82, 102, 103, + /* 1110 */ 85, 113, 113, 113, 113, 113, 113, 92, 93, 94, + /* 1120 */ 95, 96, 97, 98, 99, 113, 82, 102, 103, 85, + /* 1130 */ 113, 113, 113, 113, 113, 113, 113, 93, 94, 95, + /* 1140 */ 96, 97, 98, 99, 113, 82, 102, 103, 85, 113, + /* 1150 */ 65, 66, 67, 68, 69, 70, 93, 94, 95, 96, + /* 1160 */ 97, 98, 99, 113, 82, 102, 103, 85, 113, 113, + /* 1170 */ 113, 113, 113, 113, 113, 93, 94, 95, 96, 97, + /* 1180 */ 98, 99, 113, 82, 102, 103, 85, 113, 113, 113, + /* 1190 */ 113, 113, 113, 113, 93, 94, 95, 96, 97, 98, + /* 1200 */ 99, 113, 82, 102, 103, 85, 113, 113, 113, 113, + /* 1210 */ 113, 113, 113, 93, 94, 95, 96, 97, 98, 99, + /* 1220 */ 113, 82, 102, 103, 85, 113, 113, 113, 113, 113, + /* 1230 */ 113, 113, 93, 94, 95, 96, 97, 98, 99, 113, + /* 1240 */ 82, 102, 103, 85, 113, 113, 113, 113, 113, 113, + /* 1250 */ 113, 93, 94, 95, 96, 97, 98, 99, 113, 82, + /* 1260 */ 102, 103, 85, 113, 113, 113, 113, 113, 113, 113, + /* 1270 */ 93, 94, 95, 96, 97, 98, 99, 113, 82, 102, + /* 1280 */ 103, 85, 113, 113, 113, 113, 113, 113, 113, 93, + /* 1290 */ 94, 95, 96, 97, 98, 99, 113, 82, 102, 103, + /* 1300 */ 85, 113, 113, 113, 113, 113, 113, 113, 93, 94, + /* 1310 */ 95, 96, 97, 98, 99, 113, 82, 102, 103, 85, + /* 1320 */ 113, 113, 113, 113, 113, 113, 113, 93, 94, 95, + /* 1330 */ 96, 97, 98, 99, 113, 82, 102, 103, 85, 113, + /* 1340 */ 113, 113, 113, 113, 113, 113, 93, 94, 95, 96, + /* 1350 */ 97, 98, 99, 113, 82, 102, 103, 85, 113, 113, + /* 1360 */ 113, 113, 113, 113, 113, 93, 94, 95, 96, 97, + /* 1370 */ 98, 99, 113, 82, 102, 103, 85, 113, 113, 113, + /* 1380 */ 113, 113, 113, 113, 93, 94, 95, 96, 97, 98, + /* 1390 */ 99, 113, 82, 102, 103, 85, 113, 113, 113, 113, + /* 1400 */ 113, 113, 113, 113, 94, 95, 96, 97, 98, 99, + /* 1410 */ 113, 82, 102, 103, 85, 113, 113, 113, 113, 113, + /* 1420 */ 113, 113, 113, 94, 95, 96, 97, 98, 99, 113, + /* 1430 */ 82, 102, 103, 85, 113, 113, 113, 113, 113, 113, + /* 1440 */ 113, 113, 94, 95, 96, 97, 98, 99, 113, 82, + /* 1450 */ 102, 103, 85, 113, 113, 113, 113, 113, 82, 113, + /* 1460 */ 113, 85, 95, 96, 97, 98, 99, 113, 113, 102, + /* 1470 */ 103, 95, 96, 97, 98, 99, 113, 82, 102, 103, + /* 1480 */ 85, 113, 113, 113, 113, 113, 113, 82, 113, 113, + /* 1490 */ 85, 96, 97, 98, 99, 113, 82, 102, 103, 85, + /* 1500 */ 113, 96, 97, 98, 99, 113, 82, 102, 103, 85, + /* 1510 */ 96, 97, 98, 99, 113, 82, 102, 103, 85, 113, + /* 1520 */ 96, 97, 98, 99, 113, 82, 102, 103, 85, 96, + /* 1530 */ 97, 98, 99, 113, 82, 102, 103, 85, 113, 96, + /* 1540 */ 97, 98, 99, 113, 82, 102, 103, 85, 96, 97, + /* 1550 */ 98, 99, 113, 82, 102, 103, 85, 113, 96, 97, + /* 1560 */ 98, 99, 113, 82, 102, 103, 85, 96, 97, 98, + /* 1570 */ 99, 113, 113, 102, 103, 113, 113, 96, 97, 98, + /* 1580 */ 99, 113, 82, 102, 103, 85, 113, 113, 113, 113, + /* 1590 */ 82, 113, 113, 85, 113, 113, 96, 97, 98, 99, + /* 1600 */ 113, 113, 102, 103, 96, 97, 98, 99, 113, 82, + /* 1610 */ 102, 103, 85, 113, 113, 113, 113, 82, 113, 113, + /* 1620 */ 85, 113, 113, 96, 97, 98, 99, 113, 113, 102, + /* 1630 */ 103, 96, 97, 98, 99, 113, 113, 102, 103, }; -#define YY_SHIFT_USE_DFLT (-46) -#define YY_SHIFT_COUNT (138) -#define YY_SHIFT_MIN (-45) -#define YY_SHIFT_MAX (1076) +#define YY_SHIFT_USE_DFLT (-47) +#define YY_SHIFT_COUNT (140) +#define YY_SHIFT_MIN (-46) +#define YY_SHIFT_MAX (1085) static const short yy_shift_ofst[] = { - /* 0 */ -1, 90, 281, 425, 453, 281, 453, 453, 453, 453, - /* 10 */ 217, 153, 453, 453, 453, 453, 453, 453, 453, 453, - /* 20 */ 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, - /* 30 */ 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, - /* 40 */ 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, - /* 50 */ 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, - /* 60 */ 453, 453, 453, 453, 453, 453, 453, 453, 453, 1076, - /* 70 */ 259, 35, 191, 65, 259, 189, 399, 35, 35, 35, - /* 80 */ 35, 35, 493, -46, 1010, 282, 282, 282, -45, -45, - /* 90 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, 79, - /* 100 */ -45, 79, -45, 79, -45, 261, 315, 251, 101, 242, - /* 110 */ 193, 92, 92, 84, 92, 96, 192, 81, 92, 96, - /* 120 */ 101, 134, 39, 7, 197, 105, 190, 178, 18, 152, - /* 130 */ 107, 40, 22, 18, 40, 22, 18, 15, 7, + /* 0 */ -1, 91, 285, 431, 459, 285, 459, 459, 459, 459, + /* 10 */ 220, 155, 459, 459, 459, 459, 459, 459, 459, 459, + /* 20 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + /* 30 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + /* 40 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + /* 50 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + /* 60 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + /* 70 */ 1085, 264, 35, 193, 65, 264, 191, 404, 35, 35, + /* 80 */ 35, 35, 35, 195, -47, 286, 286, 286, 1018, -46, + /* 90 */ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + /* 100 */ -46, 79, -46, 79, -46, 79, -46, 208, 254, 253, + /* 110 */ 102, 85, 132, 87, 87, 39, 87, 97, 2, 110, + /* 120 */ 87, 97, 102, 136, 40, 34, 197, 218, 168, 111, + /* 130 */ 107, 200, 177, 109, 115, 107, 109, 115, 107, 21, + /* 140 */ 34, }; -#define YY_REDUCE_USE_DFLT (-70) -#define YY_REDUCE_COUNT (83) -#define YY_REDUCE_MIN (-69) -#define YY_REDUCE_MAX (1507) +#define YY_REDUCE_USE_DFLT (-71) +#define YY_REDUCE_COUNT (84) +#define YY_REDUCE_MIN (-70) +#define YY_REDUCE_MAX (1535) static const short yy_reduce_ofst[] = { - /* 0 */ -62, -7, 151, 87, 25, 360, 332, 296, 274, 212, - /* 10 */ 839, 817, 795, 773, 751, 729, 707, 685, 663, 641, - /* 20 */ 619, 597, 575, 553, 531, 509, 486, 464, 442, 858, - /* 30 */ 899, 877, 921, 956, 979, 1017, 998, 1264, 1245, 1226, - /* 40 */ 1207, 1188, 1169, 1150, 1131, 1112, 1093, 1074, 1055, 1036, - /* 50 */ 1321, 1302, 1283, 1349, 1340, 1507, 1499, 1480, 1472, 1453, - /* 60 */ 1444, 1434, 1425, 1415, 1406, 1396, 1387, 1377, 1368, -64, - /* 70 */ 14, -69, 80, 126, 55, 254, 254, 250, 232, 210, - /* 80 */ 186, 184, 155, 154, + /* 0 */ -63, -7, 153, 88, 25, 365, 337, 300, 278, 215, + /* 10 */ 846, 824, 802, 780, 758, 736, 714, 692, 670, 648, + /* 20 */ 626, 604, 582, 560, 538, 516, 492, 470, 448, 865, + /* 30 */ 906, 884, 928, 963, 987, 1025, 1006, 1291, 1272, 1253, + /* 40 */ 1234, 1215, 1196, 1177, 1158, 1139, 1120, 1101, 1082, 1063, + /* 50 */ 1044, 1348, 1329, 1310, 1376, 1367, 1535, 1527, 1508, 1500, + /* 60 */ 1481, 1471, 1462, 1452, 1443, 1433, 1424, 1414, 1405, 1395, + /* 70 */ -65, 14, -70, 154, 128, 77, 235, 235, 234, 213, + /* 80 */ 194, 192, 189, 165, 159, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 354, 354, 342, 354, 332, 354, 339, 354, 354, 354, - /* 10 */ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - /* 20 */ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - /* 30 */ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - /* 40 */ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - /* 50 */ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - /* 60 */ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - /* 70 */ 348, 354, 354, 310, 354, 354, 354, 354, 354, 354, - /* 80 */ 354, 354, 354, 332, 306, 266, 268, 267, 282, 281, - /* 90 */ 280, 279, 278, 277, 276, 275, 274, 273, 269, 287, - /* 100 */ 272, 289, 271, 288, 270, 354, 354, 354, 256, 354, - /* 110 */ 354, 283, 286, 354, 285, 264, 354, 306, 284, 265, - /* 120 */ 255, 253, 354, 316, 354, 354, 354, 351, 259, 354, - /* 130 */ 354, 262, 260, 257, 263, 261, 258, 354, 354, 349, - /* 140 */ 353, 352, 350, 343, 347, 346, 345, 344, 233, 231, - /* 150 */ 237, 252, 251, 250, 249, 248, 247, 246, 245, 244, - /* 160 */ 243, 242, 340, 341, 338, 337, 328, 326, 325, 330, - /* 170 */ 324, 335, 334, 333, 331, 329, 327, 323, 290, 322, - /* 180 */ 321, 320, 319, 318, 317, 316, 293, 315, 314, 312, - /* 190 */ 292, 336, 238, 313, 311, 309, 308, 307, 305, 304, - /* 200 */ 303, 302, 301, 300, 299, 298, 297, 296, 295, 294, - /* 210 */ 291, 254, 241, 240, 239, 236, 235, 234, 230, 227, - /* 220 */ 232, 229, 228, + /* 0 */ 357, 357, 345, 357, 335, 357, 342, 357, 357, 357, + /* 10 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + /* 20 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + /* 30 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + /* 40 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + /* 50 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + /* 60 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + /* 70 */ 357, 351, 357, 357, 313, 357, 357, 357, 357, 357, + /* 80 */ 357, 357, 357, 357, 335, 268, 270, 269, 309, 285, + /* 90 */ 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, + /* 100 */ 271, 290, 274, 292, 273, 291, 272, 357, 357, 357, + /* 110 */ 258, 357, 357, 286, 289, 357, 288, 266, 357, 309, + /* 120 */ 287, 267, 257, 255, 357, 319, 357, 357, 357, 354, + /* 130 */ 261, 357, 357, 264, 262, 259, 265, 263, 260, 357, + /* 140 */ 357, 352, 356, 355, 353, 346, 350, 349, 348, 347, + /* 150 */ 235, 233, 239, 254, 253, 252, 251, 250, 249, 248, + /* 160 */ 247, 246, 245, 244, 343, 344, 341, 340, 331, 329, + /* 170 */ 328, 333, 327, 338, 337, 336, 334, 332, 330, 326, + /* 180 */ 293, 325, 324, 323, 322, 321, 320, 319, 296, 318, + /* 190 */ 317, 315, 295, 339, 240, 316, 314, 312, 311, 310, + /* 200 */ 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, + /* 210 */ 298, 297, 294, 256, 243, 242, 241, 238, 237, 236, + /* 220 */ 232, 229, 234, 231, 230, }; /* The next table maps tokens into fallback tokens. If a construct @@ -632,23 +639,24 @@ static const char *const yyTokenName[] = { "EQUAL", "NOT_EQUAL", "LESS", "GREATER", "LESS_EQUAL", "GREATER_EQUAL", "IN", "MATCH", "NEAR", "NEAR2", "SIMILAR", "TERM_EXTRACT", - "LCP", "PREFIX", "SUFFIX", "SHIFTL", - "SHIFTR", "SHIFTRR", "PLUS", "MINUS", - "STAR", "SLASH", "MOD", "DELETE", - "INCR", "DECR", "NOT", "BITWISE_NOT", - "ADJUST", "EXACT", "PARTIAL", "UNSPLIT", - "DECIMAL", "HEX_INTEGER", "STRING", "BOOLEAN", - "NULL", "BRACKETL", "BRACKETR", "DOT", - "NONEXISTENT_COLUMN", "error", "suppress_unused_variable_warning", "input", - "query", "expression", "output_columns", "adjuster", - "query_element", "primary_expression", "assignment_expression", "conditional_expression", - "lefthand_side_expression", "logical_or_expression", "logical_and_expression", "bitwise_or_expression", - "bitwise_xor_expression", "bitwise_and_expression", "equality_expression", "relational_expression", - "shift_expression", "additive_expression", "multiplicative_expression", "unary_expression", - "postfix_expression", "call_expression", "member_expression", "arguments", - "member_expression_part", "object_literal", "array_literal", "elision", - "element_list", "property_name_and_value_list", "property_name_and_value", "property_name", - "argument_list", "output_column", "adjust_expression", "adjust_match_expression", + "LCP", "PREFIX", "SUFFIX", "REGEXP", + "SHIFTL", "SHIFTR", "SHIFTRR", "PLUS", + "MINUS", "STAR", "SLASH", "MOD", + "DELETE", "INCR", "DECR", "NOT", + "BITWISE_NOT", "ADJUST", "EXACT", "PARTIAL", + "UNSPLIT", "DECIMAL", "HEX_INTEGER", "STRING", + "BOOLEAN", "NULL", "BRACKETL", "BRACKETR", + "DOT", "NONEXISTENT_COLUMN", "error", "suppress_unused_variable_warning", + "input", "query", "expression", "output_columns", + "adjuster", "query_element", "primary_expression", "assignment_expression", + "conditional_expression", "lefthand_side_expression", "logical_or_expression", "logical_and_expression", + "bitwise_or_expression", "bitwise_xor_expression", "bitwise_and_expression", "equality_expression", + "relational_expression", "shift_expression", "additive_expression", "multiplicative_expression", + "unary_expression", "postfix_expression", "call_expression", "member_expression", + "arguments", "member_expression_part", "object_literal", "array_literal", + "elision", "element_list", "property_name_and_value_list", "property_name_and_value", + "property_name", "argument_list", "output_column", "adjust_expression", + "adjust_match_expression", }; #endif /* NDEBUG */ @@ -716,77 +724,78 @@ static const char *const yyRuleName[] = { /* 57 */ "relational_expression ::= relational_expression LCP shift_expression", /* 58 */ "relational_expression ::= relational_expression PREFIX shift_expression", /* 59 */ "relational_expression ::= relational_expression SUFFIX shift_expression", - /* 60 */ "shift_expression ::= additive_expression", - /* 61 */ "shift_expression ::= shift_expression SHIFTL additive_expression", - /* 62 */ "shift_expression ::= shift_expression SHIFTR additive_expression", - /* 63 */ "shift_expression ::= shift_expression SHIFTRR additive_expression", - /* 64 */ "additive_expression ::= multiplicative_expression", - /* 65 */ "additive_expression ::= additive_expression PLUS multiplicative_expression", - /* 66 */ "additive_expression ::= additive_expression MINUS multiplicative_expression", - /* 67 */ "multiplicative_expression ::= unary_expression", - /* 68 */ "multiplicative_expression ::= multiplicative_expression STAR unary_expression", - /* 69 */ "multiplicative_expression ::= multiplicative_expression SLASH unary_expression", - /* 70 */ "multiplicative_expression ::= multiplicative_expression MOD unary_expression", - /* 71 */ "unary_expression ::= postfix_expression", - /* 72 */ "unary_expression ::= DELETE unary_expression", - /* 73 */ "unary_expression ::= INCR unary_expression", - /* 74 */ "unary_expression ::= DECR unary_expression", - /* 75 */ "unary_expression ::= PLUS unary_expression", - /* 76 */ "unary_expression ::= MINUS unary_expression", - /* 77 */ "unary_expression ::= NOT unary_expression", - /* 78 */ "unary_expression ::= BITWISE_NOT unary_expression", - /* 79 */ "unary_expression ::= ADJUST unary_expression", - /* 80 */ "unary_expression ::= EXACT unary_expression", - /* 81 */ "unary_expression ::= PARTIAL unary_expression", - /* 82 */ "unary_expression ::= UNSPLIT unary_expression", - /* 83 */ "postfix_expression ::= lefthand_side_expression", - /* 84 */ "postfix_expression ::= lefthand_side_expression INCR", - /* 85 */ "postfix_expression ::= lefthand_side_expression DECR", - /* 86 */ "lefthand_side_expression ::= call_expression", - /* 87 */ "lefthand_side_expression ::= member_expression", - /* 88 */ "call_expression ::= member_expression arguments", - /* 89 */ "member_expression ::= primary_expression", - /* 90 */ "member_expression ::= member_expression member_expression_part", - /* 91 */ "primary_expression ::= object_literal", - /* 92 */ "primary_expression ::= PARENL expression PARENR", - /* 93 */ "primary_expression ::= IDENTIFIER", - /* 94 */ "primary_expression ::= array_literal", - /* 95 */ "primary_expression ::= DECIMAL", - /* 96 */ "primary_expression ::= HEX_INTEGER", - /* 97 */ "primary_expression ::= STRING", - /* 98 */ "primary_expression ::= BOOLEAN", - /* 99 */ "primary_expression ::= NULL", - /* 100 */ "array_literal ::= BRACKETL elision BRACKETR", - /* 101 */ "array_literal ::= BRACKETL element_list elision BRACKETR", - /* 102 */ "array_literal ::= BRACKETL element_list BRACKETR", - /* 103 */ "elision ::= COMMA", - /* 104 */ "elision ::= elision COMMA", - /* 105 */ "element_list ::= assignment_expression", - /* 106 */ "element_list ::= elision assignment_expression", - /* 107 */ "element_list ::= element_list elision assignment_expression", - /* 108 */ "object_literal ::= BRACEL property_name_and_value_list BRACER", - /* 109 */ "property_name_and_value_list ::=", - /* 110 */ "property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value", - /* 111 */ "property_name_and_value ::= property_name COLON assignment_expression", - /* 112 */ "property_name ::= IDENTIFIER|STRING|DECIMAL", - /* 113 */ "member_expression_part ::= BRACKETL expression BRACKETR", - /* 114 */ "member_expression_part ::= DOT IDENTIFIER", - /* 115 */ "arguments ::= PARENL argument_list PARENR", - /* 116 */ "argument_list ::=", - /* 117 */ "argument_list ::= assignment_expression", - /* 118 */ "argument_list ::= argument_list COMMA assignment_expression", - /* 119 */ "output_columns ::=", - /* 120 */ "output_columns ::= output_column", - /* 121 */ "output_columns ::= output_columns COMMA output_column", - /* 122 */ "output_column ::= STAR", - /* 123 */ "output_column ::= NONEXISTENT_COLUMN", - /* 124 */ "output_column ::= assignment_expression", - /* 125 */ "adjuster ::=", - /* 126 */ "adjuster ::= adjust_expression", - /* 127 */ "adjuster ::= adjuster PLUS adjust_expression", - /* 128 */ "adjust_expression ::= adjust_match_expression", - /* 129 */ "adjust_expression ::= adjust_match_expression STAR DECIMAL", - /* 130 */ "adjust_match_expression ::= IDENTIFIER MATCH STRING", + /* 60 */ "relational_expression ::= relational_expression REGEXP shift_expression", + /* 61 */ "shift_expression ::= additive_expression", + /* 62 */ "shift_expression ::= shift_expression SHIFTL additive_expression", + /* 63 */ "shift_expression ::= shift_expression SHIFTR additive_expression", + /* 64 */ "shift_expression ::= shift_expression SHIFTRR additive_expression", + /* 65 */ "additive_expression ::= multiplicative_expression", + /* 66 */ "additive_expression ::= additive_expression PLUS multiplicative_expression", + /* 67 */ "additive_expression ::= additive_expression MINUS multiplicative_expression", + /* 68 */ "multiplicative_expression ::= unary_expression", + /* 69 */ "multiplicative_expression ::= multiplicative_expression STAR unary_expression", + /* 70 */ "multiplicative_expression ::= multiplicative_expression SLASH unary_expression", + /* 71 */ "multiplicative_expression ::= multiplicative_expression MOD unary_expression", + /* 72 */ "unary_expression ::= postfix_expression", + /* 73 */ "unary_expression ::= DELETE unary_expression", + /* 74 */ "unary_expression ::= INCR unary_expression", + /* 75 */ "unary_expression ::= DECR unary_expression", + /* 76 */ "unary_expression ::= PLUS unary_expression", + /* 77 */ "unary_expression ::= MINUS unary_expression", + /* 78 */ "unary_expression ::= NOT unary_expression", + /* 79 */ "unary_expression ::= BITWISE_NOT unary_expression", + /* 80 */ "unary_expression ::= ADJUST unary_expression", + /* 81 */ "unary_expression ::= EXACT unary_expression", + /* 82 */ "unary_expression ::= PARTIAL unary_expression", + /* 83 */ "unary_expression ::= UNSPLIT unary_expression", + /* 84 */ "postfix_expression ::= lefthand_side_expression", + /* 85 */ "postfix_expression ::= lefthand_side_expression INCR", + /* 86 */ "postfix_expression ::= lefthand_side_expression DECR", + /* 87 */ "lefthand_side_expression ::= call_expression", + /* 88 */ "lefthand_side_expression ::= member_expression", + /* 89 */ "call_expression ::= member_expression arguments", + /* 90 */ "member_expression ::= primary_expression", + /* 91 */ "member_expression ::= member_expression member_expression_part", + /* 92 */ "primary_expression ::= object_literal", + /* 93 */ "primary_expression ::= PARENL expression PARENR", + /* 94 */ "primary_expression ::= IDENTIFIER", + /* 95 */ "primary_expression ::= array_literal", + /* 96 */ "primary_expression ::= DECIMAL", + /* 97 */ "primary_expression ::= HEX_INTEGER", + /* 98 */ "primary_expression ::= STRING", + /* 99 */ "primary_expression ::= BOOLEAN", + /* 100 */ "primary_expression ::= NULL", + /* 101 */ "array_literal ::= BRACKETL elision BRACKETR", + /* 102 */ "array_literal ::= BRACKETL element_list elision BRACKETR", + /* 103 */ "array_literal ::= BRACKETL element_list BRACKETR", + /* 104 */ "elision ::= COMMA", + /* 105 */ "elision ::= elision COMMA", + /* 106 */ "element_list ::= assignment_expression", + /* 107 */ "element_list ::= elision assignment_expression", + /* 108 */ "element_list ::= element_list elision assignment_expression", + /* 109 */ "object_literal ::= BRACEL property_name_and_value_list BRACER", + /* 110 */ "property_name_and_value_list ::=", + /* 111 */ "property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value", + /* 112 */ "property_name_and_value ::= property_name COLON assignment_expression", + /* 113 */ "property_name ::= IDENTIFIER|STRING|DECIMAL", + /* 114 */ "member_expression_part ::= BRACKETL expression BRACKETR", + /* 115 */ "member_expression_part ::= DOT IDENTIFIER", + /* 116 */ "arguments ::= PARENL argument_list PARENR", + /* 117 */ "argument_list ::=", + /* 118 */ "argument_list ::= assignment_expression", + /* 119 */ "argument_list ::= argument_list COMMA assignment_expression", + /* 120 */ "output_columns ::=", + /* 121 */ "output_columns ::= output_column", + /* 122 */ "output_columns ::= output_columns COMMA output_column", + /* 123 */ "output_column ::= STAR", + /* 124 */ "output_column ::= NONEXISTENT_COLUMN", + /* 125 */ "output_column ::= assignment_expression", + /* 126 */ "adjuster ::=", + /* 127 */ "adjuster ::= adjust_expression", + /* 128 */ "adjuster ::= adjuster PLUS adjust_expression", + /* 129 */ "adjust_expression ::= adjust_match_expression", + /* 130 */ "adjust_expression ::= adjust_match_expression STAR DECIMAL", + /* 131 */ "adjust_match_expression ::= IDENTIFIER MATCH STRING", }; #endif /* NDEBUG */ @@ -865,13 +874,13 @@ static void yy_destructor( ** which appear on the RHS of the rule, but which are not used ** inside the C code. */ - case 74: /* suppress_unused_variable_warning */ + case 75: /* suppress_unused_variable_warning */ { #line 11 "grn_ecmascript.lemon" (void)efsi; -#line 875 "grn_ecmascript.c" +#line 884 "grn_ecmascript.c" } break; default: break; /* If no destructor action specified: do nothing */ @@ -1109,137 +1118,138 @@ static const struct { YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ unsigned char nrhs; /* Number of right-hand side symbols in the rule */ } yyRuleInfo[] = { - { 75, 1 }, - { 75, 1 }, - { 75, 2 }, - { 75, 2 }, + { 76, 1 }, { 76, 1 }, { 76, 2 }, - { 76, 3 }, - { 76, 3 }, - { 76, 3 }, - { 80, 1 }, - { 80, 3 }, - { 80, 2 }, - { 80, 3 }, - { 80, 3 }, - { 80, 2 }, + { 76, 2 }, { 77, 1 }, + { 77, 2 }, { 77, 3 }, - { 82, 1 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, - { 82, 3 }, + { 77, 3 }, + { 77, 3 }, + { 81, 1 }, + { 81, 3 }, + { 81, 2 }, + { 81, 3 }, + { 81, 3 }, + { 81, 2 }, + { 78, 1 }, + { 78, 3 }, { 83, 1 }, - { 83, 5 }, - { 85, 1 }, - { 85, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 83, 3 }, + { 84, 1 }, + { 84, 5 }, { 86, 1 }, { 86, 3 }, - { 86, 3 }, { 87, 1 }, { 87, 3 }, + { 87, 3 }, { 88, 1 }, { 88, 3 }, { 89, 1 }, { 89, 3 }, { 90, 1 }, { 90, 3 }, - { 90, 3 }, { 91, 1 }, { 91, 3 }, { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, - { 91, 3 }, { 92, 1 }, { 92, 3 }, { 92, 3 }, { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, + { 92, 3 }, { 93, 1 }, { 93, 3 }, { 93, 3 }, + { 93, 3 }, { 94, 1 }, { 94, 3 }, { 94, 3 }, - { 94, 3 }, { 95, 1 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, - { 95, 2 }, + { 95, 3 }, + { 95, 3 }, + { 95, 3 }, { 96, 1 }, { 96, 2 }, { 96, 2 }, - { 84, 1 }, - { 84, 1 }, + { 96, 2 }, + { 96, 2 }, + { 96, 2 }, + { 96, 2 }, + { 96, 2 }, + { 96, 2 }, + { 96, 2 }, + { 96, 2 }, + { 96, 2 }, + { 97, 1 }, + { 97, 2 }, { 97, 2 }, - { 98, 1 }, + { 85, 1 }, + { 85, 1 }, { 98, 2 }, - { 81, 1 }, - { 81, 3 }, - { 81, 1 }, - { 81, 1 }, - { 81, 1 }, - { 81, 1 }, - { 81, 1 }, - { 81, 1 }, - { 81, 1 }, - { 102, 3 }, - { 102, 4 }, - { 102, 3 }, - { 103, 1 }, - { 103, 2 }, + { 99, 1 }, + { 99, 2 }, + { 82, 1 }, + { 82, 3 }, + { 82, 1 }, + { 82, 1 }, + { 82, 1 }, + { 82, 1 }, + { 82, 1 }, + { 82, 1 }, + { 82, 1 }, + { 103, 3 }, + { 103, 4 }, + { 103, 3 }, { 104, 1 }, { 104, 2 }, - { 104, 3 }, - { 101, 3 }, - { 105, 0 }, + { 105, 1 }, + { 105, 2 }, { 105, 3 }, + { 102, 3 }, + { 106, 0 }, { 106, 3 }, - { 107, 1 }, - { 100, 3 }, - { 100, 2 }, - { 99, 3 }, - { 108, 0 }, + { 107, 3 }, { 108, 1 }, - { 108, 3 }, - { 78, 0 }, - { 78, 1 }, - { 78, 3 }, - { 109, 1 }, - { 109, 1 }, + { 101, 3 }, + { 101, 2 }, + { 100, 3 }, + { 109, 0 }, { 109, 1 }, + { 109, 3 }, { 79, 0 }, { 79, 1 }, { 79, 3 }, { 110, 1 }, - { 110, 3 }, + { 110, 1 }, + { 110, 1 }, + { 80, 0 }, + { 80, 1 }, + { 80, 3 }, + { 111, 1 }, { 111, 3 }, + { 112, 3 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -1299,7 +1309,7 @@ static void yy_reduce( { grn_expr_append_op(efsi->ctx, efsi->e, grn_int32_value_at(&efsi->op_stack, -1), 2); } -#line 1303 "grn_ecmascript.c" +#line 1313 "grn_ecmascript.c" break; case 6: /* query ::= query LOGICAL_AND query_element */ case 35: /* logical_and_expression ::= logical_and_expression LOGICAL_AND bitwise_or_expression */ yytestcase(yyruleno==35); @@ -1307,7 +1317,7 @@ static void yy_reduce( { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND, 2); } -#line 1311 "grn_ecmascript.c" +#line 1321 "grn_ecmascript.c" break; case 7: /* query ::= query LOGICAL_AND_NOT query_element */ case 36: /* logical_and_expression ::= logical_and_expression LOGICAL_AND_NOT bitwise_or_expression */ yytestcase(yyruleno==36); @@ -1315,7 +1325,7 @@ static void yy_reduce( { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_NOT, 2); } -#line 1319 "grn_ecmascript.c" +#line 1329 "grn_ecmascript.c" break; case 8: /* query ::= query LOGICAL_OR query_element */ case 33: /* logical_or_expression ::= logical_or_expression LOGICAL_OR logical_and_expression */ yytestcase(yyruleno==33); @@ -1323,7 +1333,7 @@ static void yy_reduce( { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR, 2); } -#line 1327 "grn_ecmascript.c" +#line 1337 "grn_ecmascript.c" break; case 11: /* query_element ::= RELATIVE_OP query_element */ #line 62 "grn_ecmascript.lemon" @@ -1331,7 +1341,7 @@ static void yy_reduce( int mode; GRN_INT32_POP(&efsi->mode_stack, mode); } -#line 1335 "grn_ecmascript.c" +#line 1345 "grn_ecmascript.c" break; case 12: /* query_element ::= IDENTIFIER RELATIVE_OP query_element */ #line 66 "grn_ecmascript.lemon" @@ -1358,7 +1368,7 @@ static void yy_reduce( break; } } -#line 1362 "grn_ecmascript.c" +#line 1372 "grn_ecmascript.c" break; case 13: /* query_element ::= BRACEL expression BRACER */ case 14: /* query_element ::= EVAL primary_expression */ yytestcase(yyruleno==14); @@ -1366,98 +1376,98 @@ static void yy_reduce( { efsi->flags = efsi->default_flags; } -#line 1370 "grn_ecmascript.c" +#line 1380 "grn_ecmascript.c" break; case 16: /* expression ::= expression COMMA assignment_expression */ #line 97 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2); } -#line 1377 "grn_ecmascript.c" +#line 1387 "grn_ecmascript.c" break; case 18: /* assignment_expression ::= lefthand_side_expression ASSIGN assignment_expression */ #line 102 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ASSIGN, 2); } -#line 1384 "grn_ecmascript.c" +#line 1394 "grn_ecmascript.c" break; case 19: /* assignment_expression ::= lefthand_side_expression STAR_ASSIGN assignment_expression */ #line 105 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR_ASSIGN, 2); } -#line 1391 "grn_ecmascript.c" +#line 1401 "grn_ecmascript.c" break; case 20: /* assignment_expression ::= lefthand_side_expression SLASH_ASSIGN assignment_expression */ #line 108 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH_ASSIGN, 2); } -#line 1398 "grn_ecmascript.c" +#line 1408 "grn_ecmascript.c" break; case 21: /* assignment_expression ::= lefthand_side_expression MOD_ASSIGN assignment_expression */ #line 111 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD_ASSIGN, 2); } -#line 1405 "grn_ecmascript.c" +#line 1415 "grn_ecmascript.c" break; case 22: /* assignment_expression ::= lefthand_side_expression PLUS_ASSIGN assignment_expression */ #line 114 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS_ASSIGN, 2); } -#line 1412 "grn_ecmascript.c" +#line 1422 "grn_ecmascript.c" break; case 23: /* assignment_expression ::= lefthand_side_expression MINUS_ASSIGN assignment_expression */ #line 117 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS_ASSIGN, 2); } -#line 1419 "grn_ecmascript.c" +#line 1429 "grn_ecmascript.c" break; case 24: /* assignment_expression ::= lefthand_side_expression SHIFTL_ASSIGN assignment_expression */ #line 120 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL_ASSIGN, 2); } -#line 1426 "grn_ecmascript.c" +#line 1436 "grn_ecmascript.c" break; case 25: /* assignment_expression ::= lefthand_side_expression SHIFTR_ASSIGN assignment_expression */ #line 123 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR_ASSIGN, 2); } -#line 1433 "grn_ecmascript.c" +#line 1443 "grn_ecmascript.c" break; case 26: /* assignment_expression ::= lefthand_side_expression SHIFTRR_ASSIGN assignment_expression */ #line 126 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR_ASSIGN, 2); } -#line 1440 "grn_ecmascript.c" +#line 1450 "grn_ecmascript.c" break; case 27: /* assignment_expression ::= lefthand_side_expression AND_ASSIGN assignment_expression */ #line 129 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_ASSIGN, 2); } -#line 1447 "grn_ecmascript.c" +#line 1457 "grn_ecmascript.c" break; case 28: /* assignment_expression ::= lefthand_side_expression XOR_ASSIGN assignment_expression */ #line 132 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_XOR_ASSIGN, 2); } -#line 1454 "grn_ecmascript.c" +#line 1464 "grn_ecmascript.c" break; case 29: /* assignment_expression ::= lefthand_side_expression OR_ASSIGN assignment_expression */ #line 135 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR_ASSIGN, 2); } -#line 1461 "grn_ecmascript.c" +#line 1471 "grn_ecmascript.c" break; case 31: /* conditional_expression ::= logical_or_expression QUESTION assignment_expression COLON assignment_expression */ #line 140 "grn_ecmascript.lemon" @@ -1466,202 +1476,209 @@ static void yy_reduce( e->codes[yymsp[-3].minor.yy0].nargs = yymsp[-1].minor.yy0 - yymsp[-3].minor.yy0; e->codes[yymsp[-1].minor.yy0].nargs = e->codes_curr - yymsp[-1].minor.yy0 - 1; } -#line 1470 "grn_ecmascript.c" +#line 1480 "grn_ecmascript.c" break; case 38: /* bitwise_or_expression ::= bitwise_or_expression BITWISE_OR bitwise_xor_expression */ #line 160 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_OR, 2); } -#line 1477 "grn_ecmascript.c" +#line 1487 "grn_ecmascript.c" break; case 40: /* bitwise_xor_expression ::= bitwise_xor_expression BITWISE_XOR bitwise_and_expression */ #line 165 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_XOR, 2); } -#line 1484 "grn_ecmascript.c" +#line 1494 "grn_ecmascript.c" break; case 42: /* bitwise_and_expression ::= bitwise_and_expression BITWISE_AND equality_expression */ #line 170 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_AND, 2); } -#line 1491 "grn_ecmascript.c" +#line 1501 "grn_ecmascript.c" break; case 44: /* equality_expression ::= equality_expression EQUAL relational_expression */ #line 175 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EQUAL, 2); } -#line 1498 "grn_ecmascript.c" +#line 1508 "grn_ecmascript.c" break; case 45: /* equality_expression ::= equality_expression NOT_EQUAL relational_expression */ #line 178 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT_EQUAL, 2); } -#line 1505 "grn_ecmascript.c" +#line 1515 "grn_ecmascript.c" break; case 47: /* relational_expression ::= relational_expression LESS shift_expression */ #line 183 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS, 2); } -#line 1512 "grn_ecmascript.c" +#line 1522 "grn_ecmascript.c" break; case 48: /* relational_expression ::= relational_expression GREATER shift_expression */ #line 186 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER, 2); } -#line 1519 "grn_ecmascript.c" +#line 1529 "grn_ecmascript.c" break; case 49: /* relational_expression ::= relational_expression LESS_EQUAL shift_expression */ #line 189 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS_EQUAL, 2); } -#line 1526 "grn_ecmascript.c" +#line 1536 "grn_ecmascript.c" break; case 50: /* relational_expression ::= relational_expression GREATER_EQUAL shift_expression */ #line 192 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER_EQUAL, 2); } -#line 1533 "grn_ecmascript.c" +#line 1543 "grn_ecmascript.c" break; case 51: /* relational_expression ::= relational_expression IN shift_expression */ #line 195 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_IN, 2); } -#line 1540 "grn_ecmascript.c" +#line 1550 "grn_ecmascript.c" break; case 52: /* relational_expression ::= relational_expression MATCH shift_expression */ - case 130: /* adjust_match_expression ::= IDENTIFIER MATCH STRING */ yytestcase(yyruleno==130); + case 131: /* adjust_match_expression ::= IDENTIFIER MATCH STRING */ yytestcase(yyruleno==131); #line 198 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MATCH, 2); } -#line 1548 "grn_ecmascript.c" +#line 1558 "grn_ecmascript.c" break; case 53: /* relational_expression ::= relational_expression NEAR shift_expression */ #line 201 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR, 2); } -#line 1555 "grn_ecmascript.c" +#line 1565 "grn_ecmascript.c" break; case 54: /* relational_expression ::= relational_expression NEAR2 shift_expression */ #line 204 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR2, 2); } -#line 1562 "grn_ecmascript.c" +#line 1572 "grn_ecmascript.c" break; case 55: /* relational_expression ::= relational_expression SIMILAR shift_expression */ #line 207 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SIMILAR, 2); } -#line 1569 "grn_ecmascript.c" +#line 1579 "grn_ecmascript.c" break; case 56: /* relational_expression ::= relational_expression TERM_EXTRACT shift_expression */ #line 210 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_TERM_EXTRACT, 2); } -#line 1576 "grn_ecmascript.c" +#line 1586 "grn_ecmascript.c" break; case 57: /* relational_expression ::= relational_expression LCP shift_expression */ #line 213 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LCP, 2); } -#line 1583 "grn_ecmascript.c" +#line 1593 "grn_ecmascript.c" break; case 58: /* relational_expression ::= relational_expression PREFIX shift_expression */ #line 216 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PREFIX, 2); } -#line 1590 "grn_ecmascript.c" +#line 1600 "grn_ecmascript.c" break; case 59: /* relational_expression ::= relational_expression SUFFIX shift_expression */ #line 219 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SUFFIX, 2); } -#line 1597 "grn_ecmascript.c" +#line 1607 "grn_ecmascript.c" break; - case 61: /* shift_expression ::= shift_expression SHIFTL additive_expression */ -#line 224 "grn_ecmascript.lemon" + case 60: /* relational_expression ::= relational_expression REGEXP shift_expression */ +#line 222 "grn_ecmascript.lemon" { - grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL, 2); + grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_REGEXP, 2); } -#line 1604 "grn_ecmascript.c" +#line 1614 "grn_ecmascript.c" break; - case 62: /* shift_expression ::= shift_expression SHIFTR additive_expression */ + case 62: /* shift_expression ::= shift_expression SHIFTL additive_expression */ #line 227 "grn_ecmascript.lemon" { - grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR, 2); + grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL, 2); } -#line 1611 "grn_ecmascript.c" +#line 1621 "grn_ecmascript.c" break; - case 63: /* shift_expression ::= shift_expression SHIFTRR additive_expression */ + case 63: /* shift_expression ::= shift_expression SHIFTR additive_expression */ #line 230 "grn_ecmascript.lemon" { + grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR, 2); +} +#line 1628 "grn_ecmascript.c" + break; + case 64: /* shift_expression ::= shift_expression SHIFTRR additive_expression */ +#line 233 "grn_ecmascript.lemon" +{ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR, 2); } -#line 1618 "grn_ecmascript.c" +#line 1635 "grn_ecmascript.c" break; - case 65: /* additive_expression ::= additive_expression PLUS multiplicative_expression */ - case 127: /* adjuster ::= adjuster PLUS adjust_expression */ yytestcase(yyruleno==127); -#line 235 "grn_ecmascript.lemon" + case 66: /* additive_expression ::= additive_expression PLUS multiplicative_expression */ + case 128: /* adjuster ::= adjuster PLUS adjust_expression */ yytestcase(yyruleno==128); +#line 238 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 2); } -#line 1626 "grn_ecmascript.c" +#line 1643 "grn_ecmascript.c" break; - case 66: /* additive_expression ::= additive_expression MINUS multiplicative_expression */ -#line 238 "grn_ecmascript.lemon" + case 67: /* additive_expression ::= additive_expression MINUS multiplicative_expression */ +#line 241 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 2); } -#line 1633 "grn_ecmascript.c" +#line 1650 "grn_ecmascript.c" break; - case 68: /* multiplicative_expression ::= multiplicative_expression STAR unary_expression */ - case 129: /* adjust_expression ::= adjust_match_expression STAR DECIMAL */ yytestcase(yyruleno==129); -#line 243 "grn_ecmascript.lemon" + case 69: /* multiplicative_expression ::= multiplicative_expression STAR unary_expression */ + case 130: /* adjust_expression ::= adjust_match_expression STAR DECIMAL */ yytestcase(yyruleno==130); +#line 246 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR, 2); } -#line 1641 "grn_ecmascript.c" +#line 1658 "grn_ecmascript.c" break; - case 69: /* multiplicative_expression ::= multiplicative_expression SLASH unary_expression */ -#line 246 "grn_ecmascript.lemon" + case 70: /* multiplicative_expression ::= multiplicative_expression SLASH unary_expression */ +#line 249 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH, 2); } -#line 1648 "grn_ecmascript.c" +#line 1665 "grn_ecmascript.c" break; - case 70: /* multiplicative_expression ::= multiplicative_expression MOD unary_expression */ -#line 249 "grn_ecmascript.lemon" + case 71: /* multiplicative_expression ::= multiplicative_expression MOD unary_expression */ +#line 252 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD, 2); } -#line 1655 "grn_ecmascript.c" +#line 1672 "grn_ecmascript.c" break; - case 72: /* unary_expression ::= DELETE unary_expression */ -#line 254 "grn_ecmascript.lemon" + case 73: /* unary_expression ::= DELETE unary_expression */ +#line 257 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DELETE, 1); } -#line 1662 "grn_ecmascript.c" +#line 1679 "grn_ecmascript.c" break; - case 73: /* unary_expression ::= INCR unary_expression */ -#line 257 "grn_ecmascript.lemon" + case 74: /* unary_expression ::= INCR unary_expression */ +#line 260 "grn_ecmascript.lemon" { grn_ctx *ctx = efsi->ctx; grn_expr *e = (grn_expr *)(efsi->e); @@ -1679,10 +1696,10 @@ static void yy_reduce( grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR, 1); } } -#line 1683 "grn_ecmascript.c" +#line 1700 "grn_ecmascript.c" break; - case 74: /* unary_expression ::= DECR unary_expression */ -#line 274 "grn_ecmascript.lemon" + case 75: /* unary_expression ::= DECR unary_expression */ +#line 277 "grn_ecmascript.lemon" { grn_ctx *ctx = efsi->ctx; grn_expr *e = (grn_expr *)(efsi->e); @@ -1700,66 +1717,66 @@ static void yy_reduce( grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR, 1); } } -#line 1704 "grn_ecmascript.c" +#line 1721 "grn_ecmascript.c" break; - case 75: /* unary_expression ::= PLUS unary_expression */ -#line 291 "grn_ecmascript.lemon" + case 76: /* unary_expression ::= PLUS unary_expression */ +#line 294 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 1); } -#line 1711 "grn_ecmascript.c" +#line 1728 "grn_ecmascript.c" break; - case 76: /* unary_expression ::= MINUS unary_expression */ -#line 294 "grn_ecmascript.lemon" + case 77: /* unary_expression ::= MINUS unary_expression */ +#line 297 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 1); } -#line 1718 "grn_ecmascript.c" +#line 1735 "grn_ecmascript.c" break; - case 77: /* unary_expression ::= NOT unary_expression */ -#line 297 "grn_ecmascript.lemon" + case 78: /* unary_expression ::= NOT unary_expression */ +#line 300 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT, 1); } -#line 1725 "grn_ecmascript.c" +#line 1742 "grn_ecmascript.c" break; - case 78: /* unary_expression ::= BITWISE_NOT unary_expression */ -#line 300 "grn_ecmascript.lemon" + case 79: /* unary_expression ::= BITWISE_NOT unary_expression */ +#line 303 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_NOT, 1); } -#line 1732 "grn_ecmascript.c" +#line 1749 "grn_ecmascript.c" break; - case 79: /* unary_expression ::= ADJUST unary_expression */ -#line 303 "grn_ecmascript.lemon" + case 80: /* unary_expression ::= ADJUST unary_expression */ +#line 306 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 1); } -#line 1739 "grn_ecmascript.c" +#line 1756 "grn_ecmascript.c" break; - case 80: /* unary_expression ::= EXACT unary_expression */ -#line 306 "grn_ecmascript.lemon" + case 81: /* unary_expression ::= EXACT unary_expression */ +#line 309 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EXACT, 1); } -#line 1746 "grn_ecmascript.c" +#line 1763 "grn_ecmascript.c" break; - case 81: /* unary_expression ::= PARTIAL unary_expression */ -#line 309 "grn_ecmascript.lemon" + case 82: /* unary_expression ::= PARTIAL unary_expression */ +#line 312 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PARTIAL, 1); } -#line 1753 "grn_ecmascript.c" +#line 1770 "grn_ecmascript.c" break; - case 82: /* unary_expression ::= UNSPLIT unary_expression */ -#line 312 "grn_ecmascript.lemon" + case 83: /* unary_expression ::= UNSPLIT unary_expression */ +#line 315 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_UNSPLIT, 1); } -#line 1760 "grn_ecmascript.c" +#line 1777 "grn_ecmascript.c" break; - case 84: /* postfix_expression ::= lefthand_side_expression INCR */ -#line 317 "grn_ecmascript.lemon" + case 85: /* postfix_expression ::= lefthand_side_expression INCR */ +#line 320 "grn_ecmascript.lemon" { grn_ctx *ctx = efsi->ctx; grn_expr *e = (grn_expr *)(efsi->e); @@ -1777,10 +1794,10 @@ static void yy_reduce( grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR_POST, 1); } } -#line 1781 "grn_ecmascript.c" +#line 1798 "grn_ecmascript.c" break; - case 85: /* postfix_expression ::= lefthand_side_expression DECR */ -#line 334 "grn_ecmascript.lemon" + case 86: /* postfix_expression ::= lefthand_side_expression DECR */ +#line 337 "grn_ecmascript.lemon" { grn_ctx *ctx = efsi->ctx; grn_expr *e = (grn_expr *)(efsi->e); @@ -1798,51 +1815,51 @@ static void yy_reduce( grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR_POST, 1); } } -#line 1802 "grn_ecmascript.c" +#line 1819 "grn_ecmascript.c" break; - case 88: /* call_expression ::= member_expression arguments */ -#line 355 "grn_ecmascript.lemon" + case 89: /* call_expression ::= member_expression arguments */ +#line 358 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_CALL, yymsp[0].minor.yy0); } -#line 1809 "grn_ecmascript.c" +#line 1826 "grn_ecmascript.c" break; - case 113: /* member_expression_part ::= BRACKETL expression BRACKETR */ -#line 391 "grn_ecmascript.lemon" + case 114: /* member_expression_part ::= BRACKETL expression BRACKETR */ +#line 394 "grn_ecmascript.lemon" { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GET_MEMBER, 2); } -#line 1816 "grn_ecmascript.c" +#line 1833 "grn_ecmascript.c" break; - case 115: /* arguments ::= PARENL argument_list PARENR */ -#line 396 "grn_ecmascript.lemon" + case 116: /* arguments ::= PARENL argument_list PARENR */ +#line 399 "grn_ecmascript.lemon" { yygotominor.yy0 = yymsp[-1].minor.yy0; } -#line 1821 "grn_ecmascript.c" +#line 1838 "grn_ecmascript.c" break; - case 116: /* argument_list ::= */ -#line 397 "grn_ecmascript.lemon" + case 117: /* argument_list ::= */ +#line 400 "grn_ecmascript.lemon" { yygotominor.yy0 = 0; } -#line 1826 "grn_ecmascript.c" +#line 1843 "grn_ecmascript.c" break; - case 117: /* argument_list ::= assignment_expression */ -#line 398 "grn_ecmascript.lemon" + case 118: /* argument_list ::= assignment_expression */ +#line 401 "grn_ecmascript.lemon" { yygotominor.yy0 = 1; } -#line 1831 "grn_ecmascript.c" +#line 1848 "grn_ecmascript.c" break; - case 118: /* argument_list ::= argument_list COMMA assignment_expression */ -#line 399 "grn_ecmascript.lemon" + case 119: /* argument_list ::= argument_list COMMA assignment_expression */ +#line 402 "grn_ecmascript.lemon" { yygotominor.yy0 = yymsp[-2].minor.yy0 + 1; } -#line 1836 "grn_ecmascript.c" +#line 1853 "grn_ecmascript.c" break; - case 119: /* output_columns ::= */ -#line 401 "grn_ecmascript.lemon" + case 120: /* output_columns ::= */ +#line 404 "grn_ecmascript.lemon" { yygotominor.yy0 = 0; } -#line 1843 "grn_ecmascript.c" +#line 1860 "grn_ecmascript.c" break; - case 120: /* output_columns ::= output_column */ -#line 404 "grn_ecmascript.lemon" + case 121: /* output_columns ::= output_column */ +#line 407 "grn_ecmascript.lemon" { if (yymsp[0].minor.yy0) { yygotominor.yy0 = 0; @@ -1850,10 +1867,10 @@ static void yy_reduce( yygotominor.yy0 = 1; } } -#line 1854 "grn_ecmascript.c" +#line 1871 "grn_ecmascript.c" break; - case 121: /* output_columns ::= output_columns COMMA output_column */ -#line 412 "grn_ecmascript.lemon" + case 122: /* output_columns ::= output_columns COMMA output_column */ +#line 415 "grn_ecmascript.lemon" { if (yymsp[0].minor.yy0) { yygotominor.yy0 = yymsp[-2].minor.yy0; @@ -1864,10 +1881,10 @@ static void yy_reduce( yygotominor.yy0 = 1; } } -#line 1868 "grn_ecmascript.c" +#line 1885 "grn_ecmascript.c" break; - case 122: /* output_column ::= STAR */ -#line 423 "grn_ecmascript.lemon" + case 123: /* output_column ::= STAR */ +#line 426 "grn_ecmascript.lemon" { grn_ctx *ctx = efsi->ctx; grn_obj *expr = efsi->e; @@ -1905,21 +1922,21 @@ static void yy_reduce( yygotominor.yy0 = GRN_TRUE; } } -#line 1909 "grn_ecmascript.c" +#line 1926 "grn_ecmascript.c" break; - case 123: /* output_column ::= NONEXISTENT_COLUMN */ -#line 460 "grn_ecmascript.lemon" + case 124: /* output_column ::= NONEXISTENT_COLUMN */ +#line 463 "grn_ecmascript.lemon" { yygotominor.yy0 = GRN_TRUE; } -#line 1916 "grn_ecmascript.c" +#line 1933 "grn_ecmascript.c" break; - case 124: /* output_column ::= assignment_expression */ -#line 463 "grn_ecmascript.lemon" + case 125: /* output_column ::= assignment_expression */ +#line 466 "grn_ecmascript.lemon" { yygotominor.yy0 = GRN_FALSE; } -#line 1923 "grn_ecmascript.c" +#line 1940 "grn_ecmascript.c" break; default: /* (0) input ::= query */ yytestcase(yyruleno==0); @@ -1939,41 +1956,41 @@ static void yy_reduce( /* (41) bitwise_and_expression ::= equality_expression */ yytestcase(yyruleno==41); /* (43) equality_expression ::= relational_expression */ yytestcase(yyruleno==43); /* (46) relational_expression ::= shift_expression */ yytestcase(yyruleno==46); - /* (60) shift_expression ::= additive_expression */ yytestcase(yyruleno==60); - /* (64) additive_expression ::= multiplicative_expression */ yytestcase(yyruleno==64); - /* (67) multiplicative_expression ::= unary_expression */ yytestcase(yyruleno==67); - /* (71) unary_expression ::= postfix_expression */ yytestcase(yyruleno==71); - /* (83) postfix_expression ::= lefthand_side_expression */ yytestcase(yyruleno==83); - /* (86) lefthand_side_expression ::= call_expression */ yytestcase(yyruleno==86); - /* (87) lefthand_side_expression ::= member_expression */ yytestcase(yyruleno==87); - /* (89) member_expression ::= primary_expression */ yytestcase(yyruleno==89); - /* (90) member_expression ::= member_expression member_expression_part */ yytestcase(yyruleno==90); - /* (91) primary_expression ::= object_literal */ yytestcase(yyruleno==91); - /* (92) primary_expression ::= PARENL expression PARENR */ yytestcase(yyruleno==92); - /* (93) primary_expression ::= IDENTIFIER */ yytestcase(yyruleno==93); - /* (94) primary_expression ::= array_literal */ yytestcase(yyruleno==94); - /* (95) primary_expression ::= DECIMAL */ yytestcase(yyruleno==95); - /* (96) primary_expression ::= HEX_INTEGER */ yytestcase(yyruleno==96); - /* (97) primary_expression ::= STRING */ yytestcase(yyruleno==97); - /* (98) primary_expression ::= BOOLEAN */ yytestcase(yyruleno==98); - /* (99) primary_expression ::= NULL */ yytestcase(yyruleno==99); - /* (100) array_literal ::= BRACKETL elision BRACKETR */ yytestcase(yyruleno==100); - /* (101) array_literal ::= BRACKETL element_list elision BRACKETR */ yytestcase(yyruleno==101); - /* (102) array_literal ::= BRACKETL element_list BRACKETR */ yytestcase(yyruleno==102); - /* (103) elision ::= COMMA */ yytestcase(yyruleno==103); - /* (104) elision ::= elision COMMA */ yytestcase(yyruleno==104); - /* (105) element_list ::= assignment_expression */ yytestcase(yyruleno==105); - /* (106) element_list ::= elision assignment_expression */ yytestcase(yyruleno==106); - /* (107) element_list ::= element_list elision assignment_expression */ yytestcase(yyruleno==107); - /* (108) object_literal ::= BRACEL property_name_and_value_list BRACER */ yytestcase(yyruleno==108); - /* (109) property_name_and_value_list ::= */ yytestcase(yyruleno==109); - /* (110) property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value */ yytestcase(yyruleno==110); - /* (111) property_name_and_value ::= property_name COLON assignment_expression */ yytestcase(yyruleno==111); - /* (112) property_name ::= IDENTIFIER|STRING|DECIMAL */ yytestcase(yyruleno==112); - /* (114) member_expression_part ::= DOT IDENTIFIER */ yytestcase(yyruleno==114); - /* (125) adjuster ::= */ yytestcase(yyruleno==125); - /* (126) adjuster ::= adjust_expression */ yytestcase(yyruleno==126); - /* (128) adjust_expression ::= adjust_match_expression */ yytestcase(yyruleno==128); + /* (61) shift_expression ::= additive_expression */ yytestcase(yyruleno==61); + /* (65) additive_expression ::= multiplicative_expression */ yytestcase(yyruleno==65); + /* (68) multiplicative_expression ::= unary_expression */ yytestcase(yyruleno==68); + /* (72) unary_expression ::= postfix_expression */ yytestcase(yyruleno==72); + /* (84) postfix_expression ::= lefthand_side_expression */ yytestcase(yyruleno==84); + /* (87) lefthand_side_expression ::= call_expression */ yytestcase(yyruleno==87); + /* (88) lefthand_side_expression ::= member_expression */ yytestcase(yyruleno==88); + /* (90) member_expression ::= primary_expression */ yytestcase(yyruleno==90); + /* (91) member_expression ::= member_expression member_expression_part */ yytestcase(yyruleno==91); + /* (92) primary_expression ::= object_literal */ yytestcase(yyruleno==92); + /* (93) primary_expression ::= PARENL expression PARENR */ yytestcase(yyruleno==93); + /* (94) primary_expression ::= IDENTIFIER */ yytestcase(yyruleno==94); + /* (95) primary_expression ::= array_literal */ yytestcase(yyruleno==95); + /* (96) primary_expression ::= DECIMAL */ yytestcase(yyruleno==96); + /* (97) primary_expression ::= HEX_INTEGER */ yytestcase(yyruleno==97); + /* (98) primary_expression ::= STRING */ yytestcase(yyruleno==98); + /* (99) primary_expression ::= BOOLEAN */ yytestcase(yyruleno==99); + /* (100) primary_expression ::= NULL */ yytestcase(yyruleno==100); + /* (101) array_literal ::= BRACKETL elision BRACKETR */ yytestcase(yyruleno==101); + /* (102) array_literal ::= BRACKETL element_list elision BRACKETR */ yytestcase(yyruleno==102); + /* (103) array_literal ::= BRACKETL element_list BRACKETR */ yytestcase(yyruleno==103); + /* (104) elision ::= COMMA */ yytestcase(yyruleno==104); + /* (105) elision ::= elision COMMA */ yytestcase(yyruleno==105); + /* (106) element_list ::= assignment_expression */ yytestcase(yyruleno==106); + /* (107) element_list ::= elision assignment_expression */ yytestcase(yyruleno==107); + /* (108) element_list ::= element_list elision assignment_expression */ yytestcase(yyruleno==108); + /* (109) object_literal ::= BRACEL property_name_and_value_list BRACER */ yytestcase(yyruleno==109); + /* (110) property_name_and_value_list ::= */ yytestcase(yyruleno==110); + /* (111) property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value */ yytestcase(yyruleno==111); + /* (112) property_name_and_value ::= property_name COLON assignment_expression */ yytestcase(yyruleno==112); + /* (113) property_name ::= IDENTIFIER|STRING|DECIMAL */ yytestcase(yyruleno==113); + /* (115) member_expression_part ::= DOT IDENTIFIER */ yytestcase(yyruleno==115); + /* (126) adjuster ::= */ yytestcase(yyruleno==126); + /* (127) adjuster ::= adjust_expression */ yytestcase(yyruleno==127); + /* (129) adjust_expression ::= adjust_match_expression */ yytestcase(yyruleno==129); break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -2055,7 +2072,7 @@ static void yy_syntax_error( GRN_OBJ_FIN(ctx, &message); } } -#line 2059 "grn_ecmascript.c" +#line 2076 "grn_ecmascript.c" grn_expr_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } diff --git a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h index c8e74b2fb8f..6280690482b 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h +++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h @@ -44,29 +44,30 @@ #define GRN_EXPR_TOKEN_LCP 44 #define GRN_EXPR_TOKEN_PREFIX 45 #define GRN_EXPR_TOKEN_SUFFIX 46 -#define GRN_EXPR_TOKEN_SHIFTL 47 -#define GRN_EXPR_TOKEN_SHIFTR 48 -#define GRN_EXPR_TOKEN_SHIFTRR 49 -#define GRN_EXPR_TOKEN_PLUS 50 -#define GRN_EXPR_TOKEN_MINUS 51 -#define GRN_EXPR_TOKEN_STAR 52 -#define GRN_EXPR_TOKEN_SLASH 53 -#define GRN_EXPR_TOKEN_MOD 54 -#define GRN_EXPR_TOKEN_DELETE 55 -#define GRN_EXPR_TOKEN_INCR 56 -#define GRN_EXPR_TOKEN_DECR 57 -#define GRN_EXPR_TOKEN_NOT 58 -#define GRN_EXPR_TOKEN_BITWISE_NOT 59 -#define GRN_EXPR_TOKEN_ADJUST 60 -#define GRN_EXPR_TOKEN_EXACT 61 -#define GRN_EXPR_TOKEN_PARTIAL 62 -#define GRN_EXPR_TOKEN_UNSPLIT 63 -#define GRN_EXPR_TOKEN_DECIMAL 64 -#define GRN_EXPR_TOKEN_HEX_INTEGER 65 -#define GRN_EXPR_TOKEN_STRING 66 -#define GRN_EXPR_TOKEN_BOOLEAN 67 -#define GRN_EXPR_TOKEN_NULL 68 -#define GRN_EXPR_TOKEN_BRACKETL 69 -#define GRN_EXPR_TOKEN_BRACKETR 70 -#define GRN_EXPR_TOKEN_DOT 71 -#define GRN_EXPR_TOKEN_NONEXISTENT_COLUMN 72 +#define GRN_EXPR_TOKEN_REGEXP 47 +#define GRN_EXPR_TOKEN_SHIFTL 48 +#define GRN_EXPR_TOKEN_SHIFTR 49 +#define GRN_EXPR_TOKEN_SHIFTRR 50 +#define GRN_EXPR_TOKEN_PLUS 51 +#define GRN_EXPR_TOKEN_MINUS 52 +#define GRN_EXPR_TOKEN_STAR 53 +#define GRN_EXPR_TOKEN_SLASH 54 +#define GRN_EXPR_TOKEN_MOD 55 +#define GRN_EXPR_TOKEN_DELETE 56 +#define GRN_EXPR_TOKEN_INCR 57 +#define GRN_EXPR_TOKEN_DECR 58 +#define GRN_EXPR_TOKEN_NOT 59 +#define GRN_EXPR_TOKEN_BITWISE_NOT 60 +#define GRN_EXPR_TOKEN_ADJUST 61 +#define GRN_EXPR_TOKEN_EXACT 62 +#define GRN_EXPR_TOKEN_PARTIAL 63 +#define GRN_EXPR_TOKEN_UNSPLIT 64 +#define GRN_EXPR_TOKEN_DECIMAL 65 +#define GRN_EXPR_TOKEN_HEX_INTEGER 66 +#define GRN_EXPR_TOKEN_STRING 67 +#define GRN_EXPR_TOKEN_BOOLEAN 68 +#define GRN_EXPR_TOKEN_NULL 69 +#define GRN_EXPR_TOKEN_BRACKETL 70 +#define GRN_EXPR_TOKEN_BRACKETR 71 +#define GRN_EXPR_TOKEN_DOT 72 +#define GRN_EXPR_TOKEN_NONEXISTENT_COLUMN 73 diff --git a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon index 322d7ac8264..1d812655d70 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon +++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon @@ -219,6 +219,9 @@ relational_expression ::= relational_expression PREFIX shift_expression. { relational_expression ::= relational_expression SUFFIX shift_expression. { grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SUFFIX, 2); } +relational_expression ::= relational_expression REGEXP shift_expression. { + grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_REGEXP, 2); +} shift_expression ::= additive_expression. shift_expression ::= shift_expression SHIFTL additive_expression. { diff --git a/storage/mroonga/vendor/groonga/lib/grn_expr.h b/storage/mroonga/vendor/groonga/lib/grn_expr.h index 0a21f72bb92..75871491d7c 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_expr.h +++ b/storage/mroonga/vendor/groonga/lib/grn_expr.h @@ -44,7 +44,10 @@ typedef grn_bool (*grn_scan_info_each_arg_callback)(grn_ctx *ctx, grn_obj *obj, scan_info *grn_scan_info_open(grn_ctx *ctx, int start); void grn_scan_info_close(grn_ctx *ctx, scan_info *si); void grn_scan_info_put_index(grn_ctx *ctx, scan_info *si, grn_obj *index, - uint32_t sid, int32_t weight); + uint32_t sid, int32_t weight, + grn_obj *scorer, + grn_obj *scorer_args_expr, + uint32_t scorer_args_expr_offset); scan_info **grn_scan_info_put_logical_op(grn_ctx *ctx, scan_info **sis, int *ip, grn_operator op, int start); int grn_scan_info_get_flags(scan_info *si); @@ -59,12 +62,16 @@ int grn_scan_info_get_max_interval(scan_info *si); void grn_scan_info_set_max_interval(scan_info *si, int max_interval); int grn_scan_info_get_similarity_threshold(scan_info *si); void grn_scan_info_set_similarity_threshold(scan_info *si, int similarity_threshold); -grn_obj *grn_scan_info_get_scorer(scan_info *si); -void grn_scan_info_set_scorer(scan_info *si, grn_obj *scorer); grn_bool grn_scan_info_push_arg(scan_info *si, grn_obj *arg); grn_obj *grn_scan_info_get_arg(grn_ctx *ctx, scan_info *si, int i); -int32_t grn_expr_code_get_weight(grn_ctx *ctx, grn_expr_code *ec); +int32_t grn_expr_code_get_weight(grn_ctx *ctx, grn_expr_code *ec, uint32_t *offset); +grn_rc grn_expr_code_inspect_indented(grn_ctx *ctx, + grn_obj *buffer, + grn_expr_code *code, + const char *indent); +void grn_p_expr_code(grn_ctx *ctx, grn_expr_code *code); + void grn_expr_take_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj); grn_obj *grn_expr_alloc_const(grn_ctx *ctx, grn_obj *expr); @@ -73,3 +80,4 @@ grn_obj *grn_expr_alloc_const(grn_ctx *ctx, grn_obj *expr); #endif #endif /* GRN_EXPR_H */ + diff --git a/storage/mroonga/vendor/groonga/lib/grn_hash.h b/storage/mroonga/vendor/groonga/lib/grn_hash.h index 44f5bcba0ed..d50836d80f1 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_hash.h +++ b/storage/mroonga/vendor/groonga/lib/grn_hash.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 @@ -187,7 +187,15 @@ GRN_API grn_id grn_table_queue_tail(grn_table_queue *queue); /**** grn_hash ****/ #define GRN_HASH_TINY (0x01<<6) -#define GRN_HASH_MAX_KEY_SIZE GRN_TABLE_MAX_KEY_SIZE +#define GRN_HASH_MAX_KEY_SIZE_NORMAL GRN_TABLE_MAX_KEY_SIZE +#define GRN_HASH_MAX_KEY_SIZE_LARGE (0xffff) + +#define GRN_HASH_IS_LARGE_KEY(hash)\ + ((hash)->key_size > GRN_HASH_MAX_KEY_SIZE_NORMAL) + +typedef struct _grn_hash_header_common grn_hash_header_common; +typedef struct _grn_hash_header_normal grn_hash_header_normal; +typedef struct _grn_hash_header_large grn_hash_header_large; struct _grn_hash { grn_db_obj obj; @@ -205,7 +213,11 @@ struct _grn_hash { /* For grn_io_hash. */ grn_io *io; - struct grn_hash_header *header; + union { + grn_hash_header_common *common; + grn_hash_header_normal *normal; + grn_hash_header_large *large; + } header; uint32_t *lock; // uint32_t nref; // unsigned int max_n_subrecs; @@ -230,24 +242,36 @@ struct _grn_hash { grn_tiny_bitmap bitmap; }; -/* Header of grn_io_hash. */ -struct grn_hash_header { - uint32_t flags; - grn_encoding encoding; - uint32_t key_size; - uint32_t value_size; - grn_id tokenizer; - uint32_t curr_rec; - int32_t curr_key; - uint32_t idx_offset; - uint32_t entry_size; - uint32_t max_offset; - uint32_t n_entries; - uint32_t n_garbages; - uint32_t lock; - grn_id normalizer; - uint32_t reserved[15]; - grn_id garbages[GRN_HASH_MAX_KEY_SIZE]; +#define GRN_HASH_HEADER_COMMON_FIELDS\ + uint32_t flags;\ + grn_encoding encoding;\ + uint32_t key_size;\ + uint32_t value_size;\ + grn_id tokenizer;\ + uint32_t curr_rec;\ + int32_t curr_key;\ + uint32_t idx_offset;\ + uint32_t entry_size;\ + uint32_t max_offset;\ + uint32_t n_entries;\ + uint32_t n_garbages;\ + uint32_t lock;\ + grn_id normalizer;\ + uint32_t reserved[15] + +struct _grn_hash_header_common { + GRN_HASH_HEADER_COMMON_FIELDS; +}; + +struct _grn_hash_header_normal { + GRN_HASH_HEADER_COMMON_FIELDS; + grn_id garbages[GRN_HASH_MAX_KEY_SIZE_NORMAL]; + grn_table_queue queue; +}; + +struct _grn_hash_header_large { + GRN_HASH_HEADER_COMMON_FIELDS; + grn_id garbages[GRN_HASH_MAX_KEY_SIZE_LARGE]; grn_table_queue queue; }; diff --git a/storage/mroonga/vendor/groonga/lib/grn_ii.h b/storage/mroonga/vendor/groonga/lib/grn_ii.h index 0d44079a38c..fe9b1ec26a4 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_ii.h +++ b/storage/mroonga/vendor/groonga/lib/grn_ii.h @@ -152,6 +152,8 @@ struct _grn_select_optarg { void *func_arg; int max_size; grn_obj *scorer; + grn_obj *scorer_args_expr; + unsigned int scorer_args_expr_offset; }; GRN_API grn_rc grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id id, diff --git a/storage/mroonga/vendor/groonga/lib/grn_io.h b/storage/mroonga/vendor/groonga/lib/grn_io.h index 00a1c3a0936..14f5e496f8b 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_io.h +++ b/storage/mroonga/vendor/groonga/lib/grn_io.h @@ -380,7 +380,7 @@ uint32_t grn_expire(grn_ctx *ctx, int count_thresh, uint32_t limit); *_p++ = _v & 0xff; \ } else { \ *_p++ = 0x8f; \ - memcpy(_p, &_v, sizeof(uint32_t));\ + grn_memcpy(_p, &_v, sizeof(uint32_t));\ _p += sizeof(uint32_t); \ } \ p = _p; \ @@ -395,7 +395,7 @@ uint32_t grn_expire(grn_ctx *ctx, int count_thresh, uint32_t limit); switch (_v >> 4) { \ case 0x08 : \ if (_v == 0x8f) { \ - memcpy(&_v, _p, sizeof(uint32_t));\ + grn_memcpy(&_v, _p, sizeof(uint32_t));\ _p += sizeof(uint32_t); \ } \ break; \ diff --git a/storage/mroonga/vendor/groonga/lib/grn_logger.h b/storage/mroonga/vendor/groonga/lib/grn_logger.h new file mode 100644 index 00000000000..95186ca107a --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/grn_logger.h @@ -0,0 +1,37 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + 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 + 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_LOGGER_H +#define GRN_LOGGER_H + +#include "grn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void grn_logger_init(void); +void grn_logger_fin(grn_ctx *ctx); + +void grn_query_logger_init(void); +void grn_query_logger_fin(grn_ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_LOGGER_H */ diff --git a/storage/mroonga/vendor/groonga/lib/grn_msgpack.h b/storage/mroonga/vendor/groonga/lib/grn_msgpack.h new file mode 100644 index 00000000000..db86987c08a --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/grn_msgpack.h @@ -0,0 +1,48 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + 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 + 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_MSGPACK_H +#define GRN_MSGPACK_H + +#ifdef GRN_WITH_MESSAGE_PACK +# include <msgpack.h> + +# if MSGPACK_VERSION_MAJOR < 1 +typedef unsigned int msgpack_size_t; + +# define msgpack_pack_str(packer, size) msgpack_pack_raw(packer, size) +# define msgpack_pack_str_body(packer, value, size) \ + msgpack_pack_raw_body(packer, value, size) + +# define MSGPACK_OBJECT_STR MSGPACK_OBJECT_RAW +# define MSGPACK_OBJECT_FLOAT MSGPACK_OBJECT_DOUBLE + +# define MSGPACK_OBJECT_STR_PTR(object) (object)->via.raw.ptr +# define MSGPACK_OBJECT_STR_SIZE(object) (object)->via.raw.size + +# define MSGPACK_OBJECT_FLOAT_VALUE(object) (object)->via.dec +# else /* MSGPACK_VERSION_MAJOR < 1 */ +typedef size_t msgpack_size_t; + +# define MSGPACK_OBJECT_STR_PTR(object) (object)->via.str.ptr +# define MSGPACK_OBJECT_STR_SIZE(object) (object)->via.str.size + +# define MSGPACK_OBJECT_FLOAT_VALUE(object) (object)->via.f64 +# endif /* MSGPACK_VERSION_MAJOR < 1 */ +#endif /* GRN_WITH_MESSAGE_PACK */ + +#endif /* GRN_MSGPACK_H */ diff --git a/storage/mroonga/vendor/groonga/lib/grn_plugin.h b/storage/mroonga/vendor/groonga/lib/grn_plugin.h index 121c3143faf..75b29f56cc9 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_plugin.h +++ b/storage/mroonga/vendor/groonga/lib/grn_plugin.h @@ -37,6 +37,7 @@ typedef void * grn_dl_symbol; typedef struct _grn_plugin grn_plugin; struct _grn_plugin { + char path[PATH_MAX]; grn_dl dl; grn_plugin_func init_func; grn_plugin_func register_func; diff --git a/storage/mroonga/vendor/groonga/lib/grn_rset.h b/storage/mroonga/vendor/groonga/lib/grn_rset.h index 4fa0d08355a..b92e21162df 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_rset.h +++ b/storage/mroonga/vendor/groonga/lib/grn_rset.h @@ -53,7 +53,7 @@ typedef struct { #define GRN_RSET_SUBRECS_NTH(subrecs,size,n) \ ((double *)((byte *)subrecs + n * GRN_RSET_SUBREC_SIZE(size))) #define GRN_RSET_SUBRECS_COPY(subrecs,size,n,src) \ - (memcpy(GRN_RSET_SUBRECS_NTH(subrecs, size, n), src, GRN_RSET_SUBREC_SIZE(size))) + (grn_memcpy(GRN_RSET_SUBRECS_NTH(subrecs, size, n), src, GRN_RSET_SUBREC_SIZE(size))) #define GRN_RSET_SUBRECS_SIZE(subrec_size,n) \ (GRN_RSET_SUBREC_SIZE(subrec_size) * n) diff --git a/storage/mroonga/vendor/groonga/lib/grn_scorer.h b/storage/mroonga/vendor/groonga/lib/grn_scorer.h index 898a83366b0..05f982180db 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_scorer.h +++ b/storage/mroonga/vendor/groonga/lib/grn_scorer.h @@ -39,6 +39,8 @@ struct _grn_scorer_matched_record { uint64_t n_candidates; uint32_t n_tokens; int weight; + grn_obj *args_expr; + unsigned int args_expr_offset; }; diff --git a/storage/mroonga/vendor/groonga/lib/grn_store.h b/storage/mroonga/vendor/groonga/lib/grn_store.h index 742d11341fc..9e1223e0685 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_store.h +++ b/storage/mroonga/vendor/groonga/lib/grn_store.h @@ -71,8 +71,6 @@ void *grn_ra_ref_cache(grn_ctx *ctx, grn_ra *ra, grn_id id, grn_ra_cache *cache) /**** variable sized elements ****/ -extern grn_bool grn_ja_skip_same_value_put; - typedef struct _grn_ja grn_ja; struct _grn_ja { diff --git a/storage/mroonga/vendor/groonga/lib/grn_str.h b/storage/mroonga/vendor/groonga/lib/grn_str.h index ade8c04053e..e6fab611ccd 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_str.h +++ b/storage/mroonga/vendor/groonga/lib/grn_str.h @@ -54,6 +54,7 @@ GRN_API int grn_atoi(const char *nptr, const char *end, const char **rest); GRN_API unsigned int grn_atoui(const char *nptr, const char *end, const char **rest); unsigned int grn_htoui(const char *nptr, const char *end, const char **rest); GRN_API int64_t grn_atoll(const char *nptr, const char *end, const char **rest); +GRN_API uint64_t grn_atoull(const char *nptr, const char *end, const char **rest); grn_rc grn_itoa(int i, char *p, char *end, char **rest); grn_rc grn_lltoa(int64_t i, char *p, char *end, char **rest); grn_rc grn_ulltoa(uint64_t i, char *p, char *end, char **rest); diff --git a/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h b/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h index 81175bc432f..fec62224418 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h +++ b/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h @@ -26,6 +26,11 @@ extern "C" { #endif +#define GRN_TOKENIZER_BEGIN_MARK_UTF8 "\xEF\xBF\xAF" +#define GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN 3 +#define GRN_TOKENIZER_END_MARK_UTF8 "\xEF\xBF\xB0" +#define GRN_TOKENIZER_END_MARK_UTF8_LEN 3 + typedef enum { GRN_TOKEN_CURSOR_DOING = 0, GRN_TOKEN_CURSOR_DONE, diff --git a/storage/mroonga/vendor/groonga/lib/grn_util.h b/storage/mroonga/vendor/groonga/lib/grn_util.h index 84aa357e4e3..f94140dcb66 100644 --- a/storage/mroonga/vendor/groonga/lib/grn_util.h +++ b/storage/mroonga/vendor/groonga/lib/grn_util.h @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2010-2011 Brazil +/* Copyright(C) 2010-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -29,6 +29,8 @@ GRN_API grn_rc grn_normalize_offset_and_limit(grn_ctx *ctx, int size, int *offse GRN_API const char *grn_win32_base_dir(void); GRN_API char *grn_path_separator_to_system(char *dest, char *groonga_path); +int grn_mkstemp(char *path_template); + #ifdef __cplusplus } #endif diff --git a/storage/mroonga/vendor/groonga/lib/hash.c b/storage/mroonga/vendor/groonga/lib/hash.c index 22491c5fc8b..2c44f25cc20 100644 --- a/storage/mroonga/vendor/groonga/lib/hash.c +++ b/storage/mroonga/vendor/groonga/lib/hash.c @@ -1,6 +1,6 @@ /* -*- 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 @@ -700,7 +700,7 @@ grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id, void *valuebuf) void * const value = grn_array_get_value_inline(ctx, array, id); if (value) { if (valuebuf) { - memcpy(valuebuf, value, array->value_size); + grn_memcpy(valuebuf, value, array->value_size); } return array->value_size; } @@ -724,7 +724,7 @@ grn_array_set_value_inline(grn_ctx *ctx, grn_array *array, grn_id id, switch ((flags & GRN_OBJ_SET_MASK)) { case GRN_OBJ_SET : - memcpy(entry, value, array->value_size); + grn_memcpy(entry, value, array->value_size); return GRN_SUCCESS; case GRN_OBJ_INCR : switch (array->value_size) { @@ -863,7 +863,7 @@ grn_array_copy_sort_key(grn_ctx *ctx, grn_array *array, if (!array->keys) { return ctx->rc; } - memcpy(array->keys, keys, sizeof(grn_table_sort_key) * n_keys); + grn_memcpy(array->keys, keys, sizeof(grn_table_sort_key) * n_keys); array->n_keys = n_keys; return GRN_SUCCESS; } @@ -1167,7 +1167,11 @@ grn_array_unblock(grn_ctx *ctx, grn_array *array) /* grn_hash : hash table */ #define GRN_HASH_MAX_SEGMENT 0x400 -#define GRN_HASH_HEADER_SIZE 0x9000 +#define GRN_HASH_HEADER_SIZE_NORMAL 0x9000 +#define GRN_HASH_HEADER_SIZE_LARGE\ + (GRN_HASH_HEADER_SIZE_NORMAL +\ + (sizeof(grn_id) *\ + (GRN_HASH_MAX_KEY_SIZE_LARGE - GRN_HASH_MAX_KEY_SIZE_NORMAL))) #define GRN_HASH_SEGMENT_SIZE 0x400000 #define W_OF_KEY_IN_A_SEGMENT 22 #define IDX_MASK_IN_A_SEGMENT 0xfffff @@ -1298,7 +1302,7 @@ inline static grn_id * grn_hash_idx_at(grn_ctx *ctx, grn_hash *hash, grn_id id) { if (grn_hash_is_io_hash(hash)) { - id = (id & *hash->max_offset) + hash->header->idx_offset; + id = (id & *hash->max_offset) + hash->header.common->idx_offset; return grn_io_hash_idx_at(ctx, hash, id); } else { return hash->index + (id & *hash->max_offset); @@ -1380,15 +1384,18 @@ grn_io_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash, key_offset = entry->key.offset; } else { uint32_t segment_id; + grn_hash_header_common *header; + + header = hash->header.common; if (key_size >= GRN_HASH_SEGMENT_SIZE) { return GRN_INVALID_ARGUMENT; } - key_offset = hash->header->curr_key; + key_offset = header->curr_key; segment_id = (key_offset + key_size) >> W_OF_KEY_IN_A_SEGMENT; if ((key_offset >> W_OF_KEY_IN_A_SEGMENT) != segment_id) { - key_offset = hash->header->curr_key = segment_id << W_OF_KEY_IN_A_SEGMENT; + key_offset = header->curr_key = segment_id << W_OF_KEY_IN_A_SEGMENT; } - hash->header->curr_key += key_size; + header->curr_key += key_size; entry->key.offset = key_offset; } @@ -1397,7 +1404,7 @@ grn_io_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash, if (!key_ptr) { return GRN_NO_MEMORY_AVAILABLE; } - memcpy(key_ptr, key, key_size); + grn_memcpy(key_ptr, key, key_size); } return GRN_SUCCESS; } @@ -1410,7 +1417,7 @@ grn_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash, if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) { if (grn_hash_is_io_hash(hash)) { if (key_size <= sizeof(entry->io_entry.key.buf)) { - memcpy(entry->io_entry.key.buf, key, key_size); + grn_memcpy(entry->io_entry.key.buf, key, key_size); entry->io_entry.flag = HASH_IMMEDIATE; } else { const grn_rc rc = @@ -1425,7 +1432,7 @@ grn_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash, entry->io_entry.key_size = key_size; } else { if (key_size <= sizeof(entry->tiny_entry.key.buf)) { - memcpy(entry->tiny_entry.key.buf, key, key_size); + grn_memcpy(entry->tiny_entry.key.buf, key, key_size); entry->tiny_entry.flag = HASH_IMMEDIATE; } else { grn_ctx * const ctx = hash->ctx; @@ -1433,7 +1440,7 @@ grn_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash, if (!entry->tiny_entry.key.ptr) { return GRN_NO_MEMORY_AVAILABLE; } - memcpy(entry->tiny_entry.key.ptr, key, key_size); + grn_memcpy(entry->tiny_entry.key.ptr, key, key_size); entry->tiny_entry.flag = 0; } entry->tiny_entry.hash_value = hash_value; @@ -1444,7 +1451,7 @@ grn_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash, *(uint32_t *)entry->plain_entry.key = hash_value; } else { entry->rich_entry.hash_value = hash_value; - memcpy(entry->rich_entry.key_and_value, key, key_size); + grn_memcpy(entry->rich_entry.key_and_value, key, key_size); } } return GRN_SUCCESS; @@ -1537,7 +1544,8 @@ grn_io_hash_calculate_entry_size(uint32_t key_size, uint32_t value_size, } static grn_io * -grn_io_hash_create_io(grn_ctx *ctx, const char *path, uint32_t entry_size) +grn_io_hash_create_io(grn_ctx *ctx, const char *path, + uint32_t header_size, uint32_t entry_size) { uint32_t w_of_element = 0; grn_io_array_spec array_spec[4]; @@ -1555,7 +1563,7 @@ grn_io_hash_create_io(grn_ctx *ctx, const char *path, uint32_t entry_size) array_spec[GRN_HASH_INDEX_SEGMENT].max_n_segments = 1U << (30 - (22 - 2)); array_spec[GRN_HASH_BITMAP_SEGMENT].w_of_element = 0; array_spec[GRN_HASH_BITMAP_SEGMENT].max_n_segments = 1U << (30 - (22 + 3)); - return grn_io_create_with_array(ctx, path, GRN_HASH_HEADER_SIZE, + return grn_io_create_with_array(ctx, path, header_size, GRN_HASH_SEGMENT_SIZE, grn_io_auto, 4, array_spec); } @@ -1566,12 +1574,17 @@ grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path, grn_encoding encoding, uint32_t init_size) { grn_io *io; - struct grn_hash_header *header; - uint32_t entry_size, max_offset; + grn_hash_header_common *header; + uint32_t header_size, entry_size, max_offset; + if (key_size <= GRN_HASH_MAX_KEY_SIZE_NORMAL) { + header_size = GRN_HASH_HEADER_SIZE_NORMAL; + } else { + header_size = GRN_HASH_HEADER_SIZE_LARGE; + } entry_size = grn_io_hash_calculate_entry_size(key_size, value_size, flags); - io = grn_io_hash_create_io(ctx, path, entry_size); + io = grn_io_hash_create_io(ctx, path, header_size, entry_size); if (!io) { return GRN_NO_MEMORY_AVAILABLE; } @@ -1587,6 +1600,8 @@ grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path, encoding = ctx->encoding; } + hash->key_size = key_size; + header = grn_io_header(io); header->flags = flags; header->encoding = encoding; @@ -1610,11 +1625,18 @@ grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path, header->normalizer = GRN_ID_NIL; } GRN_PTR_INIT(&(hash->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL); - grn_table_queue_init(ctx, &header->queue); + { + grn_table_queue *queue; + if (GRN_HASH_IS_LARGE_KEY(hash)) { + queue = &(((grn_hash_header_large *)(header))->queue); + } else { + queue = &(((grn_hash_header_normal *)(header))->queue); + } + grn_table_queue_init(ctx, queue); + } hash->obj.header.flags = header->flags; hash->ctx = ctx; - hash->key_size = key_size; hash->encoding = encoding; hash->value_size = value_size; hash->entry_size = entry_size; @@ -1622,7 +1644,7 @@ grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path, hash->n_entries = &header->n_entries; hash->max_offset = &header->max_offset; hash->io = io; - hash->header = header; + hash->header.common = header; hash->lock = &header->lock; hash->tokenizer = NULL; return GRN_SUCCESS; @@ -1711,7 +1733,7 @@ grn_hash_create(grn_ctx *ctx, const char *path, uint32_t key_size, uint32_t valu if (!ctx) { return NULL; } - if (key_size > GRN_HASH_MAX_KEY_SIZE) { + if (key_size > GRN_HASH_MAX_KEY_SIZE_LARGE) { return NULL; } hash = (grn_hash *)GRN_MALLOC(sizeof(grn_hash)); @@ -1732,7 +1754,7 @@ grn_hash_open(grn_ctx *ctx, const char *path) if (ctx) { grn_io * const io = grn_io_open(ctx, path, grn_io_auto); if (io) { - struct grn_hash_header * const header = grn_io_header(io); + grn_hash_header_common * const header = grn_io_header(io); if (grn_io_get_type(io) == GRN_TABLE_HASH_KEY) { grn_hash * const hash = (grn_hash *)GRN_MALLOC(sizeof(grn_hash)); if (hash) { @@ -1747,7 +1769,7 @@ grn_hash_open(grn_ctx *ctx, const char *path) hash->n_entries = &header->n_entries; hash->max_offset = &header->max_offset; hash->io = io; - hash->header = header; + hash->header.common = header; hash->lock = &header->lock; hash->tokenizer = grn_ctx_at(ctx, header->tokenizer); if (header->flags & GRN_OBJ_KEY_NORMALIZE) { @@ -1911,7 +1933,7 @@ grn_hash_reset(grn_ctx *ctx, grn_hash *hash, uint32_t expected_n_entries) if (grn_hash_is_io_hash(hash)) { uint32_t i; - src_offset = hash->header->idx_offset; + src_offset = hash->header.common->idx_offset; dest_offset = MAX_INDEX_SIZE - src_offset; for (i = 0; i < new_index_size; i += (IDX_MASK_IN_A_SEGMENT + 1)) { /* @@ -1979,7 +2001,7 @@ grn_hash_reset(grn_ctx *ctx, grn_hash *hash, uint32_t expected_n_entries) } if (grn_hash_is_io_hash(hash)) { - hash->header->idx_offset = dest_offset; + hash->header.common->idx_offset = dest_offset; } else { grn_id * const old_index = hash->index; hash->index = new_index; @@ -2038,15 +2060,22 @@ grn_io_hash_add(grn_ctx *ctx, grn_hash *hash, uint32_t hash_value, { grn_id entry_id; grn_hash_entry *entry; - struct grn_hash_header * const header = hash->header; + grn_hash_header_common * const header = hash->header.common; + grn_id *garbages; - entry_id = header->garbages[key_size - 1]; + if (GRN_HASH_IS_LARGE_KEY(hash)) { + garbages = hash->header.large->garbages; + } else { + garbages = hash->header.normal->garbages; + } + + entry_id = garbages[key_size - 1]; if (entry_id) { entry = grn_io_hash_entry_at(ctx, hash, entry_id, GRN_TABLE_ADD); if (!entry) { return GRN_ID_NIL; } - header->garbages[key_size - 1] = *(grn_id *)entry; + garbages[key_size - 1] = *(grn_id *)entry; if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) { /* keep entry->io_entry's hash_value, flag, key_size and key. */ memset(entry->io_entry.value, 0, header->value_size); @@ -2282,7 +2311,7 @@ grn_hash_get_key(grn_ctx *ctx, grn_hash *hash, grn_id id, void *keybuf, int bufs } key_size = grn_hash_entry_get_key_size(hash, entry); if (bufsize >= key_size) { - memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size); + grn_memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size); } return key_size; } @@ -2320,7 +2349,7 @@ grn_hash_get_value(grn_ctx *ctx, grn_hash *hash, grn_id id, void *valuebuf) return 0; } if (valuebuf) { - memcpy(valuebuf, value, hash->value_size); + grn_memcpy(valuebuf, value, hash->value_size); } return hash->value_size; } @@ -2353,14 +2382,14 @@ grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id, } key_size = grn_hash_entry_get_key_size(hash, entry); if (bufsize >= key_size) { - memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size); + grn_memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size); } value = grn_hash_entry_get_value(hash, entry); if (!value) { return 0; } if (valuebuf) { - memcpy(valuebuf, value, hash->value_size); + grn_memcpy(valuebuf, value, hash->value_size); } return key_size; } @@ -2400,7 +2429,7 @@ grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id, switch (flags & GRN_OBJ_SET_MASK) { case GRN_OBJ_SET : - memcpy(entry_value, value, hash->value_size); + grn_memcpy(entry_value, value, hash->value_size); return GRN_SUCCESS; case GRN_OBJ_INCR : switch (hash->value_size) { @@ -2436,9 +2465,14 @@ grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id, *ep = GARBAGE;\ if (grn_hash_is_io_hash(hash)) {\ uint32_t size = key_size - 1;\ - struct grn_hash_header *hh = hash->header;\ - ee->key = hh->garbages[size];\ - hh->garbages[size] = e;\ + grn_id *garbages;\ + if (GRN_HASH_IS_LARGE_KEY(hash)) {\ + garbages = hash->header.large->garbages;\ + } else {\ + garbages = hash->header.normal->garbages;\ + }\ + ee->key = garbages[size];\ + garbages[size] = e;\ grn_io_array_bit_off(ctx, hash->io, GRN_HASH_BITMAP_SEGMENT, e);\ } else {\ ee->key = hash->garbages;\ @@ -2537,7 +2571,7 @@ grn_hash_cursor_close(grn_ctx *ctx, grn_hash_cursor *c) } #define HASH_CURR_MAX(hash) \ - ((grn_hash_is_io_hash(hash)) ? (hash)->header->curr_rec : (hash)->a.max) + ((grn_hash_is_io_hash(hash)) ? (hash)->header.common->curr_rec : (hash)->a.max) grn_hash_cursor * grn_hash_cursor_open(grn_ctx *ctx, grn_hash *hash, @@ -3061,7 +3095,7 @@ void grn_hash_check(grn_ctx *ctx, grn_hash *hash) { char buf[8]; - struct grn_hash_header *h = hash->header; + grn_hash_header_common *h = hash->header.common; GRN_OUTPUT_ARRAY_OPEN("RESULT", 1); GRN_OUTPUT_MAP_OPEN("SUMMARY", 25); GRN_OUTPUT_CSTR("flags"); @@ -3158,7 +3192,7 @@ subrecs_push(byte *subrecs, int size, int n_subrecs, int score, void *body, int } v = subrecs + n * (size + GRN_RSET_SCORE_SIZE); *((int *)v) = score; - memcpy(v + GRN_RSET_SCORE_SIZE, body, size); + grn_memcpy(v + GRN_RSET_SCORE_SIZE, body, size); } inline static void @@ -3191,8 +3225,8 @@ subrecs_replace_min(byte *subrecs, int size, int n_subrecs, int score, void *bod } } v = subrecs + n * (size + GRN_RSET_SCORE_SIZE); - memcpy(v, &score, GRN_RSET_SCORE_SIZE); - memcpy(v + GRN_RSET_SCORE_SIZE, body, size); + grn_memcpy(v, &score, GRN_RSET_SCORE_SIZE); + grn_memcpy(v + GRN_RSET_SCORE_SIZE, body, size); } void @@ -3252,7 +3286,7 @@ grn_rhash_group(grn_hash *s, int limit, grn_group_optarg *optarg) if (gkey) { GRN_FREE(gkey); } return NULL; } - memcpy(&h, s, sizeof(grn_hash)); + grn_memcpy(&h, s, sizeof(grn_hash)); g = s; s = &h; if (grn_rhash_init(ctx, g, unit, rsize, s->record_unit, s->key_size, limit)) { diff --git a/storage/mroonga/vendor/groonga/lib/ii.c b/storage/mroonga/vendor/groonga/lib/ii.c index 3b5478f9ea7..2d32df2fd4d 100644 --- a/storage/mroonga/vendor/groonga/lib/ii.c +++ b/storage/mroonga/vendor/groonga/lib/ii.c @@ -19,6 +19,12 @@ #include <fcntl.h> #include <string.h> #include <sys/stat.h> +#include <math.h> + +#ifdef WIN32 +# include <io.h> +# include <share.h> +#endif /* WIN32 */ #include "grn_ii.h" #include "grn_ctx_impl.h" @@ -42,8 +48,8 @@ #define S_CHUNK (1 << GRN_II_W_CHUNK) #define W_SEGMENT 18 #define S_SEGMENT (1 << W_SEGMENT) -#define W_ARRAY_ELEMENT 3 -#define S_ARRAY_ELEMENT (1 << W_ARRAY_ELEMENT) +#define W_ARRAY_ELEMENT 3 +#define S_ARRAY_ELEMENT (1 << W_ARRAY_ELEMENT) #define W_ARRAY (W_SEGMENT - W_ARRAY_ELEMENT) #define ARRAY_MASK_IN_A_SEGMENT ((1 << W_ARRAY) - 1) #define NOT_ASSIGNED 0xffffffff @@ -1408,7 +1414,7 @@ pack(uint32_t *p, uint32_t i, uint8_t *freq, uint8_t *rp) } } rp = pack_(p - i, i, w, rp); - memcpy(rp, ebuf, ep - ebuf); + grn_memcpy(rp, ebuf, ep - ebuf); return rp + (ep - ebuf); } @@ -1560,7 +1566,7 @@ grn_p_encv(grn_ctx *ctx, datavec *dv, uint32_t dvlen, uint8_t *res) case 0x08 : \ if (_v == 0x8f) { \ if (_p + sizeof(uint32_t) > pe) { return 0; } \ - memcpy(&_v, _p, sizeof(uint32_t)); \ + grn_memcpy(&_v, _p, sizeof(uint32_t)); \ _p += sizeof(uint32_t); \ } \ break; \ @@ -2004,7 +2010,7 @@ buffer_put(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_term *bt, buffer_rec *r_curr, *r_start = NULL; uint16_t last = 0, *lastp = &bt->pos_in_buffer, pos = BUFFER_REC_POS(b, rnew); int vdelta = 0, delta, delta0 = 0, vhops = 0, nhops = 0, reset = 1; - memcpy(NEXT_ADDR(rnew), bs, size - sizeof(buffer_rec)); + grn_memcpy(NEXT_ADDR(rnew), bs, size - sizeof(buffer_rec)); for (;;) { if (!*lastp) { rnew->step = 0; @@ -2468,7 +2474,7 @@ chunk_flush(grn_ctx *ctx, grn_ii *ii, chunk_info *cinfo, uint8_t *enc, uint32_t if (encsize) { if (!(rc = chunk_new(ctx, ii, &dcn, encsize))) { if ((dc = WIN_MAP(ii->chunk, ctx, &dw, dcn, 0, encsize, grn_io_wronly))) { - memcpy(dc, enc, encsize); + grn_memcpy(dc, enc, encsize); grn_io_win_unmap(&dw); cinfo->segno = dcn; cinfo->size = encsize; @@ -2612,7 +2618,7 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h, if (!bt->pos_in_buffer) { GRN_ASSERT(!bt->size_in_buffer); if (bt->size_in_chunk) { - memcpy(dcp, sc + bt->pos_in_chunk, bt->size_in_chunk); + grn_memcpy(dcp, sc + bt->pos_in_chunk, bt->size_in_chunk); bt->pos_in_chunk = (uint32_t)(dcp - dc); dcp += bt->size_in_chunk; } @@ -2779,7 +2785,10 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h, if (sb->header.chunk_size + S_SEGMENT <= (dcp - dc) + encsize) { int i; - char buf[255], *bufp; +#define BUF_SIZE 255 + char buf[BUF_SIZE], *bufp, *buf_end; + buf_end = buf + BUF_SIZE; +#undef BUF_SIZE GRN_LOG(ctx, GRN_LOG_NOTICE, "cs(%d)+(%d)=(%d)<=(%" GRN_FMT_LLD ")+(%d)=(%" GRN_FMT_LLD ")", sb->header.chunk_size, S_SEGMENT, sb->header.chunk_size + S_SEGMENT, @@ -2788,7 +2797,10 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h, GRN_LOG(ctx, GRN_LOG_NOTICE, "rdv[%d] data_size=%d, flags=%d", j, rdv[j].data_size, rdv[j].flags); for (i = 0, bufp = buf; i < rdv[j].data_size;) { - bufp += sprintf(bufp, " %d", rdv[j].data[i]); + bufp += grn_snprintf(bufp, + buf_end - bufp, + buf_end - bufp, + " %d", rdv[j].data[i]); i++; if (!(i % 32) || i == rdv[j].data_size) { GRN_LOG(ctx, GRN_LOG_NOTICE, "rdv[%d].data[%d]%s", j, i, buf); @@ -2801,7 +2813,10 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h, GRN_LOG(ctx, GRN_LOG_NOTICE, "dv[%d] data_size=%d, flags=%d", j, dv[j].data_size, dv[j].flags); for (i = 0, bufp = buf; i < dv[j].data_size;) { - bufp += sprintf(bufp, " %d", dv[j].data[i]); + bufp += grn_snprintf(bufp, + buf_end - bufp, + buf_end - bufp, + " %d", dv[j].data[i]); i++; if (!(i % 32) || i == dv[j].data_size) { GRN_LOG(ctx, GRN_LOG_NOTICE, "dv[%d].data[%d]%s", j, i, buf); @@ -2890,7 +2905,7 @@ buffer_flush(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h) sb->header.chunk_size, grn_io_rdonly))) { uint16_t n = sb->header.nterms; memset(db, 0, S_SEGMENT); - memcpy(db->terms, sb->terms, n * sizeof(buffer_term)); + grn_memcpy(db->terms, sb->terms, n * sizeof(buffer_term)); db->header.nterms = n; if (!(rc = buffer_merge(ctx, ii, seg, h, sb, sc, db, dc))) { actual_chunk_size = db->header.chunk_size; @@ -3168,7 +3183,7 @@ term_split(grn_ctx *ctx, grn_obj *lexicon, buffer *sb, buffer *db0, buffer *db1) bt = db0->terms; nt = &db0->header.nterms; for (s = 0; n + 1 < i && s <= th; n++, bt++) { - memcpy(bt, ts[n].bt, sizeof(buffer_term)); + grn_memcpy(bt, ts[n].bt, sizeof(buffer_term)); (*nt)++; s += ts[n].bt->size_in_chunk + 1; } @@ -3176,7 +3191,7 @@ term_split(grn_ctx *ctx, grn_obj *lexicon, buffer *sb, buffer *db0, buffer *db1) bt = db1->terms; nt = &db1->header.nterms; for (; n < i; n++, bt++) { - memcpy(bt, ts[n].bt, sizeof(buffer_term)); + grn_memcpy(bt, ts[n].bt, sizeof(buffer_term)); (*nt)++; } GRN_FREE(ts); @@ -3468,8 +3483,8 @@ _grn_ii_create(grn_ctx *ctx, grn_ii *ii, const char *path, grn_obj *lexicon, uin S_SEGMENT, MAX_PSEG, grn_io_auto, GRN_IO_EXPIRE_SEGMENT); if (!seg) { return NULL; } if (path) { - strcpy(path2, path); - strcat(path2, ".c"); + grn_strcpy(path2, PATH_MAX, path); + grn_strcat(path2, PATH_MAX, ".c"); chunk = grn_io_create(ctx, path2, 0, S_CHUNK, GRN_II_MAX_CHUNK, grn_io_auto, GRN_IO_EXPIRE_SEGMENT); } else { @@ -3525,7 +3540,8 @@ grn_ii_remove(grn_ctx *ctx, const char *path) char buffer[PATH_MAX]; if (!path || strlen(path) > PATH_MAX - 4) { return GRN_INVALID_ARGUMENT; } if ((rc = grn_io_remove(ctx, path))) { goto exit; } - snprintf(buffer, PATH_MAX, "%s.c", path); + grn_snprintf(buffer, PATH_MAX, PATH_MAX, + "%s.c", path); rc = grn_io_remove(ctx, buffer); exit : return rc; @@ -3587,8 +3603,8 @@ grn_ii_open(grn_ctx *ctx, const char *path, grn_obj *lexicon) return NULL; } if (strlen(path) + 6 >= PATH_MAX) { return NULL; } - strcpy(path2, path); - strcat(path2, ".c"); + grn_strcpy(path2, PATH_MAX, path); + grn_strcat(path2, PATH_MAX, ".c"); seg = grn_io_open(ctx, path, grn_io_auto); if (!seg) { return NULL; } chunk = grn_io_open(ctx, path2, grn_io_auto); @@ -4093,6 +4109,41 @@ exit : return c; } +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]) { + c->min = min; + if (c->buf && c->pc.rid < c->min && c->curr_chunk < c->nchunks) { + uint32_t i, skip_chunk = 0; + grn_id rid; + for (i = 0, rid = GRN_ID_NIL; i < c->nchunks; i++) { + rid += c->cinfo[i].dgap; + if (rid < c->min) { + skip_chunk = i + 1; + } else { + rid -= c->cinfo[i].dgap; + break; + } + } + if (skip_chunk > c->curr_chunk) { + c->pc.rid = rid; + c->curr_chunk = skip_chunk; + c->crp = c->cdp + c->cdf; + } + } + } +} + grn_ii_posting * grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c) { @@ -4198,34 +4249,55 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c) } } if (c->stat & BUFFER_USED) { - if (c->nextb) { - uint32_t lrid = c->pb.rid, lsid = c->pb.sid; /* for check */ - buffer_rec *br = BUFFER_REC_AT(c->buf, c->nextb); - if (buffer_is_reused(ctx, c->ii, c)) { - GRN_LOG(ctx, GRN_LOG_NOTICE, "buffer reused(%d,%d)", c->buffer_pseg, *c->ppseg); - // todo : rewind; - } - c->bp = NEXT_ADDR(br); - GRN_B_DEC(c->pb.rid, c->bp); - if ((c->ii->header->flags & GRN_OBJ_WITH_SECTION)) { - GRN_B_DEC(c->pb.sid, c->bp); - } else { - c->pb.sid = 1; - } - if (lrid > c->pb.rid || (lrid == c->pb.rid && lsid >= c->pb.sid)) { - ERR(GRN_FILE_CORRUPT, "brokend!! (%d:%d) -> (%d:%d) (%d->%d)", lrid, lsid, c->pb.rid, c->pb.sid, c->buffer_pseg, *c->ppseg); - } - c->nextb = br->step; - GRN_B_DEC(c->pb.tf, c->bp); - if ((c->ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { - GRN_B_DEC(c->pb.weight, c->bp); + for (;;) { + if (c->nextb) { + uint32_t lrid = c->pb.rid, lsid = c->pb.sid; /* for check */ + buffer_rec *br = BUFFER_REC_AT(c->buf, c->nextb); + if (buffer_is_reused(ctx, c->ii, c)) { + GRN_LOG(ctx, GRN_LOG_NOTICE, "buffer reused(%d,%d)", c->buffer_pseg, *c->ppseg); + // todo : rewind; + } + c->bp = NEXT_ADDR(br); + GRN_B_DEC(c->pb.rid, c->bp); + if ((c->ii->header->flags & GRN_OBJ_WITH_SECTION)) { + GRN_B_DEC(c->pb.sid, c->bp); + } else { + c->pb.sid = 1; + } + if (lrid > c->pb.rid || (lrid == c->pb.rid && lsid >= c->pb.sid)) { + ERR(GRN_FILE_CORRUPT, "brokend!! (%d:%d) -> (%d:%d) (%d->%d)", lrid, lsid, c->pb.rid, c->pb.sid, c->buffer_pseg, *c->ppseg); + } + if (c->pb.rid < c->min) { + c->pb.rid = 0; + if (br->jump > 0) { + buffer_rec *jump_br = BUFFER_REC_AT(c->buf, br->jump); + uint8_t *jump_bp; + uint32_t jump_rid; + jump_bp = NEXT_ADDR(jump_br); + GRN_B_DEC(jump_rid, jump_bp); + if (jump_rid < c->min) { + c->nextb = br->jump; + } else { + c->nextb = br->step; + } + } else { + c->nextb = br->step; + } + continue; + } + c->nextb = br->step; + GRN_B_DEC(c->pb.tf, c->bp); + if ((c->ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { + GRN_B_DEC(c->pb.weight, c->bp); + } else { + c->pb.weight = 0; + } + c->pb.rest = c->pb.tf; + c->pb.pos = 0; } else { - c->pb.weight = 0; + c->pb.rid = 0; } - c->pb.rest = c->pb.tf; - c->pb.pos = 0; - } else { - c->pb.rid = 0; + break; } } if (c->pb.rid) { @@ -4273,6 +4345,10 @@ grn_ii_cursor_next(grn_ctx *ctx, grn_ii_cursor *c) } else { c->post = &c->pb; c->stat |= SOLE_DOC_USED; + if (c->post->rid < c->min) { + c->post = NULL; + return NULL; + } } } return c->post; @@ -4552,10 +4628,11 @@ cursor_heap_recalc_min(cursor_heap *h) } static inline void -cursor_heap_pop(grn_ctx *ctx, cursor_heap *h) +cursor_heap_pop(grn_ctx *ctx, cursor_heap *h, grn_id min) { if (h->n_entries) { grn_ii_cursor *c = h->bins[0]; + grn_ii_cursor_set_min(ctx, c, min); if (!grn_ii_cursor_next(ctx, c)) { grn_ii_cursor_close(ctx, c); h->bins[0] = h->bins[--h->n_entries]; @@ -5402,7 +5479,7 @@ token_info_skip(grn_ctx *ctx, token_info *ti, uint32_t rid, uint32_t sid) if (!(c = cursor_heap_min(ti->cursors))) { return GRN_END_OF_DATA; } p = c->post; if (p->rid > rid || (p->rid == rid && p->sid >= sid)) { break; } - cursor_heap_pop(ctx, ti->cursors); + cursor_heap_pop(ctx, ti->cursors, rid); } ti->pos = p->pos - ti->offset; ti->p = p; @@ -5521,7 +5598,9 @@ token_info_build(grn_ctx *ctx, grn_obj *lexicon, grn_ii *ii, const char *string, token_cursor->curr_size, token_cursor->pos, ef & EX_PREFIX); break; } - if (!ti) { goto exit; } + if (!ti) { + goto exit; + } tis[(*n)++] = ti; } rc = GRN_SUCCESS; @@ -6079,9 +6158,11 @@ grn_ii_select_sequential_search(grn_ctx *ctx, { /* Disabled by default. */ double too_many_index_match_ratio = -1; - const char *too_many_index_match_ratio_env = - getenv("GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO"); - if (too_many_index_match_ratio_env) { + 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); } @@ -6161,7 +6242,6 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_ grn_wv_mode wvm = grn_wv_none; grn_obj *lexicon = ii->lexicon; grn_scorer_score_func *score_func = NULL; - void *score_func_user_data = NULL; grn_scorer_matched_record record; if (!lexicon || !ii || !s) { return GRN_INVALID_ARGUMENT; } @@ -6240,7 +6320,6 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_ if (optarg && optarg->scorer) { grn_proc *scorer = (grn_proc *)(optarg->scorer); score_func = scorer->callbacks.scorer.score; - score_func_user_data = scorer->user_data; record.table = grn_ctx_at(ctx, s->obj.header.domain); record.lexicon = lexicon; record.id = GRN_ID_NIL; @@ -6252,6 +6331,8 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_ record.n_candidates = 0; record.n_tokens = 0; record.weight = 0; + record.args_expr = optarg->scorer_args_expr; + record.args_expr_offset = optarg->scorer_args_expr_offset; } for (;;) { @@ -6397,6 +6478,93 @@ exit : return rc; } +uint32_t +grn_ii_estimate_size_for_query(grn_ctx *ctx, grn_ii *ii, + const char *query, unsigned int query_len, + grn_search_optarg *optarg) +{ + grn_rc rc; + grn_obj *lexicon = ii->lexicon; + token_info **tis = NULL; + uint32_t i; + uint32_t n_tis = 0; + grn_bool only_skip_token = GRN_FALSE; + grn_operator mode = GRN_OP_EXACT; + double estimated_size = 0; + + if (query_len == 0) { + return 0; + } + + tis = GRN_MALLOC(sizeof(token_info *) * query_len * 2); + if (!tis) { + return 0; + } + + if (optarg) { + switch (optarg->mode) { + case GRN_OP_NEAR : + case GRN_OP_NEAR2 : + mode = optarg->mode; + break; + case GRN_OP_SIMILAR : + mode = optarg->mode; + break; + case GRN_OP_REGEXP : + mode = optarg->mode; + break; + default : + break; + } + } + + rc = token_info_build(ctx, lexicon, ii, query, query_len, + tis, &n_tis, &only_skip_token, mode); + if (rc != GRN_SUCCESS) { + goto exit; + } + + for (i = 0; i < n_tis; i++) { + token_info *ti = tis[i]; + double term_estimated_size; + term_estimated_size = ((double)ti->size / ti->ntoken); + if (i == 0) { + estimated_size = term_estimated_size; + } else { + estimated_size = fmin(estimated_size, term_estimated_size); + } + } + +exit : + for (i = 0; i < n_tis; i++) { + token_info *ti = tis[i]; + if (ti) { + token_info_close(ctx, ti); + } + } + if (tis) { + GRN_FREE(tis); + } + + return estimated_size; +} + +uint32_t +grn_ii_estimate_size_for_lexicon_cursor(grn_ctx *ctx, grn_ii *ii, + grn_table_cursor *lexicon_cursor) +{ + grn_id term_id; + uint32_t estimated_size = 0; + + while ((term_id = grn_table_cursor_next(ctx, lexicon_cursor)) != GRN_ID_NIL) { + uint32_t term_estimated_size; + term_estimated_size = grn_ii_estimate_size(ctx, ii, term_id); + estimated_size += term_estimated_size; + } + + return estimated_size; +} + grn_rc grn_ii_sel(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len, grn_hash *s, grn_operator op, grn_search_optarg *optarg) @@ -6417,6 +6585,9 @@ grn_ii_sel(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len arg.mode = optarg->mode; arg.similarity_threshold = optarg->similarity_threshold; break; + case GRN_OP_REGEXP : + arg.mode = optarg->mode; + break; default : break; } @@ -6425,6 +6596,8 @@ grn_ii_sel(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len arg.vector_size = optarg->vector_size; } arg.scorer = optarg->scorer; + arg.scorer_args_expr = optarg->scorer_args_expr; + arg.scorer_args_expr_offset = optarg->scorer_args_expr_offset; } /* todo : support subrec grn_rset_init(ctx, s, grn_rec_document, 0, grn_rec_none, 0, 0); @@ -6755,8 +6928,12 @@ grn_ii_inspect_values(grn_ctx *ctx, grn_ii *ii, grn_obj *buf) /********************** buffered index builder ***********************/ -const grn_id II_BUFFER_RID_FLAG = 0x80000000; -const grn_id II_BUFFER_WEIGHT_FLAG = 0x40000000; +const grn_id II_BUFFER_TYPE_MASK = 0xc0000000; +#define II_BUFFER_TYPE_RID 0x80000000 +#define II_BUFFER_TYPE_WEIGHT 0x40000000 +#define II_BUFFER_TYPE(id) (((id) & II_BUFFER_TYPE_MASK)) +#define II_BUFFER_PACK(value, type) ((value) | (type)) +#define II_BUFFER_UNPACK(id, type) ((id) & ~(type)) #ifdef II_BUFFER_ORDER_BY_ID const int II_BUFFER_ORDER = GRN_CURSOR_BY_ID; #else /* II_BUFFER_ORDER_BY_ID */ @@ -6932,7 +7109,7 @@ encode_terms(grn_ctx *ctx, grn_ii_buffer *ii_buffer, } if (outbufp_ + II_BUFFER_BLOCK_READ_UNIT_SIZE < outbufp) { uint32_t size = outbufp - outbufp_ + sizeof(uint32_t); - memcpy(pnext, &size, sizeof(uint32_t)); + grn_memcpy(pnext, &size, sizeof(uint32_t)); pnext = outbufp; outbufp += sizeof(uint32_t); outbufp_ = outbufp; @@ -6941,7 +7118,7 @@ encode_terms(grn_ctx *ctx, grn_ii_buffer *ii_buffer, grn_table_cursor_close(ctx, tc); if (outbufp_ < outbufp) { uint32_t size = outbufp - outbufp_; - memcpy(pnext, &size, sizeof(uint32_t)); + grn_memcpy(pnext, &size, sizeof(uint32_t)); } return outbufp - outbuf; } @@ -6958,59 +7135,66 @@ encode_postings(grn_ctx *ctx, grn_ii_buffer *ii_buffer, uint8_t *outbuf) uint32_t flags = ii_buffer->ii->header->flags; for (rest = ii_buffer->block_pos; rest; bp++, rest--) { grn_id id = *bp; - if (id & II_BUFFER_RID_FLAG) { - rid = id - II_BUFFER_RID_FLAG; + switch (II_BUFFER_TYPE(id)) { + case II_BUFFER_TYPE_RID : + rid = II_BUFFER_UNPACK(id, II_BUFFER_TYPE_RID); if ((flags & GRN_OBJ_WITH_SECTION) && rest) { sid = *++bp; rest--; } weight = 0; pos = 0; - } else if (id & II_BUFFER_WEIGHT_FLAG) { - weight = id - II_BUFFER_WEIGHT_FLAG; - } else { - ii_buffer_counter *counter = &ii_buffer->counters[id - 1]; - if (counter->last_rid == rid && counter->last_sid == sid) { - counter->last_tf++; - counter->last_weight += weight; - } else { - if (counter->last_tf) { - uint8_t *p = outbuf + counter->offset_tf; - GRN_B_ENC(counter->last_tf - 1, p); - counter->offset_tf = p - outbuf; - if (flags & GRN_OBJ_WITH_WEIGHT) { - p = outbuf + counter->offset_weight; - GRN_B_ENC(counter->last_weight, p); - counter->offset_weight = p - outbuf; + break; + case II_BUFFER_TYPE_WEIGHT : + weight = II_BUFFER_UNPACK(id, II_BUFFER_TYPE_WEIGHT); + break; + default : + { + ii_buffer_counter *counter = &ii_buffer->counters[id - 1]; + if (counter->last_rid == rid && counter->last_sid == sid) { + counter->last_tf++; + counter->last_weight += weight; + } else { + if (counter->last_tf) { + uint8_t *p = outbuf + counter->offset_tf; + GRN_B_ENC(counter->last_tf - 1, p); + counter->offset_tf = p - outbuf; + if (flags & GRN_OBJ_WITH_WEIGHT) { + p = outbuf + counter->offset_weight; + GRN_B_ENC(counter->last_weight, p); + counter->offset_weight = p - outbuf; + } } - } - { - uint8_t *p = outbuf + counter->offset_rid; - GRN_B_ENC(rid - counter->last_rid, p); - counter->offset_rid = p - outbuf; - } - if (flags & GRN_OBJ_WITH_SECTION) { - uint8_t *p = outbuf + counter->offset_sid; - if (counter->last_rid != rid) { - GRN_B_ENC(sid - 1, p); - } else { - GRN_B_ENC(sid - counter->last_sid - 1, p); + { + uint8_t *p = outbuf + counter->offset_rid; + GRN_B_ENC(rid - counter->last_rid, p); + counter->offset_rid = p - outbuf; } - counter->offset_sid = p - outbuf; + if (flags & GRN_OBJ_WITH_SECTION) { + uint8_t *p = outbuf + counter->offset_sid; + if (counter->last_rid != rid) { + GRN_B_ENC(sid - 1, p); + } else { + GRN_B_ENC(sid - counter->last_sid - 1, p); + } + counter->offset_sid = p - outbuf; + } + counter->last_rid = rid; + counter->last_sid = sid; + counter->last_tf = 1; + counter->last_weight = weight; + counter->last_pos = 0; + } + if ((flags & GRN_OBJ_WITH_POSITION) && rest) { + uint8_t *p = outbuf + counter->offset_pos; + pos = *++bp; + rest--; + GRN_B_ENC(pos - counter->last_pos, p); + counter->offset_pos = p - outbuf; + counter->last_pos = pos; } - counter->last_rid = rid; - counter->last_sid = sid; - counter->last_tf = 1; - counter->last_weight = weight; - counter->last_pos = 0; - } - if (flags & GRN_OBJ_WITH_POSITION) { - uint8_t *p = outbuf + counter->offset_pos; - GRN_B_ENC(pos - counter->last_pos, p); - counter->offset_pos = p - outbuf; - counter->last_pos = pos; } - pos++; + break; } } } @@ -7046,7 +7230,7 @@ grn_ii_buffer_flush(grn_ctx *ctx, grn_ii_buffer *ii_buffer) encode_postings(ctx, ii_buffer, outbuf); encode_last_tf(ctx, ii_buffer, outbuf); { - ssize_t r = GRN_WRITE(ii_buffer->tmpfd, outbuf, encsize); + ssize_t r = grn_write(ii_buffer->tmpfd, outbuf, encsize); if (r != encsize) { ERR(GRN_INPUT_OUTPUT_ERROR, "write returned %" GRN_FMT_LLD " != %" GRN_FMT_LLU, (long long int)r, (unsigned long long int)encsize); @@ -7126,7 +7310,7 @@ grn_ii_buffer_tokenize(grn_ctx *ctx, grn_ii_buffer *ii_buffer, grn_id rid, { if (value_len) { grn_obj *tmp_lexicon; - uint32_t est_len = value_len + 2; + uint32_t est_len = value_len * 2 + 2; if (ii_buffer->block_buf_size < ii_buffer->block_pos + est_len) { grn_ii_buffer_flush(ctx, ii_buffer); } @@ -7142,24 +7326,27 @@ grn_ii_buffer_tokenize(grn_ctx *ctx, grn_ii_buffer *ii_buffer, grn_id rid, grn_token_cursor *token_cursor; grn_id *buffer = ii_buffer->block_buf; uint32_t block_pos = ii_buffer->block_pos; - buffer[block_pos++] = rid + II_BUFFER_RID_FLAG; - if ((ii_buffer->ii->header->flags & GRN_OBJ_WITH_SECTION)) { + uint32_t ii_flags = ii_buffer->ii->header->flags; + buffer[block_pos++] = II_BUFFER_PACK(rid, II_BUFFER_TYPE_RID); + if (ii_flags & GRN_OBJ_WITH_SECTION) { buffer[block_pos++] = sid; } if (weight) { - buffer[block_pos++] = weight + II_BUFFER_WEIGHT_FLAG; + buffer[block_pos++] = II_BUFFER_PACK(weight, II_BUFFER_TYPE_WEIGHT); } if ((token_cursor = grn_token_cursor_open(ctx, tmp_lexicon, value, value_len, GRN_TOKEN_ADD, token_flags))) { - uint32_t pos; - for (pos = 0; !token_cursor->status; pos++) { + while (!token_cursor->status) { grn_id tid; if ((tid = grn_token_cursor_next(ctx, token_cursor))) { ii_buffer_counter *counter; counter = get_buffer_counter(ctx, ii_buffer, tmp_lexicon, tid); if (!counter) { return; } buffer[block_pos++] = tid; + if (ii_flags & GRN_OBJ_WITH_POSITION) { + buffer[block_pos++] = token_cursor->pos; + } if (counter->last_rid != rid) { counter->offset_rid += GRN_B_ENC_SIZE(rid - counter->last_rid); counter->last_rid = rid; @@ -7187,8 +7374,9 @@ grn_ii_buffer_tokenize(grn_ctx *ctx, grn_ii_buffer *ii_buffer, grn_id rid, counter->last_pos = 0; counter->nrecs++; } - counter->offset_pos += GRN_B_ENC_SIZE(pos - counter->last_pos); - counter->last_pos = pos; + counter->offset_pos += + GRN_B_ENC_SIZE(token_cursor->pos - counter->last_pos); + counter->last_pos = token_cursor->pos; counter->last_tf++; counter->last_weight += weight; counter->nposts++; @@ -7219,11 +7407,20 @@ grn_ii_buffer_fetch(grn_ctx *ctx, grn_ii_buffer *ii_buffer, return; } } - if (grn_lseek(ii_buffer->tmpfd, block->head, SEEK_SET) != block->head) { - SERR("grn_lseek"); - return; + { + off64_t seeked_position; + seeked_position = grn_lseek(ii_buffer->tmpfd, block->head, SEEK_SET); + if (seeked_position != block->head) { + ERRNO_ERR("grn_lseek"); + GRN_LOG(ctx, GRN_LOG_ERROR, + "failed to " + "grn_lseek(%" GRN_FMT_OFF64_T ") -> %" GRN_FMT_OFF64_T, + block->head, + seeked_position); + return; + } } - if (read(ii_buffer->tmpfd, block->buffer, bytesize) != bytesize) { + if (grn_read(ii_buffer->tmpfd, block->buffer, bytesize) != bytesize) { SERR("read"); return; } @@ -7239,8 +7436,8 @@ grn_ii_buffer_fetch(grn_ctx *ctx, grn_ii_buffer *ii_buffer, block->nextsize = 0; } else { block->rest = block->nextsize - sizeof(uint32_t); - memcpy(&block->nextsize, - &block->buffer[block->rest], sizeof(uint32_t)); + grn_memcpy(&block->nextsize, + &block->buffer[block->rest], sizeof(uint32_t)); } } } @@ -7528,16 +7725,10 @@ grn_ii_buffer_open(grn_ctx *ctx, grn_ii *ii, if (ii_buffer->counters) { ii_buffer->block_buf = GRN_MALLOCN(grn_id, II_BUFFER_BLOCK_SIZE); if (ii_buffer->block_buf) { - int open_flags = 0; -#ifdef WIN32 - open_flags |= O_BINARY; -#endif - snprintf(ii_buffer->tmpfpath, PATH_MAX, - "%sXXXXXX", grn_io_path(ii->seg)); + grn_snprintf(ii_buffer->tmpfpath, PATH_MAX, PATH_MAX, + "%sXXXXXX", grn_io_path(ii->seg)); ii_buffer->block_buf_size = II_BUFFER_BLOCK_SIZE; - ii_buffer->tmpfd = GRN_MKOSTEMP(ii_buffer->tmpfpath, - open_flags, - S_IRUSR|S_IWUSR); + ii_buffer->tmpfd = grn_mkstemp(ii_buffer->tmpfpath); if (ii_buffer->tmpfd != -1) { grn_obj_flags flags; grn_table_get_info(ctx, ii->lexicon, &flags, NULL, NULL, NULL, NULL); @@ -7577,7 +7768,7 @@ grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer) grn_ii_buffer_flush(ctx, ii_buffer); } if (ii_buffer->tmpfd != -1) { - GRN_CLOSE(ii_buffer->tmpfd); + grn_close(ii_buffer->tmpfd); } if (ii_buffer->block_buf) { GRN_FREE(ii_buffer->block_buf); @@ -7604,13 +7795,11 @@ grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer) ii_buffer->nblocks, ii_buffer->update_buffer_size); datavec_init(ctx, ii_buffer->data_vectors, ii_buffer->ii->n_elements, 0, 0); -#ifdef WIN32 - ii_buffer->tmpfd = GRN_OPEN(ii_buffer->tmpfpath, O_RDONLY|O_BINARY); -#else /* WIN32 */ - ii_buffer->tmpfd = GRN_OPEN(ii_buffer->tmpfpath, O_RDONLY); -#endif /* WIN32 */ + grn_open(ii_buffer->tmpfd, + ii_buffer->tmpfpath, + O_RDONLY | GRN_OPEN_FLAG_BINARY); if (ii_buffer->tmpfd == -1) { - SERR("oepn"); + ERRNO_ERR("oepn"); return ctx->rc; } { @@ -7652,8 +7841,8 @@ grn_ii_buffer_commit(grn_ctx *ctx, grn_ii_buffer *ii_buffer) GRN_LOG(ctx, GRN_LOG_NOTICE, "tmpfile_size:%" GRN_FMT_INT64D " > total_chunk_size:%" GRN_FMT_SIZE, ii_buffer->filepos, ii_buffer->total_chunk_size); - GRN_CLOSE(ii_buffer->tmpfd); - unlink(ii_buffer->tmpfpath); + grn_close(ii_buffer->tmpfd); + grn_unlink(ii_buffer->tmpfpath); ii_buffer->tmpfd = -1; return ctx->rc; } @@ -7671,8 +7860,8 @@ grn_ii_buffer_close(grn_ctx *ctx, grn_ii_buffer *ii_buffer) grn_obj_close(ctx, ii_buffer->tmp_lexicon); } if (ii_buffer->tmpfd != -1) { - GRN_CLOSE(ii_buffer->tmpfd); - unlink(ii_buffer->tmpfpath); + grn_close(ii_buffer->tmpfd); + grn_unlink(ii_buffer->tmpfpath); } if (ii_buffer->block_buf) { GRN_FREE(ii_buffer->block_buf); @@ -7749,7 +7938,21 @@ grn_ii_buffer_parse(grn_ctx *ctx, grn_ii_buffer *ii_buffer, grn_rc grn_ii_build(grn_ctx *ctx, grn_ii *ii, uint64_t sparsity) { - grn_ii_buffer *ii_buffer = grn_ii_buffer_open(ctx, ii, sparsity); + grn_ii_buffer *ii_buffer; + + { + grn_obj *data_table; + + data_table = grn_ctx_at(ctx, DB_OBJ(ii)->range); + if (!data_table) { + return ctx->rc; + } + if (grn_table_size(ctx, data_table) == 0) { + return ctx->rc; + } + } + + ii_buffer = grn_ii_buffer_open(ctx, ii, sparsity); if (ii_buffer) { grn_id *s = ii->obj.source; if ((ii->obj.source_size) && s) { diff --git a/storage/mroonga/vendor/groonga/lib/io.c b/storage/mroonga/vendor/groonga/lib/io.c index 2ea581b8db7..a78c7f242c9 100644 --- a/storage/mroonga/vendor/groonga/lib/io.c +++ b/storage/mroonga/vendor/groonga/lib/io.c @@ -29,9 +29,13 @@ #include "grn_hash.h" #include "grn_ctx_impl.h" +#ifdef WIN32 +# include <share.h> +#endif /* WIN32 */ + #define GRN_IO_IDSTR "GROONGA:IO:00001" -#define GRN_IO_VERSION_DEFAULT 0 +#define GRN_IO_VERSION_DEFAULT 1 #define GRN_IO_FILE_SIZE_V1 1073741824UL @@ -41,14 +45,6 @@ # define GRN_IO_FILE_SIZE_V0 GRN_IO_FILE_SIZE_V1 #endif /* WIN32 */ -#ifndef O_BINARY -# ifdef _O_BINARY -# define O_BINARY _O_BINARY -# else -# define O_BINARY 0 -# endif -#endif - typedef struct _grn_io_fileinfo { #ifdef WIN32 HANDLE fh; @@ -65,10 +61,10 @@ typedef struct _grn_io_fileinfo { static uint32_t grn_io_version_default = GRN_IO_VERSION_DEFAULT; -inline static grn_rc grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags); +inline static grn_rc grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags); inline static void grn_fileinfo_init(fileinfo *fis, int nfis); -inline static int grn_opened(fileinfo *fi); -inline static grn_rc grn_close(grn_ctx *ctx, fileinfo *fi); +inline static int grn_fileinfo_opened(fileinfo *fi); +inline static grn_rc grn_fileinfo_close(grn_ctx *ctx, fileinfo *fi); #ifdef WIN32 inline static void * grn_mmap(grn_ctx *ctx, grn_io *io, HANDLE *fmo, fileinfo *fi, @@ -106,10 +102,12 @@ inline static grn_rc grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t co grn_rc grn_io_init(void) { - const char *version_env; + char version_env[GRN_ENV_BUFFER_SIZE]; - version_env = getenv("GRN_IO_VERSION"); - if (version_env) { + grn_getenv("GRN_IO_VERSION", + version_env, + GRN_ENV_BUFFER_SIZE); + if (version_env[0]) { grn_io_version_default = atoi(version_env); } @@ -194,7 +192,7 @@ grn_io_create_tmp(uint32_t header_size, uint32_t segment_size, header->n_arrays = 0; header->flags = flags; header->lock = 0; - memcpy(header->idstr, GRN_IO_IDSTR, 16); + grn_memcpy(header->idstr, GRN_IO_IDSTR, 16); if ((io = GRN_GMALLOCN(grn_io, 1))) { grn_io_mapinfo *maps = NULL; if ((maps = GRN_GCALLOC(sizeof(grn_io_mapinfo) * max_segment))) { @@ -283,7 +281,7 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg bs, file_size); if ((fis = GRN_GMALLOCN(fileinfo, max_nfiles))) { grn_fileinfo_init(fis, max_nfiles); - if (!grn_open(ctx, fis, path, O_RDWR|O_CREAT|O_EXCL)) { + if (!grn_fileinfo_open(ctx, fis, path, O_RDWR|O_CREAT|O_EXCL)) { header = (struct _grn_io_header *)GRN_MMAP(&grn_gctx, NULL, &fis->fmo, fis, 0, b); if (header) { @@ -294,12 +292,12 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg header->n_arrays = 0; header->flags = flags; header->lock = 0; - memcpy(header->idstr, GRN_IO_IDSTR, 16); + grn_memcpy(header->idstr, GRN_IO_IDSTR, 16); grn_msync(ctx, header, b); if ((io = GRN_GMALLOCN(grn_io, 1))) { grn_io_mapinfo *maps = NULL; if ((maps = GRN_GCALLOC(sizeof(grn_io_mapinfo) * max_segment))) { - strncpy(io->path, path, PATH_MAX); + grn_strncpy(io->path, PATH_MAX, path, PATH_MAX); io->header = header; io->user_header = (((byte *) header) + IO_HEADER_SIZE); io->maps = maps; @@ -321,7 +319,8 @@ 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_close(ctx, fis); + grn_fileinfo_close(ctx, fis); + grn_unlink(path); } GRN_GFREE(fis); } @@ -395,7 +394,7 @@ grn_io_create_with_array(grn_ctx *ctx, const char *path, if ((io = grn_io_create(ctx, path, header_size + hsize, segment_size, nsegs, mode, GRN_IO_EXPIRE_GTICK))) { hp = io->user_header; - memcpy(hp, array_specs, sizeof(grn_io_array_spec) * n_arrays); + grn_memcpy(hp, array_specs, sizeof(grn_io_array_spec) * n_arrays); io->header->n_arrays = n_arrays; io->header->segment_tail = 1; if (!array_init_(io, n_arrays, hsize, msize)) { @@ -474,11 +473,12 @@ grn_io_detect_type(grn_ctx *ctx, const char *path) { struct _grn_io_header h; uint32_t res = 0; - int fd = GRN_OPEN(path, O_RDWR | O_BINARY); + int fd; + grn_open(fd, path, O_RDWR | GRN_OPEN_FLAG_BINARY); if (fd != -1) { struct stat s; if (fstat(fd, &s) != -1 && s.st_size >= sizeof(struct _grn_io_header)) { - if (read(fd, &h, sizeof(struct _grn_io_header)) == 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)) { res = h.type; } else { @@ -490,9 +490,9 @@ grn_io_detect_type(grn_ctx *ctx, const char *path) } else { ERR(GRN_INVALID_FORMAT, "grn_io_detect_type failed"); } - GRN_CLOSE(fd); + grn_close(fd); } else { - SERR(path); + ERRNO_ERR(path); } return res; } @@ -509,10 +509,14 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode) if (!path || !*path || (strlen(path) > PATH_MAX - 4)) { return NULL; } { struct _grn_io_header h; - int fd = GRN_OPEN(path, O_RDWR | O_BINARY); - if (fd == -1) { SERR(path); return NULL; } + int fd; + grn_open(fd, path, O_RDWR | GRN_OPEN_FLAG_BINARY); + if (fd == -1) { + ERRNO_ERR(path); + return NULL; + } if (fstat(fd, &s) != -1 && s.st_size >= sizeof(struct _grn_io_header)) { - if (read(fd, &h, sizeof(struct _grn_io_header)) == 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)) { header_size = h.header_size; segment_size = h.segment_size; @@ -523,13 +527,13 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode) } } } - GRN_CLOSE(fd); + grn_close(fd); if (!segment_size) { return NULL; } } b = grn_io_compute_base(header_size); bs = grn_io_compute_base_segment(b, segment_size); grn_fileinfo_init(&fi, 1); - if (!grn_open(ctx, &fi, path, O_RDWR)) { + if (!grn_fileinfo_open(ctx, &fi, path, O_RDWR)) { struct _grn_io_header *header; header = GRN_MMAP(&grn_gctx, NULL, &(fi.fmo), &fi, 0, b); if (header) { @@ -543,15 +547,15 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode) fis = GRN_GMALLOCN(fileinfo, max_nfiles); if (!fis) { GRN_MUNMAP(&grn_gctx, NULL, &(fi.fmo), &fi, header, b); - grn_close(ctx, &fi); + grn_fileinfo_close(ctx, &fi); return NULL; } grn_fileinfo_init(fis, max_nfiles); - memcpy(fis, &fi, sizeof(fileinfo)); + grn_memcpy(fis, &fi, sizeof(fileinfo)); if ((io = GRN_GMALLOC(sizeof(grn_io)))) { grn_io_mapinfo *maps = NULL; if ((maps = GRN_GCALLOC(sizeof(grn_io_mapinfo) * max_segment))) { - strncpy(io->path, path, PATH_MAX); + grn_strncpy(io->path, PATH_MAX, path, PATH_MAX); io->header = header; io->user_header = (((byte *) header) + IO_HEADER_SIZE); { @@ -578,7 +582,7 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode) GRN_GFREE(fis); GRN_MUNMAP(&grn_gctx, NULL, &(fi.fmo), &fi, header, b); } - grn_close(ctx, &fi); + grn_fileinfo_close(ctx, &fi); } return NULL; } @@ -624,7 +628,7 @@ grn_io_close(grn_ctx *ctx, grn_io *io) int i; for (i = 0; i < max_nfiles; i++) { fileinfo *fi = &(io->fis[i]); - grn_close(ctx, fi); + grn_fileinfo_close(ctx, fi); } GRN_GFREE(io->fis); } @@ -671,7 +675,7 @@ inline static void gen_pathname(const char *path, char *buffer, int fno) { size_t len = strlen(path); - memcpy(buffer, path, len); + grn_memcpy(buffer, path, len); if (fno) { buffer[len] = '.'; grn_itoh(fno, buffer + len + 1, 3); @@ -716,8 +720,8 @@ grn_io_remove(grn_ctx *ctx, const char *path) if (stat(path, &s)) { SERR("stat"); return ctx->rc; - } else if (unlink(path)) { - SERR(path); + } else if (grn_unlink(path)) { + ERRNO_ERR(path); return ctx->rc; } else { int fno; @@ -725,7 +729,9 @@ grn_io_remove(grn_ctx *ctx, const char *path) for (fno = 1; ; fno++) { gen_pathname(path, buffer, fno); if (!stat(buffer, &s)) { - if (unlink(buffer)) { SERR(buffer); } + if (grn_unlink(buffer)) { + ERRNO_ERR(buffer); + } } else { break; } @@ -790,10 +796,10 @@ grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos, rest = pos + size - file_size; size = file_size - pos; } - if (!grn_opened(fi)) { + if (!grn_fileinfo_opened(fi)) { char path[PATH_MAX]; gen_pathname(io->path, path, fno); - if (grn_open(ctx, fi, path, O_RDWR|O_CREAT)) { + if (grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) { *value = NULL; *value_len = 0; GRN_FREE(v); @@ -838,10 +844,10 @@ grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos, byte *vr = (byte *)v + size; do { fi = &io->fis[++fno]; - if (!grn_opened(fi)) { + if (!grn_fileinfo_opened(fi)) { char path[PATH_MAX]; gen_pathname(io->path, path, fno); - if (grn_open(ctx, fi, path, O_RDWR|O_CREAT)) { + if (grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) { *value = NULL; *value_len = 0; GRN_FREE(v); @@ -881,16 +887,16 @@ grn_io_write_ja(grn_io *io, grn_ctx *ctx, uint32_t key, rest = pos + size - file_size; size = file_size - pos; } - if (!grn_opened(fi)) { + if (!grn_fileinfo_opened(fi)) { char path[PATH_MAX]; gen_pathname(io->path, path, fno); - if ((rc = grn_open(ctx, fi, path, O_RDWR|O_CREAT))) { return rc; } + if ((rc = grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT))) { return rc; } } if (value_len <= 256) { ja_element je; je.head.size = value_len; je.head.key = key; - memcpy(je.body, value, value_len); + grn_memcpy(je.body, value, value_len); rc = grn_pwrite(ctx, fi, &je, size, pos); } else { grn_io_ja_ehead eh; @@ -905,10 +911,10 @@ grn_io_write_ja(grn_io *io, grn_ctx *ctx, uint32_t key, byte *vr = (byte *)value + size - sizeof(grn_io_ja_ehead); do { fi = &io->fis[++fno]; - if (!grn_opened(fi)) { + if (!grn_fileinfo_opened(fi)) { char path[PATH_MAX]; gen_pathname(io->path, path, fno); - if ((rc = grn_open(ctx, fi, path, O_RDWR|O_CREAT))) { return rc; } + if ((rc = grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT))) { return rc; } } size = rest > file_size ? file_size : rest; if ((rc = grn_pwrite(ctx, fi, vr, size, 0))) { return rc; } @@ -932,10 +938,10 @@ grn_io_write_ja_ehead(grn_io *io, grn_ctx *ctx, uint32_t key, fileinfo *fi = &io->fis[fno]; 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) + offset + base; - if (!grn_opened(fi)) { + if (!grn_fileinfo_opened(fi)) { char path[PATH_MAX]; gen_pathname(io->path, path, fno); - if ((rc = grn_open(ctx, fi, path, O_RDWR|O_CREAT))) { return rc; } + if ((rc = grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT))) { return rc; } } { grn_io_ja_ehead eh; @@ -987,7 +993,7 @@ grn_io_win_map(grn_io *io, grn_ctx *ctx, grn_io_win *iw, uint32_t segment, return NULL; } s = (offset + r > segment_size) ? segment_size - offset : r; - memcpy(p, q + offset, s); + grn_memcpy(p, q + offset, s); GRN_IO_SEG_UNREF(io, segment); } } @@ -1027,7 +1033,7 @@ grn_io_win_unmap(grn_io_win *iw) GRN_IO_SEG_REF(io, segment, q); if (!q) { return GRN_NO_MEMORY_AVAILABLE; } s = (offset + r > segment_size) ? segment_size - offset : r; - memcpy(q + offset, p, s); + grn_memcpy(q + offset, p, s); GRN_IO_SEG_UNREF(io, segment); } } @@ -1063,10 +1069,10 @@ grn_io_win_unmap(grn_io_win *iw) 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_opened(fi)) {\ + if (!grn_fileinfo_opened(fi)) {\ char path[PATH_MAX];\ gen_pathname(io->path, path, fno);\ - if (!grn_open(ctx, fi, path, O_RDWR|O_CREAT)) { \ + if (!grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) { \ DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);\ }\ } else {\ @@ -1312,7 +1318,7 @@ static size_t mmap_size = 0; #ifdef WIN32 inline static grn_rc -grn_open_v1(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) +grn_fileinfo_open_v1(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) { CRITICAL_SECTION_INIT(fi->cs); return GRN_SUCCESS; @@ -1390,7 +1396,7 @@ grn_munmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, } inline static grn_rc -grn_open_v0(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) +grn_fileinfo_open_v0(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) { /* signature may be wrong.. */ fi->fmo = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, NULL); @@ -1475,7 +1481,7 @@ grn_munmap_v0(grn_ctx *ctx, fileinfo *fi, void *start, size_t length) } inline static grn_rc -grn_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) +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)) { @@ -1520,7 +1526,7 @@ exit : } inline static grn_rc -grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) +grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) { grn_rc rc; struct _grn_io_header io_header; @@ -1528,7 +1534,7 @@ grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) DWORD read_bytes; int version = grn_io_version_default; - rc = grn_open_common(ctx, fi, path, flags); + rc = grn_fileinfo_open_common(ctx, fi, path, flags); if (rc != GRN_SUCCESS) { return rc; } @@ -1543,9 +1549,9 @@ grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) } if (version == 0) { - return grn_open_v0(ctx, fi, path, flags); + return grn_fileinfo_open_v0(ctx, fi, path, flags); } else { - return grn_open_v1(ctx, fi, path, flags); + return grn_fileinfo_open_v1(ctx, fi, path, flags); } } @@ -1598,7 +1604,7 @@ grn_munmap(grn_ctx *ctx, grn_io *io, } inline static grn_rc -grn_close(grn_ctx *ctx, fileinfo *fi) +grn_fileinfo_close(grn_ctx *ctx, fileinfo *fi) { if (fi->fmo != NULL) { CloseHandle(fi->fmo); @@ -1622,7 +1628,7 @@ grn_fileinfo_init(fileinfo *fis, int nfis) } inline static int -grn_opened(fileinfo *fi) +grn_fileinfo_opened(fileinfo *fi) { return fi->fh != INVALID_HANDLE_VALUE; } @@ -1681,15 +1687,16 @@ grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset) #else /* WIN32 */ inline static grn_rc -grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) +grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags) { struct stat st; - if ((fi->fd = GRN_OPEN(path, flags, GRN_IO_FILE_CREATE_MODE)) == -1) { - SERR(path); + grn_open(fi->fd, path, flags); + if (fi->fd == -1) { + ERRNO_ERR(path); return ctx->rc; } if (fstat(fi->fd, &st) == -1) { - SERR(path); + ERRNO_ERR(path); return ctx->rc; } fi->dev = st.st_dev; @@ -1704,16 +1711,16 @@ grn_fileinfo_init(fileinfo *fis, int nfis) } inline static int -grn_opened(fileinfo *fi) +grn_fileinfo_opened(fileinfo *fi) { return fi->fd != -1; } inline static grn_rc -grn_close(grn_ctx *ctx, fileinfo *fi) +grn_fileinfo_close(grn_ctx *ctx, fileinfo *fi) { if (fi->fd != -1) { - if (GRN_CLOSE(fi->fd) == -1) { + if (grn_close(fi->fd) == -1) { SERR("close"); return ctx->rc; } @@ -1764,11 +1771,17 @@ grn_fail_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi, const char* file, int line, const char *func) { if (grn_fail_malloc_check(length, file, line, func)) { - return grn_mmap(ctx, fi, offset, length); + return grn_mmap(ctx, io, fi, offset, length); } else { MERR("fail_mmap(%" GRN_FMT_SIZE ",%d,%" GRN_FMT_LLU ") " "(%s:%d@%s) <%" GRN_FMT_SIZE ">", - length, fi ? fi->fd : 0, offset, file, line, func, mmap_size); + length, + fi ? fi->fd : 0, + (long long unsigned int)offset, + file, + line, + func, + mmap_size); return NULL; } } diff --git a/storage/mroonga/vendor/groonga/lib/logger.c b/storage/mroonga/vendor/groonga/lib/logger.c new file mode 100644 index 00000000000..fc9fe71767e --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/logger.c @@ -0,0 +1,584 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + 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 + 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_logger.h" +#include "grn_ctx.h" +#include "grn_ctx_impl.h" + +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> + +#ifdef WIN32 +# include <share.h> +#endif /* WIN32 */ + +#ifdef WIN32 +# define fileno(file) _fileno(file) +#endif + +static void +rotate_log_file(grn_ctx *ctx, const char *current_path) +{ + char rotated_path[PATH_MAX]; + grn_timeval now; + struct tm tm_buffer; + struct tm *tm; + + grn_timeval_now(ctx, &now); + tm = grn_timeval2tm(ctx, &now, &tm_buffer); + grn_snprintf(rotated_path, PATH_MAX, PATH_MAX, + "%s.%04d-%02d-%02d-%02d-%02d-%02d-%06d", + current_path, + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, + (int)(GRN_TIME_NSEC_TO_USEC(now.tv_nsec))); + rename(current_path, rotated_path); +} + +static char *default_logger_path = NULL; +static FILE *default_logger_file = NULL; +static grn_critical_section default_logger_lock; +static off_t default_logger_size = 0; +static off_t default_logger_rotate_threshold_size = 0; + +#define LOGGER_NEED_ROTATE(size, threshold) \ + ((threshold) > 0 && (size) >= (threshold)) + +static void +default_logger_log(grn_ctx *ctx, grn_log_level level, + const char *timestamp, const char *title, + const char *message, const char *location, void *user_data) +{ + const char slev[] = " EACewnid-"; + if (default_logger_path) { + CRITICAL_SECTION_ENTER(default_logger_lock); + if (!default_logger_file) { + default_logger_file = grn_fopen(default_logger_path, "a"); + default_logger_size = 0; + if (default_logger_file) { + struct stat stat; + if (fstat(fileno(default_logger_file), &stat) != -1) { + default_logger_size = stat.st_size; + } + } + } + if (default_logger_file) { + int written; + if (location && *location) { + written = fprintf(default_logger_file, "%s|%c|%s %s %s\n", + timestamp, *(slev + level), title, message, location); + } else { + written = fprintf(default_logger_file, "%s|%c|%s %s\n", timestamp, + *(slev + level), title, message); + } + if (written > 0) { + default_logger_size += written; + if (LOGGER_NEED_ROTATE(default_logger_size, + default_logger_rotate_threshold_size)) { + fclose(default_logger_file); + default_logger_file = NULL; + rotate_log_file(ctx, default_logger_path); + } else { + fflush(default_logger_file); + } + } + } + CRITICAL_SECTION_LEAVE(default_logger_lock); + } +} + +static void +default_logger_reopen(grn_ctx *ctx, void *user_data) +{ + GRN_LOG(ctx, GRN_LOG_NOTICE, "log will be closed."); + CRITICAL_SECTION_ENTER(default_logger_lock); + if (default_logger_file) { + fclose(default_logger_file); + default_logger_file = NULL; + } + CRITICAL_SECTION_LEAVE(default_logger_lock); + GRN_LOG(ctx, GRN_LOG_NOTICE, "log opened."); +} + +static void +default_logger_fin(grn_ctx *ctx, void *user_data) +{ + CRITICAL_SECTION_ENTER(default_logger_lock); + if (default_logger_file) { + fclose(default_logger_file); + default_logger_file = NULL; + } + CRITICAL_SECTION_LEAVE(default_logger_lock); +} + +static grn_logger default_logger = { + GRN_LOG_DEFAULT_LEVEL, + GRN_LOG_TIME|GRN_LOG_MESSAGE, + NULL, + default_logger_log, + default_logger_reopen, + default_logger_fin +}; + +static grn_logger current_logger = { + GRN_LOG_DEFAULT_LEVEL, + GRN_LOG_TIME|GRN_LOG_MESSAGE, + NULL, + NULL, + NULL, + NULL +}; + +void +grn_default_logger_set_max_level(grn_log_level max_level) +{ + default_logger.max_level = max_level; + if (current_logger.log == default_logger_log) { + current_logger.max_level = max_level; + } +} + +grn_log_level +grn_default_logger_get_max_level(void) +{ + return default_logger.max_level; +} + +void +grn_default_logger_set_path(const char *path) +{ + if (default_logger_path) { + free(default_logger_path); + } + + if (path) { + default_logger_path = grn_strdup_raw(path); + } else { + default_logger_path = NULL; + } +} + +const char * +grn_default_logger_get_path(void) +{ + return default_logger_path; +} + +void +grn_default_logger_set_rotate_threshold_size(off_t threshold) +{ + default_logger_rotate_threshold_size = threshold; +} + +off_t +grn_default_logger_get_rotate_threshold_size(void) +{ + return default_logger_rotate_threshold_size; +} + +void +grn_logger_reopen(grn_ctx *ctx) +{ + if (current_logger.reopen) { + current_logger.reopen(ctx, current_logger.user_data); + } +} + +static void +current_logger_fin(grn_ctx *ctx) +{ + if (current_logger.fin) { + current_logger.fin(ctx, current_logger.user_data); + } +} + +static void +logger_info_func_wrapper(grn_ctx *ctx, grn_log_level level, + const char *timestamp, const char *title, + const char *message, const char *location, + void *user_data) +{ + grn_logger_info *info = user_data; + info->func(level, timestamp, title, message, location, info->func_arg); +} + +/* Deprecated since 2.1.2. */ +grn_rc +grn_logger_info_set(grn_ctx *ctx, const grn_logger_info *info) +{ + if (info) { + grn_logger logger; + + memset(&logger, 0, sizeof(grn_logger)); + logger.max_level = info->max_level; + logger.flags = info->flags; + if (info->func) { + logger.log = logger_info_func_wrapper; + logger.user_data = (grn_logger_info *)info; + } else { + logger.log = default_logger_log; + logger.reopen = default_logger_reopen; + logger.fin = default_logger_fin; + } + return grn_logger_set(ctx, &logger); + } else { + return grn_logger_set(ctx, NULL); + } +} + +grn_rc +grn_logger_set(grn_ctx *ctx, const grn_logger *logger) +{ + current_logger_fin(ctx); + if (logger) { + current_logger = *logger; + } else { + current_logger = default_logger; + } + return GRN_SUCCESS; +} + +void +grn_logger_set_max_level(grn_ctx *ctx, grn_log_level max_level) +{ + current_logger.max_level = max_level; +} + +grn_log_level +grn_logger_get_max_level(grn_ctx *ctx) +{ + return current_logger.max_level; +} + +grn_bool +grn_logger_pass(grn_ctx *ctx, grn_log_level level) +{ + return level <= current_logger.max_level; +} + +#define TBUFSIZE GRN_TIMEVAL_STR_SIZE +#define MBUFSIZE 0x1000 +#define LBUFSIZE 0x400 + +void +grn_logger_put(grn_ctx *ctx, grn_log_level level, + const char *file, int line, const char *func, const char *fmt, ...) +{ + if (level <= current_logger.max_level && current_logger.log) { + char tbuf[TBUFSIZE]; + char mbuf[MBUFSIZE]; + char lbuf[LBUFSIZE]; + tbuf[0] = '\0'; + if (current_logger.flags & GRN_LOG_TIME) { + grn_timeval tv; + grn_timeval_now(ctx, &tv); + grn_timeval2str(ctx, &tv, tbuf, TBUFSIZE); + } + if (current_logger.flags & GRN_LOG_MESSAGE) { + va_list argp; + va_start(argp, fmt); + vsnprintf(mbuf, MBUFSIZE - 1, fmt, argp); + va_end(argp); + mbuf[MBUFSIZE - 1] = '\0'; + } else { + mbuf[0] = '\0'; + } + if (current_logger.flags & GRN_LOG_LOCATION) { + grn_snprintf(lbuf, LBUFSIZE, LBUFSIZE, + "%d %s:%d %s()", getpid(), file, line, func); + lbuf[LBUFSIZE - 1] = '\0'; + } else { + lbuf[0] = '\0'; + } + current_logger.log(ctx, level, tbuf, "", mbuf, lbuf, + current_logger.user_data); + } +} + +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); +} + +void +grn_logger_fin(grn_ctx *ctx) +{ + current_logger_fin(ctx); + if (default_logger_path) { + free(default_logger_path); + default_logger_path = NULL; + } + CRITICAL_SECTION_FIN(default_logger_lock); +} + + +static char *default_query_logger_path = NULL; +static FILE *default_query_logger_file = NULL; +static grn_critical_section default_query_logger_lock; +static off_t default_query_logger_size = 0; +static off_t default_query_logger_rotate_threshold_size = 0; + +static void +default_query_logger_log(grn_ctx *ctx, unsigned int flag, + const char *timestamp, const char *info, + const char *message, void *user_data) +{ + if (default_query_logger_path) { + CRITICAL_SECTION_ENTER(default_query_logger_lock); + if (!default_query_logger_file) { + default_query_logger_file = grn_fopen(default_query_logger_path, "a"); + default_query_logger_size = 0; + if (default_query_logger_file) { + struct stat stat; + if (fstat(fileno(default_query_logger_file), &stat) != -1) { + default_query_logger_size = stat.st_size; + } + } + } + if (default_query_logger_file) { + int written; + written = fprintf(default_query_logger_file, "%s|%s%s\n", + timestamp, info, message); + if (written > 0) { + default_query_logger_size += written; + if (LOGGER_NEED_ROTATE(default_query_logger_size, + default_query_logger_rotate_threshold_size)) { + fclose(default_query_logger_file); + default_query_logger_file = NULL; + rotate_log_file(ctx, default_query_logger_path); + } else { + fflush(default_query_logger_file); + } + } + } + CRITICAL_SECTION_LEAVE(default_query_logger_lock); + } +} + +static void +default_query_logger_close(grn_ctx *ctx, void *user_data) +{ + GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ", + "query log will be closed: <%s>", default_query_logger_path); + CRITICAL_SECTION_ENTER(default_query_logger_lock); + if (default_query_logger_file) { + fclose(default_query_logger_file); + default_query_logger_file = NULL; + } + CRITICAL_SECTION_LEAVE(default_query_logger_lock); +} + +static void +default_query_logger_reopen(grn_ctx *ctx, void *user_data) +{ + default_query_logger_close(ctx, user_data); + if (default_query_logger_path) { + GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ", + "query log is opened: <%s>", default_query_logger_path); + } +} + +static void +default_query_logger_fin(grn_ctx *ctx, void *user_data) +{ + if (default_query_logger_file) { + default_query_logger_close(ctx, user_data); + } +} + +static grn_query_logger default_query_logger = { + GRN_QUERY_LOG_DEFAULT, + NULL, + default_query_logger_log, + default_query_logger_reopen, + default_query_logger_fin +}; + +static grn_query_logger current_query_logger = { + GRN_QUERY_LOG_DEFAULT, + NULL, + NULL, + NULL, + NULL +}; + +void +grn_default_query_logger_set_flags(unsigned int flags) +{ + default_query_logger.flags = flags; + if (current_query_logger.log == default_query_logger_log) { + current_query_logger.flags = flags; + } +} + +unsigned int +grn_default_query_logger_get_flags(void) +{ + return default_query_logger.flags; +} + +void +grn_default_query_logger_set_path(const char *path) +{ + if (default_query_logger_path) { + free(default_query_logger_path); + } + + if (path) { + default_query_logger_path = grn_strdup_raw(path); + } else { + default_query_logger_path = NULL; + } +} + +const char * +grn_default_query_logger_get_path(void) +{ + return default_query_logger_path; +} + +void +grn_default_query_logger_set_rotate_threshold_size(off_t threshold) +{ + default_query_logger_rotate_threshold_size = threshold; +} + +off_t +grn_default_query_logger_get_rotate_threshold_size(void) +{ + return default_query_logger_rotate_threshold_size; +} + +void +grn_query_logger_reopen(grn_ctx *ctx) +{ + if (current_query_logger.reopen) { + current_query_logger.reopen(ctx, current_query_logger.user_data); + } +} + +static void +current_query_logger_fin(grn_ctx *ctx) +{ + if (current_query_logger.fin) { + current_query_logger.fin(ctx, current_query_logger.user_data); + } +} + +grn_rc +grn_query_logger_set(grn_ctx *ctx, const grn_query_logger *logger) +{ + current_query_logger_fin(ctx); + if (logger) { + current_query_logger = *logger; + } else { + current_query_logger = default_query_logger; + } + return GRN_SUCCESS; +} + +grn_bool +grn_query_logger_pass(grn_ctx *ctx, unsigned int flag) +{ + return current_query_logger.flags & flag; +} + +#define TIMESTAMP_BUFFER_SIZE TBUFSIZE +/* 8+a(%p) + 1(|) + 1(mark) + 15(elapsed time) = 25+a */ +#define INFO_BUFFER_SIZE 40 + +void +grn_query_logger_put(grn_ctx *ctx, unsigned int flag, const char *mark, + const char *format, ...) +{ + char timestamp[TIMESTAMP_BUFFER_SIZE]; + char info[INFO_BUFFER_SIZE]; + grn_obj *message = &ctx->impl->query_log_buf; + + if (!current_query_logger.log) { + return; + } + + { + grn_timeval tv; + timestamp[0] = '\0'; + grn_timeval_now(ctx, &tv); + grn_timeval2str(ctx, &tv, timestamp, TIMESTAMP_BUFFER_SIZE); + } + + if (flag & (GRN_QUERY_LOG_COMMAND | GRN_QUERY_LOG_DESTINATION)) { + grn_snprintf(info, INFO_BUFFER_SIZE, INFO_BUFFER_SIZE, + "%p|%s", ctx, mark); + info[INFO_BUFFER_SIZE - 1] = '\0'; + } else { + grn_timeval tv; + uint64_t elapsed_time; + grn_timeval_now(ctx, &tv); + elapsed_time = + (uint64_t)(tv.tv_sec - ctx->impl->tv.tv_sec) * GRN_TIME_NSEC_PER_SEC + + (tv.tv_nsec - ctx->impl->tv.tv_nsec); + + grn_snprintf(info, INFO_BUFFER_SIZE, INFO_BUFFER_SIZE, + "%p|%s%015" GRN_FMT_INT64U " ", ctx, mark, elapsed_time); + info[INFO_BUFFER_SIZE - 1] = '\0'; + } + + { + va_list args; + + va_start(args, format); + GRN_BULK_REWIND(message); + grn_text_vprintf(ctx, message, format, args); + va_end(args); + GRN_TEXT_PUTC(ctx, message, '\0'); + } + + current_query_logger.log(ctx, flag, timestamp, info, GRN_TEXT_VALUE(message), + current_query_logger.user_data); +} + +void +grn_query_logger_init(void) +{ + grn_memcpy(¤t_query_logger, + &default_query_logger, sizeof(grn_query_logger)); + CRITICAL_SECTION_INIT(default_query_logger_lock); +} + +void +grn_query_logger_fin(grn_ctx *ctx) +{ + current_query_logger_fin(ctx); + if (default_query_logger_path) { + free(default_query_logger_path); + } + CRITICAL_SECTION_FIN(default_query_logger_lock); +} + +void +grn_log_reopen(grn_ctx *ctx) +{ + grn_logger_reopen(ctx); + grn_query_logger_reopen(ctx); +} diff --git a/storage/mroonga/vendor/groonga/lib/mrb.c b/storage/mroonga/vendor/groonga/lib/mrb.c index 4d1e4b5a218..60d2172d520 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb.c +++ b/storage/mroonga/vendor/groonga/lib/mrb.c @@ -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 @@ -28,6 +28,10 @@ #include <ctype.h> +#ifdef WIN32 +# include <share.h> +#endif /* WIN32 */ + #define BUFFER_SIZE 2048 #define E_LOAD_ERROR (mrb_class_get(mrb, "LoadError")) @@ -45,9 +49,9 @@ grn_mrb_get_default_system_ruby_scripts_dir(void) base_dir = grn_win32_base_dir(); base_dir_length = strlen(base_dir); - strcpy(win32_ruby_scripts_dir_buffer, base_dir); - strcat(win32_ruby_scripts_dir_buffer, "/"); - strcat(win32_ruby_scripts_dir_buffer, relative_path); + grn_strcpy(win32_ruby_scripts_dir_buffer, PATH_MAX, base_dir); + grn_strcat(win32_ruby_scripts_dir_buffer, PATH_MAX, "/"); + grn_strcat(win32_ruby_scripts_dir_buffer, PATH_MAX, relative_path); win32_ruby_scripts_dir = win32_ruby_scripts_dir_buffer; } return win32_ruby_scripts_dir; @@ -64,14 +68,16 @@ grn_mrb_get_default_system_ruby_scripts_dir(void) const char * grn_mrb_get_system_ruby_scripts_dir(grn_ctx *ctx) { - const char *ruby_scripts_dir; + static char ruby_scripts_dir[GRN_ENV_BUFFER_SIZE]; - ruby_scripts_dir = getenv("GRN_RUBY_SCRIPTS_DIR"); - if (!ruby_scripts_dir) { - ruby_scripts_dir = grn_mrb_get_default_system_ruby_scripts_dir(); + grn_getenv("GRN_RUBY_SCRIPTS_DIR", + ruby_scripts_dir, + GRN_ENV_BUFFER_SIZE); + if (ruby_scripts_dir[0]) { + return ruby_scripts_dir; + } else { + return grn_mrb_get_default_system_ruby_scripts_dir(); } - - return ruby_scripts_dir; } static grn_bool @@ -89,7 +95,8 @@ grn_mrb_is_absolute_path(const char *path) } static grn_bool -grn_mrb_expand_script_path(grn_ctx *ctx, const char *path, char *expanded_path) +grn_mrb_expand_script_path(grn_ctx *ctx, const char *path, + char *expanded_path, size_t expanded_path_size) { const char *ruby_scripts_dir; char dir_last_char; @@ -98,15 +105,15 @@ grn_mrb_expand_script_path(grn_ctx *ctx, const char *path, char *expanded_path) if (grn_mrb_is_absolute_path(path)) { expanded_path[0] = '\0'; } else if (path[0] == '.' && path[1] == '/') { - strcpy(expanded_path, ctx->impl->mrb.base_directory); - strcat(expanded_path, "/"); + grn_strcpy(expanded_path, expanded_path_size, ctx->impl->mrb.base_directory); + grn_strcat(expanded_path, expanded_path_size, "/"); } else { ruby_scripts_dir = grn_mrb_get_system_ruby_scripts_dir(ctx); - strcpy(expanded_path, ruby_scripts_dir); + grn_strcpy(expanded_path, expanded_path_size, ruby_scripts_dir); dir_last_char = ruby_scripts_dir[strlen(expanded_path) - 1]; if (dir_last_char != '/') { - strcat(expanded_path, "/"); + grn_strcat(expanded_path, expanded_path_size, "/"); } } @@ -120,7 +127,7 @@ grn_mrb_expand_script_path(grn_ctx *ctx, const char *path, char *expanded_path) return GRN_FALSE; } - strcat(expanded_path, path); + grn_strcat(expanded_path, expanded_path_size, path); return GRN_TRUE; } @@ -139,16 +146,17 @@ grn_mrb_load(grn_ctx *ctx, const char *path) return mrb_nil_value(); } - if (!grn_mrb_expand_script_path(ctx, path, expanded_path)) { + if (!grn_mrb_expand_script_path(ctx, path, expanded_path, PATH_MAX)) { return mrb_nil_value(); } - file = fopen(expanded_path, "r"); + file = grn_fopen(expanded_path, "r"); if (!file) { char message[BUFFER_SIZE]; mrb_value exception; - snprintf(message, BUFFER_SIZE - 1, - "fopen: failed to open mruby script file: <%s>", expanded_path); + grn_snprintf(message, BUFFER_SIZE, BUFFER_SIZE, + "fopen: failed to open mruby script file: <%s>", + expanded_path); SERR(message); exception = mrb_exc_new(mrb, E_LOAD_ERROR, ctx->errbuf, strlen(ctx->errbuf)); @@ -160,8 +168,8 @@ grn_mrb_load(grn_ctx *ctx, const char *path) char current_base_directory[PATH_MAX]; char *last_directory; - strcpy(current_base_directory, data->base_directory); - strcpy(data->base_directory, expanded_path); + grn_strcpy(current_base_directory, PATH_MAX, data->base_directory); + grn_strcpy(data->base_directory, PATH_MAX, expanded_path); last_directory = strrchr(data->base_directory, '/'); if (last_directory) { last_directory[0] = '\0'; @@ -181,7 +189,7 @@ grn_mrb_load(grn_ctx *ctx, const char *path) } mrb_parser_free(parser); - strcpy(data->base_directory, current_base_directory); + grn_strcpy(data->base_directory, PATH_MAX, current_base_directory); } return result; diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c index bd288af8491..daa0caada06 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013-2014 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 @@ #include "../grn_db.h" #include "mrb_accessor.h" +#include "mrb_converter.h" static struct mrb_data_type mrb_grn_accessor_type = { "Groonga::Accessor", @@ -49,8 +50,25 @@ mrb_grn_accessor_next(mrb_state *mrb, mrb_value self) grn_accessor *accessor; accessor = DATA_PTR(self); - if (!accessor->next) { return mrb_nil_value(); } - return mrb_cptr_value(mrb, accessor->next); + return grn_mrb_value_from_grn_obj(mrb, (grn_obj *)(accessor->next)); +} + +static mrb_value +mrb_grn_accessor_have_next_p(mrb_state *mrb, mrb_value self) +{ + grn_accessor *accessor; + + accessor = DATA_PTR(self); + return mrb_bool_value(accessor->next != NULL); +} + +static mrb_value +mrb_grn_accessor_object(mrb_state *mrb, mrb_value self) +{ + grn_accessor *accessor; + + accessor = DATA_PTR(self); + return grn_mrb_value_from_grn_obj(mrb, accessor->obj); } void @@ -67,5 +85,9 @@ grn_mrb_accessor_init(grn_ctx *ctx) mrb_grn_accessor_initialize, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "next", mrb_grn_accessor_next, MRB_ARGS_NONE()); + mrb_define_method(mrb, klass, "have_next?", + mrb_grn_accessor_have_next_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, klass, "object", + mrb_grn_accessor_object, MRB_ARGS_NONE()); } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c index 2a304b68781..eb57a016148 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2014 Brazil + 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 @@ -127,6 +127,13 @@ grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk) mrb_fixnum_value(usec)); } break; + case GRN_DB_SHORT_TEXT : + case GRN_DB_TEXT : + case GRN_DB_LONG_TEXT : + mrb_value_ = mrb_str_new_static(mrb, + GRN_TEXT_VALUE(bulk), + GRN_TEXT_LEN(bulk)); + break; default : { #define MESSAGE_SIZE 4096 @@ -141,14 +148,14 @@ grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk) domain_name, GRN_TABLE_MAX_KEY_SIZE); grn_obj_unlink(ctx, domain); } else { - strcpy(domain_name, "unknown"); + grn_strcpy(domain_name, GRN_TABLE_MAX_KEY_SIZE, "unknown"); domain_name_size = strlen(domain_name); } - snprintf(message, MESSAGE_SIZE, - "unsupported bulk value type: <%d>(%.*s)", - bulk->header.domain, - domain_name_size, - 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); #undef MESSAGE_SIZE } @@ -158,6 +165,17 @@ grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk) return mrb_value_; } +grn_bool +grn_mrb_bulk_cast(mrb_state *mrb, grn_obj *from, grn_obj *to, grn_id domain_id) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_rc rc; + + grn_obj_reinit(ctx, to, domain_id, 0); + rc = grn_obj_cast(ctx, from, to, GRN_FALSE); + return rc == GRN_SUCCESS; +} + static mrb_value mrb_grn_bulk_initialize(mrb_state *mrb, mrb_value self) { diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h index e85b81568da..dd1f46fb84e 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h @@ -32,6 +32,10 @@ mrb_value grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk); grn_obj *grn_mrb_value_to_bulk(mrb_state *mrb, mrb_value mrb_value_, grn_obj *bulk); +grn_bool grn_mrb_bulk_cast(mrb_state *mrb, + grn_obj *from, + grn_obj *to, + grn_id domain_id); #ifdef __cplusplus } diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.c new file mode 100644 index 00000000000..7f4ff139de1 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.c @@ -0,0 +1,49 @@ +/* -*- 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 "mrb_ctx.h" +#include "mrb_content_type.h" + +void +grn_mrb_content_type_init(grn_ctx *ctx) +{ + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + struct RClass *module; + + module = mrb_define_module_under(mrb, data->module, "ContentType"); + + mrb_define_const(mrb, module, "NONE", + mrb_fixnum_value(GRN_CONTENT_NONE)); + mrb_define_const(mrb, module, "TSV", + mrb_fixnum_value(GRN_CONTENT_TSV)); + mrb_define_const(mrb, module, "JSON", + mrb_fixnum_value(GRN_CONTENT_JSON)); + mrb_define_const(mrb, module, "XML", + mrb_fixnum_value(GRN_CONTENT_XML)); + mrb_define_const(mrb, module, "MSGPACK", + mrb_fixnum_value(GRN_CONTENT_MSGPACK)); + mrb_define_const(mrb, module, "GROONGA_COMMAND_LIST", + mrb_fixnum_value(GRN_CONTENT_GROONGA_COMMAND_LIST)); +} +#endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.h new file mode 100644 index 00000000000..46103ff1a62 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.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_CONTENT_TYPE_H +#define GRN_MRB_CONTENT_TYPE_H + +#include "../grn_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void grn_mrb_content_type_init(grn_ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_MRB_CONTENT_TYPE_H */ diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c index 9686feb8bc9..e4c3aceb435 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013-2014 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 @@ -23,10 +23,119 @@ #include <mruby.h> #include <mruby/class.h> #include <mruby/data.h> +#include <mruby/string.h> #include "mrb_converter.h" #include "mrb_bulk.h" +void +grn_mrb_value_to_raw_data_buffer_init(mrb_state *mrb, + grn_mrb_value_to_raw_data_buffer *buffer) +{ + GRN_VOID_INIT(&(buffer->from)); + GRN_VOID_INIT(&(buffer->to)); +} + +void +grn_mrb_value_to_raw_data_buffer_fin(mrb_state *mrb, + grn_mrb_value_to_raw_data_buffer *buffer) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + + GRN_OBJ_FIN(ctx, &(buffer->from)); + GRN_OBJ_FIN(ctx, &(buffer->to)); +} + +void +grn_mrb_value_to_raw_data(mrb_state *mrb, + const char *context, + mrb_value mrb_value_, + grn_id domain_id, + grn_mrb_value_to_raw_data_buffer *buffer, + void **raw_value, + unsigned int *raw_value_size) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + enum mrb_vtype mrb_value_type; + grn_bool try_cast = GRN_FALSE; + grn_obj *from_bulk = NULL; + + if (mrb_nil_p(mrb_value_)) { + *raw_value = NULL; + *raw_value_size = 0; + return; + } + + mrb_value_type = mrb_type(mrb_value_); + + switch (mrb_value_type) { + case MRB_TT_STRING : + switch (domain_id) { + case GRN_DB_SHORT_TEXT : + case GRN_DB_TEXT : + case GRN_DB_LONG_TEXT : + *raw_value = RSTRING_PTR(mrb_value_); + *raw_value_size = RSTRING_LEN(mrb_value_); + break; + default : + try_cast = GRN_TRUE; + break; + } + break; + default : + { + struct RClass *klass; + grn_mrb_data *data = &(ctx->impl->mrb); + + klass = mrb_class(mrb, mrb_value_); + if (domain_id == GRN_DB_TIME && + klass == data->builtin.time_class) { + mrb_value mrb_sec; + mrb_value mrb_usec; + + mrb_sec = mrb_funcall(mrb, mrb_value_, "to_i", 0); + mrb_usec = mrb_funcall(mrb, mrb_value_, "usec", 0); + buffer->value.time_value = GRN_TIME_PACK(mrb_fixnum(mrb_sec), + mrb_fixnum(mrb_usec)); + *raw_value = &(buffer->value.time_value); + *raw_value_size = sizeof(buffer->value.time_value); + } else { + try_cast = GRN_TRUE; + if (mrb_value_type == MRB_TT_DATA && + klass == mrb_class_get_under(mrb, data->module, "Bulk")) { + from_bulk = DATA_PTR(mrb_value_); + } + } + } + break; + } + + if (!try_cast) { + return; + } + + if (!from_bulk) { + from_bulk = &(buffer->from); + grn_mrb_value_to_bulk(mrb, mrb_value_, from_bulk); + } + if (!grn_mrb_bulk_cast(mrb, from_bulk, &(buffer->to), domain_id)) { + grn_obj *domain; + char domain_name[GRN_TABLE_MAX_KEY_SIZE]; + int domain_name_size; + + domain = grn_ctx_at(ctx, domain_id); + domain_name_size = grn_obj_name(ctx, domain, domain_name, + GRN_TABLE_MAX_KEY_SIZE); + mrb_raisef(mrb, E_ARGUMENT_ERROR, + "%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_); + } + *raw_value = GRN_BULK_HEAD(&(buffer->to)); + *raw_value_size = GRN_BULK_VSIZE(&(buffer->to)); +} + struct RClass * grn_mrb_class_from_grn_obj(mrb_state *mrb, grn_obj *object) { @@ -85,8 +194,8 @@ grn_mrb_class_from_grn_obj(mrb_state *mrb, grn_obj *object) if (!klass) { #define BUFFER_SIZE 1024 char buffer[BUFFER_SIZE]; - snprintf(buffer, BUFFER_SIZE - 1, - "can't find class for object type: %#x", object->header.type); + grn_snprintf(buffer, BUFFER_SIZE, BUFFER_SIZE, + "can't find class for object type: %#x", object->header.type); mrb_raise(mrb, E_ARGUMENT_ERROR, buffer); #undef BUFFER_SIZE } @@ -154,16 +263,11 @@ mrb_grn_converter_singleton_convert(mrb_state *mrb, mrb_value klass) grn_mrb_value_to_bulk(mrb, mrb_from, from); to_type = grn_mrb_class_to_type(mrb, mrb_class_ptr(mrb_to_class)); - grn_obj_reinit(ctx, to, to_type, 0); - { - grn_rc rc; - rc = grn_obj_cast(ctx, from, to, GRN_FALSE); - if (rc != GRN_SUCCESS) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, - "failed to convert to %S: %S", - mrb_to_class, - from); - } + if (!grn_mrb_bulk_cast(mrb, from, to, to_type)) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, + "failed to convert to %S: %S", + mrb_to_class, + mrb_from); } return grn_mrb_value_from_bulk(mrb, to); diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h index 3dfe5e5a01a..c2cb58c0e6d 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h @@ -27,6 +27,26 @@ extern "C" { void grn_mrb_converter_init(grn_ctx *ctx); +typedef struct { + grn_obj from; + grn_obj to; + union { + int64_t time_value; + } value; +} grn_mrb_value_to_raw_data_buffer; + +void grn_mrb_value_to_raw_data_buffer_init(mrb_state *mrb, + grn_mrb_value_to_raw_data_buffer *buffer); +void grn_mrb_value_to_raw_data_buffer_fin(mrb_state *mrb, + grn_mrb_value_to_raw_data_buffer *buffer); +void grn_mrb_value_to_raw_data(mrb_state *mrb, + const char *context, + mrb_value mrb_value_, + grn_id domain_id, + grn_mrb_value_to_raw_data_buffer *buffer, + void **raw_value, + unsigned int *raw_value_size); + struct RClass *grn_mrb_class_from_grn_obj(mrb_state *mrb, grn_obj *object); mrb_value grn_mrb_value_from_grn_obj(mrb_state *mrb, grn_obj *object); diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c index f52342ae18e..3814313f3d0 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c @@ -58,6 +58,10 @@ ctx_array_reference(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "o", &mrb_id_or_name); + if (mrb_nil_p(mrb_id_or_name)) { + return mrb_nil_value(); + } + if (mrb_fixnum_p(mrb_id_or_name)) { grn_id id = mrb_fixnum(mrb_id_or_name); object = grn_ctx_at(ctx, id); @@ -220,449 +224,449 @@ grn_mrb_ctx_check(mrb_state *mrb) return; case GRN_END_OF_DATA: error_class = mrb_class_get_under(mrb, module, "EndOfData"); - snprintf(message, MESSAGE_SIZE, - "end of data: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "end of data: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_UNKNOWN_ERROR: error_class = mrb_class_get_under(mrb, module, "UnknownError"); - snprintf(message, MESSAGE_SIZE, - "unknown error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "unknown error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_OPERATION_NOT_PERMITTED: error_class = mrb_class_get_under(mrb, module, "OperationNotPermitted"); - snprintf(message, MESSAGE_SIZE, - "operation not permitted: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "operation not permitted: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_SUCH_FILE_OR_DIRECTORY: error_class = mrb_class_get_under(mrb, module, "NoSuchFileOrDirectory"); - snprintf(message, MESSAGE_SIZE, - "no such file or directory: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no such file or directory: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_SUCH_PROCESS: error_class = mrb_class_get_under(mrb, module, "NoSuchProcess"); - snprintf(message, MESSAGE_SIZE, - "no such process: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no such process: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_INTERRUPTED_FUNCTION_CALL: error_class = mrb_class_get_under(mrb, module, "InterruptedFunctionCall"); - snprintf(message, MESSAGE_SIZE, - "interrupted function call: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "interrupted function call: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_INPUT_OUTPUT_ERROR: error_class = mrb_class_get_under(mrb, module, "InputOutputError"); - snprintf(message, MESSAGE_SIZE, - "input output error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "input output error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_SUCH_DEVICE_OR_ADDRESS: error_class = mrb_class_get_under(mrb, module, "NoSuchDeviceOrAddress"); - snprintf(message, MESSAGE_SIZE, - "no such device or address: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no such device or address: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_ARG_LIST_TOO_LONG: error_class = mrb_class_get_under(mrb, module, "ArgListTooLong"); - snprintf(message, MESSAGE_SIZE, - "arg list too long: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "arg list too long: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_EXEC_FORMAT_ERROR: error_class = mrb_class_get_under(mrb, module, "ExecFormatError"); - snprintf(message, MESSAGE_SIZE, - "exec format error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "exec format error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_BAD_FILE_DESCRIPTOR: error_class = mrb_class_get_under(mrb, module, "BadFileDescriptor"); - snprintf(message, MESSAGE_SIZE, - "bad file descriptor: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "bad file descriptor: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_CHILD_PROCESSES: error_class = mrb_class_get_under(mrb, module, "NoChildProcesses"); - snprintf(message, MESSAGE_SIZE, - "no child processes: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no child processes: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_RESOURCE_TEMPORARILY_UNAVAILABLE: error_class = mrb_class_get_under(mrb, module, "ResourceTemporarilyUnavailable"); - snprintf(message, MESSAGE_SIZE, - "resource temporarily unavailable: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "resource temporarily unavailable: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NOT_ENOUGH_SPACE: error_class = mrb_class_get_under(mrb, module, "NotEnoughSpace"); - snprintf(message, MESSAGE_SIZE, - "not enough space: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "not enough space: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_PERMISSION_DENIED: error_class = mrb_class_get_under(mrb, module, "PermissionDenied"); - snprintf(message, MESSAGE_SIZE, - "permission denied: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "permission denied: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_BAD_ADDRESS: error_class = mrb_class_get_under(mrb, module, "BadAddress"); - snprintf(message, MESSAGE_SIZE, - "bad address: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "bad address: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_RESOURCE_BUSY: error_class = mrb_class_get_under(mrb, module, "ResourceBusy"); - snprintf(message, MESSAGE_SIZE, - "resource busy: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "resource busy: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_FILE_EXISTS: error_class = mrb_class_get_under(mrb, module, "FileExists"); - snprintf(message, MESSAGE_SIZE, - "file exists: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "file exists: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_IMPROPER_LINK: error_class = mrb_class_get_under(mrb, module, "ImproperLink"); - snprintf(message, MESSAGE_SIZE, - "improper link: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "improper link: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_SUCH_DEVICE: error_class = mrb_class_get_under(mrb, module, "NoSuchDevice"); - snprintf(message, MESSAGE_SIZE, - "no such device: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no such device: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NOT_A_DIRECTORY: error_class = mrb_class_get_under(mrb, module, "NotDirectory"); - snprintf(message, MESSAGE_SIZE, - "not directory: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "not directory: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_IS_A_DIRECTORY: error_class = mrb_class_get_under(mrb, module, "IsDirectory"); - snprintf(message, MESSAGE_SIZE, - "is directory: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "is directory: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_INVALID_ARGUMENT: error_class = mrb_class_get_under(mrb, module, "InvalidArgument"); - snprintf(message, MESSAGE_SIZE, - "invalid argument: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "invalid argument: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_TOO_MANY_OPEN_FILES_IN_SYSTEM: error_class = mrb_class_get_under(mrb, module, "TooManyOpenFilesInSystem"); - snprintf(message, MESSAGE_SIZE, - "too many open files in system: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "too many open files in system: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_TOO_MANY_OPEN_FILES: error_class = mrb_class_get_under(mrb, module, "TooManyOpenFiles"); - snprintf(message, MESSAGE_SIZE, - "too many open files: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "too many open files: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_INAPPROPRIATE_I_O_CONTROL_OPERATION: error_class = mrb_class_get_under(mrb, module, "InappropriateIOControlOperation"); - snprintf(message, MESSAGE_SIZE, - "inappropriate IO control operation: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "inappropriate IO control operation: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_FILE_TOO_LARGE: error_class = mrb_class_get_under(mrb, module, "FileTooLarge"); - snprintf(message, MESSAGE_SIZE, - "file too large: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "file too large: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_SPACE_LEFT_ON_DEVICE: error_class = mrb_class_get_under(mrb, module, "NoSpaceLeftOnDevice"); - snprintf(message, MESSAGE_SIZE, - "no space left on device: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no space left on device: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_INVALID_SEEK: error_class = mrb_class_get_under(mrb, module, "InvalidSeek"); - snprintf(message, MESSAGE_SIZE, - "invalid seek: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "invalid seek: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_READ_ONLY_FILE_SYSTEM: error_class = mrb_class_get_under(mrb, module, "ReadOnlyFileSystem"); - snprintf(message, MESSAGE_SIZE, - "read only file system: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "read only file system: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_TOO_MANY_LINKS: error_class = mrb_class_get_under(mrb, module, "TooManyLinks"); - snprintf(message, MESSAGE_SIZE, - "too many links: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "too many links: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_BROKEN_PIPE: error_class = mrb_class_get_under(mrb, module, "BrokenPipe"); - snprintf(message, MESSAGE_SIZE, - "broken pipe: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "broken pipe: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_DOMAIN_ERROR: error_class = mrb_class_get_under(mrb, module, "DomainError"); - snprintf(message, MESSAGE_SIZE, - "domain error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "domain error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_RESULT_TOO_LARGE: error_class = mrb_class_get_under(mrb, module, "ResultTooLarge"); - snprintf(message, MESSAGE_SIZE, - "result too large: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "result too large: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_RESOURCE_DEADLOCK_AVOIDED: error_class = mrb_class_get_under(mrb, module, "ResourceDeadlockAvoided"); - snprintf(message, MESSAGE_SIZE, - "resource deadlock avoided: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "resource deadlock avoided: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_MEMORY_AVAILABLE: error_class = mrb_class_get_under(mrb, module, "NoMemoryAvailable"); - snprintf(message, MESSAGE_SIZE, - "no memory available: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no memory available: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_FILENAME_TOO_LONG: error_class = mrb_class_get_under(mrb, module, "FilenameTooLong"); - snprintf(message, MESSAGE_SIZE, - "filename too long: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "filename too long: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_LOCKS_AVAILABLE: error_class = mrb_class_get_under(mrb, module, "NoLocksAvailable"); - snprintf(message, MESSAGE_SIZE, - "no locks available: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no locks available: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_FUNCTION_NOT_IMPLEMENTED: error_class = mrb_class_get_under(mrb, module, "FunctionNotImplemented"); - snprintf(message, MESSAGE_SIZE, - "function not implemented: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "function not implemented: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_DIRECTORY_NOT_EMPTY: error_class = mrb_class_get_under(mrb, module, "DirectoryNotEmpty"); - snprintf(message, MESSAGE_SIZE, - "directory not empty: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "directory not empty: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_ILLEGAL_BYTE_SEQUENCE: error_class = mrb_class_get_under(mrb, module, "IllegalByteSequence"); - snprintf(message, MESSAGE_SIZE, - "illegal byte sequence: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "illegal byte sequence: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_SOCKET_NOT_INITIALIZED: error_class = mrb_class_get_under(mrb, module, "SocketNotInitialized"); - snprintf(message, MESSAGE_SIZE, - "socket not initialized: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "socket not initialized: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_OPERATION_WOULD_BLOCK: error_class = mrb_class_get_under(mrb, module, "OperationWouldBlock"); - snprintf(message, MESSAGE_SIZE, - "operation would block: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "operation would block: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_ADDRESS_IS_NOT_AVAILABLE: error_class = mrb_class_get_under(mrb, module, "AddressIsNotAvailable"); - snprintf(message, MESSAGE_SIZE, - "address is not available: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "address is not available: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NETWORK_IS_DOWN: error_class = mrb_class_get_under(mrb, module, "NetworkIsDown"); - snprintf(message, MESSAGE_SIZE, - "network is down: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "network is down: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NO_BUFFER: error_class = mrb_class_get_under(mrb, module, "NoBuffer"); - snprintf(message, MESSAGE_SIZE, - "no buffer: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "no buffer: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_SOCKET_IS_ALREADY_CONNECTED: error_class = mrb_class_get_under(mrb, module, "SocketIsAlreadyConnected"); - snprintf(message, MESSAGE_SIZE, - "socket is already connected: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "socket is already connected: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_SOCKET_IS_NOT_CONNECTED: error_class = mrb_class_get_under(mrb, module, "SocketIsNotConnected"); - snprintf(message, MESSAGE_SIZE, - "socket is not connected: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "socket is not connected: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_SOCKET_IS_ALREADY_SHUTDOWNED: error_class = mrb_class_get_under(mrb, module, "SocketIsAlreadyShutdowned"); - snprintf(message, MESSAGE_SIZE, - "socket is already shutdowned: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "socket is already shutdowned: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_OPERATION_TIMEOUT: error_class = mrb_class_get_under(mrb, module, "OperationTimeout"); - snprintf(message, MESSAGE_SIZE, - "operation timeout: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "operation timeout: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_CONNECTION_REFUSED: error_class = mrb_class_get_under(mrb, module, "ConnectionRefused"); - snprintf(message, MESSAGE_SIZE, - "connection refused: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "connection refused: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_RANGE_ERROR: error_class = mrb_class_get_under(mrb, module, "RangeError"); - snprintf(message, MESSAGE_SIZE, - "range error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "range error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_TOKENIZER_ERROR: error_class = mrb_class_get_under(mrb, module, "TokenizerError"); - snprintf(message, MESSAGE_SIZE, - "tokenizer error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "tokenizer error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_FILE_CORRUPT: error_class = mrb_class_get_under(mrb, module, "FileCorrupt"); - snprintf(message, MESSAGE_SIZE, - "file corrupt: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "file corrupt: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_INVALID_FORMAT: error_class = mrb_class_get_under(mrb, module, "InvalidFormat"); - snprintf(message, MESSAGE_SIZE, - "invalid format: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "invalid format: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_OBJECT_CORRUPT: error_class = mrb_class_get_under(mrb, module, "ObjectCorrupt"); - snprintf(message, MESSAGE_SIZE, - "object corrupt: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "object corrupt: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_TOO_MANY_SYMBOLIC_LINKS: error_class = mrb_class_get_under(mrb, module, "TooManySymbolicLinks"); - snprintf(message, MESSAGE_SIZE, - "too many symbolic links: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "too many symbolic links: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NOT_SOCKET: error_class = mrb_class_get_under(mrb, module, "NotSocket"); - snprintf(message, MESSAGE_SIZE, - "not socket: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "not socket: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_OPERATION_NOT_SUPPORTED: error_class = mrb_class_get_under(mrb, module, "OperationNotSupported"); - snprintf(message, MESSAGE_SIZE, - "operation not supported: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "operation not supported: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_ADDRESS_IS_IN_USE: error_class = mrb_class_get_under(mrb, module, "AddressIsInUse"); - snprintf(message, MESSAGE_SIZE, - "address is in use: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "address is in use: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_ZLIB_ERROR: error_class = mrb_class_get_under(mrb, module, "ZlibError"); - snprintf(message, MESSAGE_SIZE, - "zlib error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "zlib error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_LZ4_ERROR: error_class = mrb_class_get_under(mrb, module, "LZ4Error"); - snprintf(message, MESSAGE_SIZE, - "LZ4 error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "LZ4 error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_STACK_OVER_FLOW: error_class = mrb_class_get_under(mrb, module, "StackOverFlow"); - snprintf(message, MESSAGE_SIZE, - "stack over flow: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "stack over flow: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_SYNTAX_ERROR: error_class = mrb_class_get_under(mrb, module, "SyntaxError"); - snprintf(message, MESSAGE_SIZE, - "syntax error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "syntax error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_RETRY_MAX: error_class = mrb_class_get_under(mrb, module, "RetryMax"); - snprintf(message, MESSAGE_SIZE, - "retry max: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "retry max: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_INCOMPATIBLE_FILE_FORMAT: error_class = mrb_class_get_under(mrb, module, "IncompatibleFileFormat"); - snprintf(message, MESSAGE_SIZE, - "incompatible file format: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "incompatible file format: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_UPDATE_NOT_ALLOWED: error_class = mrb_class_get_under(mrb, module, "UpdateNotAllowed"); - snprintf(message, MESSAGE_SIZE, - "update not allowed: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "update not allowed: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_TOO_SMALL_OFFSET: error_class = mrb_class_get_under(mrb, module, "TooSmallOffset"); - snprintf(message, MESSAGE_SIZE, - "too small offset: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "too small offset: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_TOO_LARGE_OFFSET: error_class = mrb_class_get_under(mrb, module, "TooLargeOffset"); - snprintf(message, MESSAGE_SIZE, - "too large offset: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "too large offset: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_TOO_SMALL_LIMIT: error_class = mrb_class_get_under(mrb, module, "TooSmallLimit"); - snprintf(message, MESSAGE_SIZE, - "too small limit: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "too small limit: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_CAS_ERROR: error_class = mrb_class_get_under(mrb, module, "CASError"); - snprintf(message, MESSAGE_SIZE, - "CAS error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "CAS error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_UNSUPPORTED_COMMAND_VERSION: error_class = mrb_class_get_under(mrb, module, "UnsupportedCommandVersion"); - snprintf(message, MESSAGE_SIZE, - "unsupported command version: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "unsupported command version: <%s>(%d)", + ctx->errbuf, ctx->rc); break; case GRN_NORMALIZER_ERROR: error_class = mrb_class_get_under(mrb, module, "NormalizerError"); - snprintf(message, MESSAGE_SIZE, - "normalizer error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "normalizer error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; default: error_class = mrb_class_get_under(mrb, module, "Error"); - snprintf(message, MESSAGE_SIZE, - "unsupported error: <%s>(%d)", - ctx->errbuf, ctx->rc); + grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, + "unsupported error: <%s>(%d)", + ctx->errbuf, ctx->rc); break; } #undef MESSAGE_SIZE diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c index df86d5579e4..dcae12a131a 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c @@ -33,7 +33,9 @@ #include "mrb_accessor.h" #include "mrb_ctx.h" #include "mrb_expr.h" +#include "mrb_operator.h" #include "mrb_converter.h" +#include "mrb_options.h" static struct mrb_data_type mrb_grn_scan_info_type = { "Groonga::ScanInfo", @@ -99,17 +101,35 @@ mrb_grn_expr_code_initialize(mrb_state *mrb, mrb_value self) static mrb_value mrb_grn_scan_info_put_index(mrb_state *mrb, mrb_value self) { + grn_ctx *ctx = (grn_ctx *)mrb->ud; + scan_info *si; + mrb_value mrb_index; int sid; int32_t weight; - scan_info *si; - grn_ctx *ctx = (grn_ctx *)mrb->ud; + mrb_value mrb_scorer; + mrb_value mrb_scorer_args_expr; + int32_t scorer_args_expr_offset; grn_obj *index; - mrb_value mrb_index; - - mrb_get_args(mrb, "oii", &mrb_index, &sid, &weight); + grn_obj *scorer = NULL; + grn_obj *scorer_args_expr = NULL; + + mrb_get_args(mrb, "oiiooi", + &mrb_index, &sid, &weight, + &mrb_scorer, + &mrb_scorer_args_expr, + &scorer_args_expr_offset); si = DATA_PTR(self); index = DATA_PTR(mrb_index); - grn_scan_info_put_index(ctx, si, index, sid, weight); + if (!mrb_nil_p(mrb_scorer)) { + scorer = DATA_PTR(mrb_scorer); + } + if (!mrb_nil_p(mrb_scorer_args_expr)) { + scorer_args_expr = DATA_PTR(mrb_scorer_args_expr); + } + grn_scan_info_put_index(ctx, si, index, sid, weight, + scorer, + scorer_args_expr, + scorer_args_expr_offset); return self; } @@ -121,17 +141,19 @@ mrb_grn_scan_info_get_op(mrb_state *mrb, mrb_value self) si = DATA_PTR(self); op = grn_scan_info_get_op(si); - return mrb_fixnum_value(op); + return grn_mrb_value_from_operator(mrb, op); } static mrb_value mrb_grn_scan_info_set_op(mrb_state *mrb, mrb_value self) { scan_info *si; + mrb_value mrb_op; grn_operator op; - mrb_get_args(mrb, "i", &op); + mrb_get_args(mrb, "o", &mrb_op, &op); si = DATA_PTR(self); + op = grn_mrb_value_to_operator(mrb, mrb_op); grn_scan_info_set_op(si, op); return self; } @@ -191,10 +213,12 @@ static mrb_value mrb_grn_scan_info_set_logical_op(mrb_state *mrb, mrb_value self) { scan_info *si; + mrb_value mrb_logical_op; grn_operator logical_op; - mrb_get_args(mrb, "i", &logical_op); + mrb_get_args(mrb, "o", &mrb_logical_op); si = DATA_PTR(self); + logical_op = grn_mrb_value_to_operator(mrb, mrb_logical_op); grn_scan_info_set_logical_op(si, logical_op); return self; } @@ -207,7 +231,7 @@ mrb_grn_scan_info_get_logical_op(mrb_state *mrb, mrb_value self) si = DATA_PTR(self); logical_op = grn_scan_info_get_logical_op(si); - return mrb_fixnum_value(logical_op); + return grn_mrb_value_from_operator(mrb, logical_op); } static mrb_value @@ -257,33 +281,6 @@ mrb_grn_scan_info_get_similarity_threshold(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_grn_scan_info_set_scorer(mrb_state *mrb, mrb_value self) -{ - scan_info *si; - mrb_value mrb_scorer; - - mrb_get_args(mrb, "o", &mrb_scorer); - si = DATA_PTR(self); - if (mrb_nil_p(mrb_scorer)) { - grn_scan_info_set_scorer(si, NULL); - } else { - grn_scan_info_set_scorer(si, DATA_PTR(mrb_scorer)); - } - return self; -} - -static mrb_value -mrb_grn_scan_info_get_scorer(mrb_state *mrb, mrb_value self) -{ - scan_info *si; - grn_obj *scorer; - - si = DATA_PTR(self); - scorer = grn_scan_info_get_scorer(si); - return grn_mrb_value_from_grn_obj(mrb, scorer); -} - -static mrb_value mrb_grn_scan_info_get_arg(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; @@ -315,11 +312,86 @@ mrb_grn_scan_info_push_arg(mrb_state *mrb, mrb_value self) } static mrb_value +mrb_grn_expr_code_inspect(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_expr_code *code; + mrb_value inspected; + + code = DATA_PTR(self); + + inspected = mrb_str_buf_new(mrb, 48); + + mrb_str_cat_lit(mrb, inspected, "#<"); + mrb_str_cat_cstr(mrb, inspected, mrb_obj_classname(mrb, self)); + mrb_str_cat_lit(mrb, inspected, ":"); + mrb_str_concat(mrb, inspected, mrb_ptr_to_str(mrb, mrb_cptr(self))); + + { + int32_t weight; + uint32_t offset; + + weight = grn_expr_code_get_weight(ctx, DATA_PTR(self), &offset); + + mrb_str_cat_lit(mrb, inspected, " weight="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + mrb_fixnum_value(weight), + "inspect", + 0)); + mrb_str_cat_lit(mrb, inspected, ", offset="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + mrb_fixnum_value(offset), + "inspect", + 0)); + } + + mrb_str_cat_lit(mrb, inspected, ", modify="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + mrb_fixnum_value(code->modify), + "inspect", + 0)); + + mrb_str_cat_lit(mrb, inspected, ", op="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + grn_mrb_value_from_operator(mrb, code->op), + "inspect", + 0)); + + mrb_str_cat_lit(mrb, inspected, ", flags="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + mrb_fixnum_value(code->flags), + "inspect", + 0)); + + mrb_str_cat_lit(mrb, inspected, ", value="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + grn_mrb_value_from_grn_obj(mrb, code->value), + "inspect", + 0)); + + mrb_str_cat_lit(mrb, inspected, ">"); + + return inspected; +} + +static mrb_value mrb_grn_expr_code_get_weight(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; + int32_t weight; + uint32_t offset; + mrb_value mrb_values[2]; - return mrb_fixnum_value(grn_expr_code_get_weight(ctx, DATA_PTR(self))); + weight = grn_expr_code_get_weight(ctx, DATA_PTR(self), &offset); + mrb_values[0] = mrb_fixnum_value(weight); + mrb_values[1] = mrb_fixnum_value(offset); + return mrb_ary_new_from_values(mrb, 2, mrb_values); } static mrb_value @@ -337,7 +409,7 @@ mrb_grn_expr_code_get_op(mrb_state *mrb, mrb_value self) grn_expr_code *expr_code; expr_code = DATA_PTR(self); - return mrb_fixnum_value(expr_code->op); + return grn_mrb_value_from_operator(mrb, expr_code->op); } static mrb_value @@ -491,8 +563,7 @@ mrb_grn_expression_parse(mrb_state *mrb, mrb_value self) if (!mrb_nil_p(mrb_options)) { mrb_value mrb_flags; - mrb_flags = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "flags"))); + mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags"); if (!mrb_nil_p(mrb_flags)) { flags = mrb_fixnum(mrb_flags); } @@ -512,13 +583,15 @@ mrb_grn_expression_append_object(mrb_state *mrb, mrb_value self) grn_obj *expr; mrb_value mrb_object; grn_obj *object; + mrb_value mrb_op; grn_operator op; int n_args; expr = DATA_PTR(self); - mrb_get_args(mrb, "oii", &mrb_object, &op, &n_args); + mrb_get_args(mrb, "ooi", &mrb_object, &mrb_op, &n_args); object = DATA_PTR(mrb_object); + op = grn_mrb_value_to_operator(mrb, mrb_op); grn_expr_append_obj(ctx, expr, object, op, n_args); grn_mrb_ctx_check(mrb); @@ -531,12 +604,14 @@ mrb_grn_expression_append_constant(mrb_state *mrb, mrb_value self) grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *expr; mrb_value mrb_constant; + mrb_value mrb_op; grn_operator op; int n_args; expr = DATA_PTR(self); - mrb_get_args(mrb, "oii", &mrb_constant, &op, &n_args); + mrb_get_args(mrb, "ooi", &mrb_constant, &mrb_op, &n_args); + op = grn_mrb_value_to_operator(mrb, mrb_op); switch (mrb_type(mrb_constant)) { case MRB_TT_FALSE : if (mrb_nil_p(mrb_constant)) { @@ -624,12 +699,14 @@ mrb_grn_expression_append_operator(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *expr; - grn_operator op; + mrb_value mrb_op; int n_args; + grn_operator op; expr = DATA_PTR(self); - mrb_get_args(mrb, "ii", &op, &n_args); + mrb_get_args(mrb, "oi", &mrb_op, &n_args); + op = grn_mrb_value_to_operator(mrb, mrb_op); grn_expr_append_op(ctx, expr, op, n_args); grn_mrb_ctx_check(mrb); @@ -649,7 +726,7 @@ grn_mrb_expr_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "initialize", mrb_grn_scan_info_initialize, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "put_index", - mrb_grn_scan_info_put_index, MRB_ARGS_REQ(3)); + mrb_grn_scan_info_put_index, MRB_ARGS_REQ(6)); mrb_define_method(mrb, klass, "op", mrb_grn_scan_info_get_op, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "op=", @@ -674,10 +751,6 @@ grn_mrb_expr_init(grn_ctx *ctx) mrb_grn_scan_info_get_similarity_threshold, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "similarity_threshold=", mrb_grn_scan_info_set_similarity_threshold, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, klass, "scorer", - mrb_grn_scan_info_get_scorer, MRB_ARGS_NONE()); - mrb_define_method(mrb, klass, "scorer=", - mrb_grn_scan_info_set_scorer, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "get_arg", mrb_grn_scan_info_get_arg, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "push_arg", @@ -688,6 +761,8 @@ grn_mrb_expr_init(grn_ctx *ctx) MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); mrb_define_method(mrb, klass, "initialize", mrb_grn_expr_code_initialize, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "inspect", + mrb_grn_expr_code_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "weight", mrb_grn_expr_code_get_weight, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "value", @@ -697,6 +772,14 @@ grn_mrb_expr_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "flags", mrb_grn_expr_code_get_flags, MRB_ARGS_NONE()); + { + struct RClass *expression_code_class = klass; + struct RClass *flags_module; + flags_module = mrb_define_module_under(mrb, expression_code_class, "Flags"); + mrb_define_const(mrb, flags_module, "RELATIONAL_EXPRESSION", + mrb_fixnum_value(GRN_EXPR_CODE_RELATIONAL_EXPRESSION)); + } + klass = mrb_define_class_under(mrb, module, "Expression", object_class); MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); @@ -724,11 +807,6 @@ grn_mrb_expr_init(grn_ctx *ctx) mrb_grn_expression_append_constant, MRB_ARGS_REQ(3)); mrb_define_method(mrb, klass, "append_operator", mrb_grn_expression_append_operator, MRB_ARGS_REQ(2)); - - grn_mrb_load(ctx, "expression.rb"); - grn_mrb_load(ctx, "scan_info.rb"); - grn_mrb_load(ctx, "scan_info_data.rb"); - grn_mrb_load(ctx, "scan_info_builder.rb"); } scan_info ** @@ -747,7 +825,7 @@ grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr); mrb_sis = mrb_funcall(mrb, mrb_expression, "build_scan_info", 2, - mrb_fixnum_value(op), + grn_mrb_value_from_operator(mrb, op), mrb_fixnum_value(size)); if (mrb_nil_p(mrb_sis)) { @@ -781,4 +859,31 @@ exit: return sis; } + +unsigned int +grn_mrb_expr_estimate_size(grn_ctx *ctx, grn_obj *expr, grn_obj *table) +{ + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + mrb_value mrb_expression; + mrb_value mrb_table; + mrb_value mrb_size; + unsigned int size; + int arena_index; + + arena_index = mrb_gc_arena_save(mrb); + + mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr); + mrb_table = grn_mrb_value_from_grn_obj(mrb, table); + mrb_size = mrb_funcall(mrb, mrb_expression, "estimate_size", 1, mrb_table); + if (mrb->exc) { + size = grn_table_size(ctx, table); + } else { + size = mrb_fixnum(mrb_size); + } + + mrb_gc_arena_restore(mrb, arena_index); + + return size; +} #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h index 687565dd6d9..0564401dac9 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.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 @@ -28,6 +28,9 @@ extern "C" { void grn_mrb_expr_init(grn_ctx *ctx); scan_info **grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, grn_operator op, uint32_t size); +unsigned int grn_mrb_expr_estimate_size(grn_ctx *ctx, + grn_obj *expr, + grn_obj *table); #ifdef __cplusplus } diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c index a5a4e797de2..31d00956137 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2014 Brazil + 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 @@ -22,8 +22,11 @@ #include <mruby.h> #include <mruby/class.h> #include <mruby/data.h> +#include <mruby/string.h> +#include "mrb_ctx.h" #include "mrb_hash_table.h" +#include "mrb_options.h" static struct mrb_data_type mrb_grn_hash_table_type = { "Groonga::HashTable", @@ -31,6 +34,56 @@ static struct mrb_data_type mrb_grn_hash_table_type = { }; static mrb_value +mrb_grn_hash_table_singleton_create(mrb_state *mrb, mrb_value klass) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + mrb_value mrb_options = mrb_nil_value(); + const char *name = NULL; + unsigned int name_size = 0; + const char *path = NULL; + grn_obj_flags flags = GRN_OBJ_TABLE_HASH_KEY; + grn_obj *key_type = NULL; + grn_obj *value_type = NULL; + grn_obj *table; + + mrb_get_args(mrb, "|H", &mrb_options); + + if (!mrb_nil_p(mrb_options)) { + mrb_value mrb_name; + mrb_value mrb_flags; + mrb_value mrb_key_type; + mrb_value mrb_value_type; + + mrb_name = grn_mrb_options_get_lit(mrb, mrb_options, "name"); + if (!mrb_nil_p(mrb_name)) { + name = RSTRING_PTR(mrb_name); + name_size = RSTRING_LEN(mrb_name); + } + + mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags"); + if (!mrb_nil_p(mrb_flags)) { + flags |= mrb_fixnum(mrb_flags); + } + + mrb_key_type = grn_mrb_options_get_lit(mrb, mrb_options, "key_type"); + if (!mrb_nil_p(mrb_key_type)) { + key_type = DATA_PTR(mrb_key_type); + } + + mrb_value_type = grn_mrb_options_get_lit(mrb, mrb_options, "value_type"); + if (!mrb_nil_p(mrb_value_type)) { + key_type = DATA_PTR(mrb_value_type); + } + } + + table = grn_table_create(ctx, name, name_size, path, flags, + key_type, value_type); + grn_mrb_ctx_check(mrb); + + return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, table)); +} + +static mrb_value mrb_grn_hash_table_initialize(mrb_state *mrb, mrb_value self) { mrb_value mrb_hash_table_ptr; @@ -54,6 +107,10 @@ grn_mrb_hash_table_init(grn_ctx *ctx) klass = mrb_define_class_under(mrb, module, "HashTable", table_class); MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); + mrb_define_singleton_method(mrb, (struct RObject *)klass, "create", + mrb_grn_hash_table_singleton_create, + MRB_ARGS_OPT(1)); + mrb_define_method(mrb, klass, "initialize", mrb_grn_hash_table_initialize, MRB_ARGS_REQ(1)); } 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 d91aa576e8e..eb85ff955fa 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2014 Brazil + 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 @@ -17,13 +17,17 @@ */ #include "../grn_ctx_impl.h" +#include "../grn_ii.h" #ifdef GRN_WITH_MRUBY #include <mruby.h> #include <mruby/class.h> #include <mruby/data.h> +#include "mrb_converter.h" #include "mrb_index_column.h" +#include "mrb_operator.h" +#include "mrb_options.h" static struct mrb_data_type mrb_grn_index_column_type = { "Groonga::IndexColumn", @@ -41,6 +45,84 @@ mrb_grn_index_column_initialize(mrb_state *mrb, mrb_value self) return self; } +static mrb_value +mrb_grn_index_column_get_lexicon(mrb_state *mrb, mrb_value self) +{ + grn_obj *index_column; + grn_obj *lexicon; + + index_column = DATA_PTR(self); + lexicon = ((grn_ii *)index_column)->lexicon; + + return grn_mrb_value_from_grn_obj(mrb, lexicon); +} + +static mrb_value +mrb_grn_index_column_estimate_size_for_term_id(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *index_column; + mrb_int term_id; + unsigned int size; + + index_column = DATA_PTR(self); + mrb_get_args(mrb, "i", &term_id); + + size = grn_ii_estimate_size(ctx, (grn_ii *)index_column, term_id); + return mrb_fixnum_value(size); +} + +static mrb_value +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; + 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); + + memset(&optarg, 0, sizeof(grn_search_optarg)); + optarg.mode = GRN_OP_EXACT; + + if (!mrb_nil_p(mrb_options)) { + mrb_value mrb_mode; + + mrb_mode = grn_mrb_options_get_lit(mrb, mrb_options, "mode"); + if (!mrb_nil_p(mrb_mode)) { + optarg.mode = grn_mrb_value_to_operator(mrb, mrb_mode); + } + } + + size = grn_ii_estimate_size_for_query(ctx, (grn_ii *)index_column, + query, query_len, &optarg); + return mrb_fixnum_value(size); +} + +static mrb_value +mrb_grn_index_column_estimate_size_for_lexicon_cursor(mrb_state *mrb, + mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *index_column; + mrb_value mrb_lexicon_cursor; + grn_table_cursor *lexicon_cursor; + unsigned int size; + + index_column = DATA_PTR(self); + mrb_get_args(mrb, "o", &mrb_lexicon_cursor); + + lexicon_cursor = DATA_PTR(mrb_lexicon_cursor); + size = grn_ii_estimate_size_for_lexicon_cursor(ctx, + (grn_ii *)index_column, + lexicon_cursor); + return mrb_fixnum_value(size); +} + void grn_mrb_index_column_init(grn_ctx *ctx) { @@ -55,5 +137,19 @@ grn_mrb_index_column_init(grn_ctx *ctx) MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); mrb_define_method(mrb, klass, "initialize", mrb_grn_index_column_initialize, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, klass, "lexicon", + mrb_grn_index_column_get_lexicon, + MRB_ARGS_NONE()); + + mrb_define_method(mrb, klass, "estimate_size_for_term_id", + mrb_grn_index_column_estimate_size_for_term_id, + MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "estimate_size_for_query", + mrb_grn_index_column_estimate_size_for_query, + MRB_ARGS_ARG(1, 1)); + mrb_define_method(mrb, klass, "estimate_size_for_lexicon_cursor", + mrb_grn_index_column_estimate_size_for_lexicon_cursor, + MRB_ARGS_REQ(1)); } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c index f57d59d727c..34133ff7ae0 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c @@ -17,6 +17,8 @@ */ #include "../grn_ctx_impl.h" +#include "../grn_ii.h" +#include "../grn_db.h" #ifdef GRN_WITH_MRUBY #include <mruby.h> @@ -24,9 +26,12 @@ #include <mruby/data.h> #include <mruby/string.h> #include <mruby/hash.h> +#include <mruby/variable.h> #include "mrb_ctx.h" #include "mrb_index_cursor.h" +#include "mrb_converter.h" +#include "mrb_options.h" static struct mrb_data_type mrb_grn_index_cursor_type = { "Groonga::IndexCursor", @@ -46,6 +51,7 @@ mrb_grn_index_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass) grn_id rid_min = GRN_ID_NIL; grn_id rid_max = GRN_ID_MAX; int flags = 0; + mrb_value mrb_index_cursor; mrb_get_args(mrb, "oo|H", &mrb_table_cursor, &mrb_index, &mrb_options); @@ -58,7 +64,10 @@ mrb_grn_index_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass) rid_min, rid_max, flags); grn_mrb_ctx_check(mrb); - return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, index_cursor)); + mrb_index_cursor = mrb_funcall(mrb, klass, "new", 1, + mrb_cptr_value(mrb, index_cursor)); + mrb_iv_set(mrb, mrb_index_cursor, mrb_intern_lit(mrb, "@index"), mrb_index); + return mrb_index_cursor; } static mrb_value @@ -103,6 +112,91 @@ mrb_grn_index_cursor_count(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(n_records); } +static mrb_value +mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + mrb_value mrb_result_set; + mrb_value mrb_options; + grn_obj *index_cursor; + grn_obj *expr = NULL; + grn_obj *expr_variable = NULL; + int offset = 0; + int limit = 10; + int n_matched_records = 0; + mrb_value mrb_index; + grn_obj *index; + grn_obj *lexicon; + grn_obj *data_table; + grn_hash *result_set; + grn_posting *posting; + grn_id term_id; + grn_operator op = GRN_OP_OR; + + mrb_get_args(mrb, "o|H", &mrb_result_set, &mrb_options); + + index_cursor = DATA_PTR(self); + result_set = DATA_PTR(mrb_result_set); + + if (!mrb_nil_p(mrb_options)) { + mrb_value mrb_expr; + mrb_value mrb_offset; + mrb_value mrb_limit; + + mrb_expr = grn_mrb_options_get_lit(mrb, mrb_options, "expression"); + if (!mrb_nil_p(mrb_expr)) { + expr = DATA_PTR(mrb_expr); + expr_variable = grn_expr_get_var_by_offset(ctx, expr, 0); + } + + mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset"); + if (!mrb_nil_p(mrb_offset)) { + offset = mrb_fixnum(mrb_offset); + } + + mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit"); + if (!mrb_nil_p(mrb_limit)) { + limit = mrb_fixnum(mrb_limit); + } + } + + if (limit <= 0) { + return mrb_fixnum_value(n_matched_records); + } + + mrb_index = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@index")); + index = DATA_PTR(mrb_index); + lexicon = ((grn_ii *)index)->lexicon; + data_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, index)); + + while ((posting = grn_index_cursor_next(ctx, index_cursor, &term_id))) { + if (expr) { + grn_bool matched_raw; + grn_obj *matched; + + GRN_RECORD_SET(ctx, expr_variable, posting->rid); + matched = grn_expr_exec(ctx, expr, 0); + GRN_TRUEP(ctx, matched, matched_raw); + if (!matched_raw) { + continue; + } + } + n_matched_records++; + if (offset > 0) { + offset--; + continue; + } + grn_ii_posting_add(ctx, (grn_ii_posting *)posting, result_set, op); + limit--; + if (limit == 0) { + break; + } + } + grn_ii_resolve_sel_and(ctx, result_set, op); + + return mrb_fixnum_value(n_matched_records); +} + void grn_mrb_index_cursor_init(grn_ctx *ctx) { @@ -124,5 +218,7 @@ grn_mrb_index_cursor_init(grn_ctx *ctx) mrb_grn_index_cursor_close, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "count", mrb_grn_index_cursor_count, MRB_ARGS_NONE()); + mrb_define_method(mrb, klass, "select", + mrb_grn_index_cursor_select, MRB_ARGS_ARG(1, 1)); } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c index 60398b91829..8efaa41e50d 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013-2014 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 @@ -27,9 +27,39 @@ #include "../grn_mrb.h" #include "mrb_object.h" +#include "mrb_operator.h" #include "mrb_converter.h" static mrb_value +object_inspect(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *object; + mrb_value inspected; + + object = DATA_PTR(self); + inspected = mrb_str_buf_new(mrb, 48); + + mrb_str_cat_lit(mrb, inspected, "#<"); + mrb_str_cat_cstr(mrb, inspected, mrb_obj_classname(mrb, self)); + mrb_str_cat_lit(mrb, inspected, ":"); + mrb_str_concat(mrb, inspected, mrb_ptr_to_str(mrb, mrb_cptr(self))); + if (object) { + grn_obj buffer; + GRN_TEXT_INIT(&buffer, 0); + grn_inspect(ctx, &buffer, object); + mrb_str_cat_lit(mrb, inspected, " "); + mrb_str_cat(mrb, inspected, GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer)); + GRN_OBJ_FIN(ctx, &buffer); + } else { + mrb_str_cat_lit(mrb, inspected, " (closed)"); + } + mrb_str_cat_lit(mrb, inspected, ">"); + + return inspected; +} + +static mrb_value object_get_id(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; @@ -60,19 +90,19 @@ object_find_index(mrb_state *mrb, mrb_value self) grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *object; mrb_value mrb_operator; - grn_obj *index; - int n_indexes; - int section_id; + grn_operator operator; + grn_index_datum index_datum; + int n_index_data; mrb_get_args(mrb, "o", &mrb_operator); object = DATA_PTR(self); - n_indexes = grn_column_index(ctx, - object, - mrb_fixnum(mrb_operator), - &index, - 1, - §ion_id); - if (n_indexes == 0) { + operator = grn_mrb_value_to_operator(mrb, mrb_operator); + n_index_data = grn_column_find_index_data(ctx, + object, + operator, + &index_datum, + 1); + if (n_index_data == 0) { return mrb_nil_value(); } else { grn_mrb_data *data; @@ -81,8 +111,8 @@ object_find_index(mrb_state *mrb, mrb_value self) data = &(ctx->impl->mrb); klass = mrb_class_get_under(mrb, data->module, "IndexInfo"); - args[0] = grn_mrb_value_from_grn_obj(mrb, index); - args[1] = mrb_fixnum_value(section_id); + args[0] = grn_mrb_value_from_grn_obj(mrb, index_datum.index); + args[1] = mrb_fixnum_value(index_datum.section); return mrb_obj_new(mrb, klass, 2, args); } } @@ -140,6 +170,39 @@ object_close(mrb_state *mrb, mrb_value self) } static mrb_value +object_get_domain_id(mrb_state *mrb, mrb_value self) +{ + grn_obj *object; + grn_id domain_id; + + object = DATA_PTR(self); + domain_id = object->header.domain; + + if (domain_id == GRN_ID_NIL) { + return mrb_nil_value(); + } else { + return mrb_fixnum_value(domain_id); + } +} + +static mrb_value +object_get_range_id(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *object; + grn_id range_id; + + object = DATA_PTR(self); + range_id = grn_obj_get_range(ctx, object); + + if (range_id == GRN_ID_NIL) { + return mrb_nil_value(); + } else { + return mrb_fixnum_value(range_id); + } +} + +static mrb_value object_is_temporary(mrb_state *mrb, mrb_value self) { grn_obj *object; @@ -173,6 +236,9 @@ grn_mrb_object_init(grn_ctx *ctx) MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); data->object_class = klass; + mrb_define_method(mrb, klass, "inspect", + 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()); mrb_define_method(mrb, klass, "find_index", @@ -182,6 +248,11 @@ grn_mrb_object_init(grn_ctx *ctx) 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, "domain_id", object_get_domain_id, + MRB_ARGS_NONE()); + mrb_define_method(mrb, klass, "range_id", object_get_range_id, + MRB_ARGS_NONE()); + mrb_define_method(mrb, klass, "temporary?", object_is_temporary, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "persistent?", object_is_persistent, diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c new file mode 100644 index 00000000000..c8accada692 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c @@ -0,0 +1,95 @@ +/* -*- 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/string.h> +# include <mruby/class.h> +# include <mruby/data.h> + +# include "../grn_mrb.h" +# include "mrb_object.h" +# include "mrb_operator.h" +# include "mrb_converter.h" + +void +grn_mrb_object_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, "ObjectFlags"); + +#define MRB_DEFINE_FLAG(name) \ + mrb_define_const(mrb, flags_module, #name, \ + mrb_fixnum_value(GRN_OBJ_ ## name)) + + MRB_DEFINE_FLAG(TABLE_TYPE_MASK); + MRB_DEFINE_FLAG(TABLE_HASH_KEY); + MRB_DEFINE_FLAG(TABLE_PAT_KEY); + MRB_DEFINE_FLAG(TABLE_DAT_KEY); + MRB_DEFINE_FLAG(TABLE_NO_KEY); + + MRB_DEFINE_FLAG(KEY_MASK); + MRB_DEFINE_FLAG(KEY_UINT); + MRB_DEFINE_FLAG(KEY_INT); + MRB_DEFINE_FLAG(KEY_FLOAT); + MRB_DEFINE_FLAG(KEY_GEO_POINT); + + MRB_DEFINE_FLAG(KEY_WITH_SIS); + MRB_DEFINE_FLAG(KEY_NORMALIZE); + + MRB_DEFINE_FLAG(COLUMN_TYPE_MASK); + MRB_DEFINE_FLAG(COLUMN_SCALAR); + MRB_DEFINE_FLAG(COLUMN_VECTOR); + MRB_DEFINE_FLAG(COLUMN_INDEX); + + MRB_DEFINE_FLAG(COMPRESS_MASK); + MRB_DEFINE_FLAG(COMPRESS_NONE); + MRB_DEFINE_FLAG(COMPRESS_ZLIB); + MRB_DEFINE_FLAG(COMPRESS_LZ4); + + MRB_DEFINE_FLAG(WITH_SECTION); + MRB_DEFINE_FLAG(WITH_WEIGHT); + MRB_DEFINE_FLAG(WITH_POSITION); + MRB_DEFINE_FLAG(RING_BUFFER); + + MRB_DEFINE_FLAG(UNIT_MASK); + MRB_DEFINE_FLAG(UNIT_DOCUMENT_NONE); + MRB_DEFINE_FLAG(UNIT_DOCUMENT_SECTION); + MRB_DEFINE_FLAG(UNIT_DOCUMENT_POSITION); + MRB_DEFINE_FLAG(UNIT_SECTION_NONE); + MRB_DEFINE_FLAG(UNIT_SECTION_POSITION); + MRB_DEFINE_FLAG(UNIT_POSITION_NONE); + MRB_DEFINE_FLAG(UNIT_USERDEF_DOCUMENT); + MRB_DEFINE_FLAG(UNIT_USERDEF_SECTION); + MRB_DEFINE_FLAG(UNIT_USERDEF_POSITION); + + MRB_DEFINE_FLAG(NO_SUBREC); + MRB_DEFINE_FLAG(WITH_SUBREC); + + MRB_DEFINE_FLAG(KEY_VAR_SIZE); + + MRB_DEFINE_FLAG(TEMPORARY); + MRB_DEFINE_FLAG(PERSISTENT); +} +#endif /* GRN_WITH_MRUBY */ diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h new file mode 100644 index 00000000000..60c82227078 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_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_OBJECT_FLAGS_H +#define GRN_MRB_OBJECT_FLAGS_H + +#include "../grn_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void grn_mrb_object_flags_init(grn_ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_MRB_OBJECT_FLAGS_H */ diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c index ca2fc74a38a..2e0cb481722 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2014 Brazil + 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 @@ -23,168 +23,132 @@ #include "mrb_operator.h" +mrb_value +grn_mrb_value_from_operator(mrb_state *mrb, grn_operator op) +{ + grn_ctx *ctx = (grn_ctx *)(mrb->ud); + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_value mrb_op_raw; + mrb_value mrb_op; + + mrb_op_raw = mrb_fixnum_value(op); + mrb_op = mrb_funcall(mrb, mrb_obj_value(data->groonga.operator_class), + "find", 1, mrb_op_raw); + if (mrb_nil_p(mrb_op)) { + return mrb_op_raw; + } else { + return mrb_op; + } +} + +grn_operator +grn_mrb_value_to_operator(mrb_state *mrb, mrb_value mrb_op) +{ + if (!mrb_fixnum_p(mrb_op)) { + mrb_op = mrb_funcall(mrb, mrb_op, "value", 0); + } + + return mrb_fixnum(mrb_op); +} + void grn_mrb_operator_init(grn_ctx *ctx) { - mrb_state *mrb = ctx->impl->mrb.state; + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; struct RClass *module = ctx->impl->mrb.module; - struct RClass *operator_module; + struct RClass *klass; + mrb_value klass_obj; + + klass = mrb_class_get_under(mrb, module, "Operator"); + data->groonga.operator_class = klass; + + klass_obj = mrb_obj_value(klass); +#define DEFINE_OPERATOR(name) \ + mrb_funcall(mrb, klass_obj, "register", 1, \ + mrb_funcall(mrb, klass_obj, "new", 2, \ + mrb_str_new_lit(mrb, #name), \ + mrb_fixnum_value(GRN_OP_ ## name))) - operator_module = mrb_define_module_under(mrb, module, "Operator"); + DEFINE_OPERATOR(PUSH); + DEFINE_OPERATOR(POP); + DEFINE_OPERATOR(NOP); + DEFINE_OPERATOR(CALL); + DEFINE_OPERATOR(INTERN); + DEFINE_OPERATOR(GET_REF); + DEFINE_OPERATOR(GET_VALUE); + DEFINE_OPERATOR(AND); + DEFINE_OPERATOR(AND_NOT); + DEFINE_OPERATOR(OR); + DEFINE_OPERATOR(ASSIGN); + DEFINE_OPERATOR(STAR_ASSIGN); + DEFINE_OPERATOR(SLASH_ASSIGN); + DEFINE_OPERATOR(MOD_ASSIGN); + DEFINE_OPERATOR(PLUS_ASSIGN); + DEFINE_OPERATOR(MINUS_ASSIGN); + DEFINE_OPERATOR(SHIFTL_ASSIGN); + DEFINE_OPERATOR(SHIFTR_ASSIGN); + DEFINE_OPERATOR(SHIFTRR_ASSIGN); + DEFINE_OPERATOR(AND_ASSIGN); + DEFINE_OPERATOR(XOR_ASSIGN); + DEFINE_OPERATOR(OR_ASSIGN); + DEFINE_OPERATOR(JUMP); + DEFINE_OPERATOR(CJUMP); + DEFINE_OPERATOR(COMMA); + DEFINE_OPERATOR(BITWISE_OR); + DEFINE_OPERATOR(BITWISE_XOR); + DEFINE_OPERATOR(BITWISE_AND); + DEFINE_OPERATOR(BITWISE_NOT); + DEFINE_OPERATOR(EQUAL); + DEFINE_OPERATOR(NOT_EQUAL); + DEFINE_OPERATOR(LESS); + DEFINE_OPERATOR(GREATER); + DEFINE_OPERATOR(LESS_EQUAL); + DEFINE_OPERATOR(GREATER_EQUAL); + DEFINE_OPERATOR(IN); + DEFINE_OPERATOR(MATCH); + DEFINE_OPERATOR(NEAR); + DEFINE_OPERATOR(NEAR2); + DEFINE_OPERATOR(SIMILAR); + DEFINE_OPERATOR(TERM_EXTRACT); + DEFINE_OPERATOR(SHIFTL); + DEFINE_OPERATOR(SHIFTR); + DEFINE_OPERATOR(SHIFTRR); + DEFINE_OPERATOR(PLUS); + DEFINE_OPERATOR(MINUS); + DEFINE_OPERATOR(STAR); + DEFINE_OPERATOR(SLASH); + DEFINE_OPERATOR(MOD); + DEFINE_OPERATOR(DELETE); + DEFINE_OPERATOR(INCR); + DEFINE_OPERATOR(DECR); + DEFINE_OPERATOR(INCR_POST); + DEFINE_OPERATOR(DECR_POST); + DEFINE_OPERATOR(NOT); + DEFINE_OPERATOR(ADJUST); + DEFINE_OPERATOR(EXACT); + DEFINE_OPERATOR(LCP); + DEFINE_OPERATOR(PARTIAL); + DEFINE_OPERATOR(UNSPLIT); + DEFINE_OPERATOR(PREFIX); + DEFINE_OPERATOR(SUFFIX); + DEFINE_OPERATOR(GEO_DISTANCE1); + DEFINE_OPERATOR(GEO_DISTANCE2); + DEFINE_OPERATOR(GEO_DISTANCE3); + DEFINE_OPERATOR(GEO_DISTANCE4); + DEFINE_OPERATOR(GEO_WITHINP5); + DEFINE_OPERATOR(GEO_WITHINP6); + DEFINE_OPERATOR(GEO_WITHINP8); + DEFINE_OPERATOR(OBJ_SEARCH); + DEFINE_OPERATOR(EXPR_GET_VAR); + DEFINE_OPERATOR(TABLE_CREATE); + DEFINE_OPERATOR(TABLE_SELECT); + DEFINE_OPERATOR(TABLE_SORT); + DEFINE_OPERATOR(TABLE_GROUP); + DEFINE_OPERATOR(JSON_PUT); + DEFINE_OPERATOR(GET_MEMBER); + DEFINE_OPERATOR(REGEXP); - mrb_define_const(mrb, operator_module, "PUSH", - mrb_fixnum_value(GRN_OP_PUSH)); - mrb_define_const(mrb, operator_module, "POP", - mrb_fixnum_value(GRN_OP_POP)); - mrb_define_const(mrb, operator_module, "NOP", - mrb_fixnum_value(GRN_OP_NOP)); - mrb_define_const(mrb, operator_module, "CALL", - mrb_fixnum_value(GRN_OP_CALL)); - mrb_define_const(mrb, operator_module, "INTERN", - mrb_fixnum_value(GRN_OP_INTERN)); - mrb_define_const(mrb, operator_module, "GET_REF", - mrb_fixnum_value(GRN_OP_GET_REF)); - mrb_define_const(mrb, operator_module, "GET_VALUE", - mrb_fixnum_value(GRN_OP_GET_VALUE)); - mrb_define_const(mrb, operator_module, "AND", - mrb_fixnum_value(GRN_OP_AND)); - mrb_define_const(mrb, operator_module, "AND_NOT", - mrb_fixnum_value(GRN_OP_AND_NOT)); - mrb_define_const(mrb, operator_module, "OR", - mrb_fixnum_value(GRN_OP_OR)); - mrb_define_const(mrb, operator_module, "ASSIGN", - mrb_fixnum_value(GRN_OP_ASSIGN)); - mrb_define_const(mrb, operator_module, "STAR_ASSIGN", - mrb_fixnum_value(GRN_OP_STAR_ASSIGN)); - mrb_define_const(mrb, operator_module, "SLASH_ASSIGN", - mrb_fixnum_value(GRN_OP_SLASH_ASSIGN)); - mrb_define_const(mrb, operator_module, "MOD_ASSIGN", - mrb_fixnum_value(GRN_OP_MOD_ASSIGN)); - mrb_define_const(mrb, operator_module, "PLUS_ASSIGN", - mrb_fixnum_value(GRN_OP_PLUS_ASSIGN)); - mrb_define_const(mrb, operator_module, "MINUS_ASSIGN", - mrb_fixnum_value(GRN_OP_MINUS_ASSIGN)); - mrb_define_const(mrb, operator_module, "SHIFTL_ASSIGN", - mrb_fixnum_value(GRN_OP_SHIFTL_ASSIGN)); - mrb_define_const(mrb, operator_module, "SHIFTR_ASSIGN", - mrb_fixnum_value(GRN_OP_SHIFTR_ASSIGN)); - mrb_define_const(mrb, operator_module, "SHIFTRR_ASSIGN", - mrb_fixnum_value(GRN_OP_SHIFTRR_ASSIGN)); - mrb_define_const(mrb, operator_module, "AND_ASSIGN", - mrb_fixnum_value(GRN_OP_AND_ASSIGN)); - mrb_define_const(mrb, operator_module, "XOR_ASSIGN", - mrb_fixnum_value(GRN_OP_XOR_ASSIGN)); - mrb_define_const(mrb, operator_module, "OR_ASSIGN", - mrb_fixnum_value(GRN_OP_OR_ASSIGN)); - mrb_define_const(mrb, operator_module, "JUMP", - mrb_fixnum_value(GRN_OP_JUMP)); - mrb_define_const(mrb, operator_module, "CJUMP", - mrb_fixnum_value(GRN_OP_CJUMP)); - mrb_define_const(mrb, operator_module, "COMMA", - mrb_fixnum_value(GRN_OP_COMMA)); - mrb_define_const(mrb, operator_module, "BITWISE_OR", - mrb_fixnum_value(GRN_OP_BITWISE_OR)); - mrb_define_const(mrb, operator_module, "BITWISE_XOR", - mrb_fixnum_value(GRN_OP_BITWISE_XOR)); - mrb_define_const(mrb, operator_module, "BITWISE_AND", - mrb_fixnum_value(GRN_OP_BITWISE_AND)); - mrb_define_const(mrb, operator_module, "BITWISE_NOT", - mrb_fixnum_value(GRN_OP_BITWISE_NOT)); - mrb_define_const(mrb, operator_module, "EQUAL", - mrb_fixnum_value(GRN_OP_EQUAL)); - mrb_define_const(mrb, operator_module, "NOT_EQUAL", - mrb_fixnum_value(GRN_OP_NOT_EQUAL)); - mrb_define_const(mrb, operator_module, "LESS", - mrb_fixnum_value(GRN_OP_LESS)); - mrb_define_const(mrb, operator_module, "GREATER", - mrb_fixnum_value(GRN_OP_GREATER)); - mrb_define_const(mrb, operator_module, "LESS_EQUAL", - mrb_fixnum_value(GRN_OP_LESS_EQUAL)); - mrb_define_const(mrb, operator_module, "GREATER_EQUAL", - mrb_fixnum_value(GRN_OP_GREATER_EQUAL)); - mrb_define_const(mrb, operator_module, "IN", - mrb_fixnum_value(GRN_OP_IN)); - mrb_define_const(mrb, operator_module, "MATCH", - mrb_fixnum_value(GRN_OP_MATCH)); - mrb_define_const(mrb, operator_module, "NEAR", - mrb_fixnum_value(GRN_OP_NEAR)); - mrb_define_const(mrb, operator_module, "NEAR2", - mrb_fixnum_value(GRN_OP_NEAR2)); - mrb_define_const(mrb, operator_module, "SIMILAR", - mrb_fixnum_value(GRN_OP_SIMILAR)); - mrb_define_const(mrb, operator_module, "TERM_EXTRACT", - mrb_fixnum_value(GRN_OP_TERM_EXTRACT)); - mrb_define_const(mrb, operator_module, "SHIFTL", - mrb_fixnum_value(GRN_OP_SHIFTL)); - mrb_define_const(mrb, operator_module, "SHIFTR", - mrb_fixnum_value(GRN_OP_SHIFTR)); - mrb_define_const(mrb, operator_module, "SHIFTRR", - mrb_fixnum_value(GRN_OP_SHIFTRR)); - mrb_define_const(mrb, operator_module, "PLUS", - mrb_fixnum_value(GRN_OP_PLUS)); - mrb_define_const(mrb, operator_module, "MINUS", - mrb_fixnum_value(GRN_OP_MINUS)); - mrb_define_const(mrb, operator_module, "STAR", - mrb_fixnum_value(GRN_OP_STAR)); - mrb_define_const(mrb, operator_module, "SLASH", - mrb_fixnum_value(GRN_OP_SLASH)); - mrb_define_const(mrb, operator_module, "MOD", - mrb_fixnum_value(GRN_OP_MOD)); - mrb_define_const(mrb, operator_module, "DELETE", - mrb_fixnum_value(GRN_OP_DELETE)); - mrb_define_const(mrb, operator_module, "INCR", - mrb_fixnum_value(GRN_OP_INCR)); - mrb_define_const(mrb, operator_module, "DECR", - mrb_fixnum_value(GRN_OP_DECR)); - mrb_define_const(mrb, operator_module, "INCR_POST", - mrb_fixnum_value(GRN_OP_INCR_POST)); - mrb_define_const(mrb, operator_module, "DECR_POST", - mrb_fixnum_value(GRN_OP_DECR_POST)); - mrb_define_const(mrb, operator_module, "NOT", - mrb_fixnum_value(GRN_OP_NOT)); - mrb_define_const(mrb, operator_module, "ADJUST", - mrb_fixnum_value(GRN_OP_ADJUST)); - mrb_define_const(mrb, operator_module, "EXACT", - mrb_fixnum_value(GRN_OP_EXACT)); - mrb_define_const(mrb, operator_module, "LCP", - mrb_fixnum_value(GRN_OP_LCP)); - mrb_define_const(mrb, operator_module, "PARTIAL", - mrb_fixnum_value(GRN_OP_PARTIAL)); - mrb_define_const(mrb, operator_module, "UNSPLIT", - mrb_fixnum_value(GRN_OP_UNSPLIT)); - mrb_define_const(mrb, operator_module, "PREFIX", - mrb_fixnum_value(GRN_OP_PREFIX)); - mrb_define_const(mrb, operator_module, "SUFFIX", - mrb_fixnum_value(GRN_OP_SUFFIX)); - mrb_define_const(mrb, operator_module, "GEO_DISTANCE1", - mrb_fixnum_value(GRN_OP_GEO_DISTANCE1)); - mrb_define_const(mrb, operator_module, "GEO_DISTANCE2", - mrb_fixnum_value(GRN_OP_GEO_DISTANCE2)); - mrb_define_const(mrb, operator_module, "GEO_DISTANCE3", - mrb_fixnum_value(GRN_OP_GEO_DISTANCE3)); - mrb_define_const(mrb, operator_module, "GEO_DISTANCE4", - mrb_fixnum_value(GRN_OP_GEO_DISTANCE4)); - mrb_define_const(mrb, operator_module, "GEO_WITHINP5", - mrb_fixnum_value(GRN_OP_GEO_WITHINP5)); - mrb_define_const(mrb, operator_module, "GEO_WITHINP6", - mrb_fixnum_value(GRN_OP_GEO_WITHINP6)); - mrb_define_const(mrb, operator_module, "GEO_WITHINP8", - mrb_fixnum_value(GRN_OP_GEO_WITHINP8)); - mrb_define_const(mrb, operator_module, "OBJ_SEARCH", - mrb_fixnum_value(GRN_OP_OBJ_SEARCH)); - mrb_define_const(mrb, operator_module, "EXPR_GET_VAR", - mrb_fixnum_value(GRN_OP_EXPR_GET_VAR)); - mrb_define_const(mrb, operator_module, "TABLE_CREATE", - mrb_fixnum_value(GRN_OP_TABLE_CREATE)); - mrb_define_const(mrb, operator_module, "TABLE_SELECT", - mrb_fixnum_value(GRN_OP_TABLE_SELECT)); - mrb_define_const(mrb, operator_module, "TABLE_SORT", - mrb_fixnum_value(GRN_OP_TABLE_SORT)); - mrb_define_const(mrb, operator_module, "TABLE_GROUP", - mrb_fixnum_value(GRN_OP_TABLE_GROUP)); - mrb_define_const(mrb, operator_module, "JSON_PUT", - mrb_fixnum_value(GRN_OP_JSON_PUT)); - mrb_define_const(mrb, operator_module, "GET_MEMBER", - mrb_fixnum_value(GRN_OP_GET_MEMBER)); +#undef DEFINE_OPERATOR } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h index 683b9dacbd9..b76c4983446 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2014 Brazil + 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 @@ -26,6 +26,8 @@ extern "C" { #endif void grn_mrb_operator_init(grn_ctx *ctx); +mrb_value grn_mrb_value_from_operator(mrb_state *mrb, grn_operator op); +grn_operator grn_mrb_value_to_operator(mrb_state *mrb, mrb_value mrb_op); #ifdef __cplusplus } diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.c new file mode 100644 index 00000000000..ff3a1c0e731 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.c @@ -0,0 +1,39 @@ +/* -*- 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" +#include "../grn_db.h" + +#ifdef GRN_WITH_MRUBY +#include <mruby.h> +#include <mruby/hash.h> + +#include "mrb_options.h" + +mrb_value +grn_mrb_options_get_static(mrb_state *mrb, + mrb_value mrb_options, + const char *key, + size_t key_size) +{ + mrb_sym mrb_key; + + mrb_key = mrb_intern_static(mrb, key, key_size); + return mrb_hash_get(mrb, mrb_options, mrb_symbol_value(mrb_key)); +} +#endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h new file mode 100644 index 00000000000..1aa547d3be9 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h @@ -0,0 +1,40 @@ +/* -*- 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_OPTIONS_H +#define GRN_MRB_OPTIONS_H + +#include "../grn_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +mrb_value grn_mrb_options_get_static(mrb_state *mrb, + mrb_value mrb_options, + const char *key, + size_t key_size); +#define grn_mrb_options_get_lit(mrb, mrb_options, literal) \ + grn_mrb_options_get_static(mrb, mrb_options, \ + (literal), mrb_strlen_lit(literal)) + +#ifdef __cplusplus +} +#endif + +#endif /* GRN_MRB_OPTIONS_H */ diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c index 2b86fdb482b..651a77e4549 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c @@ -29,6 +29,41 @@ #include "mrb_ctx.h" #include "mrb_table.h" #include "mrb_converter.h" +#include "mrb_options.h" + +static mrb_value +mrb_grn_table_array_reference(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *table; + grn_id key_domain_id; + mrb_value mrb_key; + grn_id record_id; + grn_mrb_value_to_raw_data_buffer buffer; + void *key; + unsigned int key_size; + + mrb_get_args(mrb, "o", &mrb_key); + + table = DATA_PTR(self); + if (table->header.type == GRN_DB) { + key_domain_id = GRN_DB_SHORT_TEXT; + } else { + 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); + record_id = grn_table_get(ctx, table, key, key_size); + grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer); + + if (record_id == GRN_ID_NIL) { + return mrb_nil_value(); + } else { + return mrb_fixnum_value(record_id); + } +} static mrb_value mrb_grn_table_is_locked(mrb_state *mrb, mrb_value self) @@ -86,14 +121,12 @@ mrb_grn_table_select(mrb_state *mrb, mrb_value self) mrb_value mrb_result; mrb_value mrb_operator; - mrb_result = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "result"))); + mrb_result = grn_mrb_options_get_lit(mrb, mrb_options, "result"); if (!mrb_nil_p(mrb_result)) { result = DATA_PTR(mrb_result); } - mrb_operator = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "operator"))); + mrb_operator = grn_mrb_options_get_lit(mrb, mrb_options, "operator"); if (!mrb_nil_p(mrb_operator)) { operator = mrb_fixnum(mrb_operator); } @@ -133,8 +166,7 @@ mrb_grn_table_sort(mrb_state *mrb, mrb_value self) mrb_value mrb_sort_order; mrb_sort_options = RARRAY_PTR(mrb_keys)[i]; - mrb_sort_key = mrb_hash_get(mrb, mrb_sort_options, - mrb_symbol_value(mrb_intern_lit(mrb, "key"))); + 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, @@ -158,9 +190,7 @@ mrb_grn_table_sort(mrb_state *mrb, mrb_value self) } keys[i].flags = 0; - mrb_sort_order = - mrb_hash_get(mrb, mrb_sort_options, - mrb_symbol_value(mrb_intern_lit(mrb, "order"))); + 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; @@ -173,14 +203,12 @@ mrb_grn_table_sort(mrb_state *mrb, mrb_value self) mrb_value mrb_offset; mrb_value mrb_limit; - mrb_offset = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "offset"))); + mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset"); if (!mrb_nil_p(mrb_offset)) { offset = mrb_fixnum(mrb_offset); } - mrb_limit = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "limit"))); + mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit"); if (!mrb_nil_p(mrb_limit)) { limit = mrb_fixnum(mrb_limit); } @@ -210,6 +238,9 @@ grn_mrb_table_init(grn_ctx *ctx) klass = mrb_define_class_under(mrb, module, "Table", object_class); MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); + mrb_define_method(mrb, klass, "[]", + mrb_grn_table_array_reference, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "locked?", mrb_grn_table_is_locked, MRB_ARGS_NONE()); diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c index 660596070d3..76d4429d24f 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c @@ -26,62 +26,17 @@ #include <mruby/hash.h> #include "mrb_ctx.h" +#include "mrb_bulk.h" #include "mrb_table_cursor.h" +#include "mrb_converter.h" +#include "mrb_options.h" + static struct mrb_data_type mrb_grn_table_cursor_type = { "Groonga::TableCursor", NULL }; -typedef union { - int64_t time_value; -} border_value_buffer; - -static void -mrb_value_to_border_value(mrb_state *mrb, - const char *type, - mrb_value mrb_border_value, - border_value_buffer *buffer, - void **border_value, - unsigned int *border_value_size) -{ - grn_ctx *ctx = (grn_ctx *)mrb->ud; - - if (mrb_nil_p(mrb_border_value)) { - return; - } - - switch (mrb_type(mrb_border_value)) { - case MRB_TT_STRING : - *border_value = RSTRING_PTR(mrb_border_value); - *border_value_size = RSTRING_LEN(mrb_border_value); - break; - default : - { - struct RClass *klass; - - klass = mrb_class(mrb, mrb_border_value); - if (klass == ctx->impl->mrb.builtin.time_class) { - mrb_value mrb_sec; - mrb_value mrb_usec; - - mrb_sec = mrb_funcall(mrb, mrb_border_value, "to_i", 0); - mrb_usec = mrb_funcall(mrb, mrb_border_value, "usec", 0); - buffer->time_value = GRN_TIME_PACK(mrb_fixnum(mrb_sec), - mrb_fixnum(mrb_usec)); - *border_value = &(buffer->time_value); - *border_value_size = sizeof(buffer->time_value); - } else { - mrb_raisef(mrb, E_NOTIMP_ERROR, - "%s: only String and Time is supported for now: %S", - type, - mrb_border_value); - } - } - break; - } -} - static mrb_value mrb_grn_table_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass) { @@ -92,10 +47,10 @@ mrb_grn_table_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass) grn_obj *table; void *min = NULL; unsigned int min_size = 0; - border_value_buffer min_buffer; + grn_mrb_value_to_raw_data_buffer min_buffer; void *max = NULL; unsigned int max_size = 0; - border_value_buffer max_buffer; + grn_mrb_value_to_raw_data_buffer max_buffer; int offset = 0; int limit = -1; int flags = 0; @@ -103,21 +58,29 @@ mrb_grn_table_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "o|H", &mrb_table, &mrb_options); table = DATA_PTR(mrb_table); + grn_mrb_value_to_raw_data_buffer_init(mrb, &min_buffer); + grn_mrb_value_to_raw_data_buffer_init(mrb, &max_buffer); if (!mrb_nil_p(mrb_options)) { + grn_id key_domain_id; mrb_value mrb_min; mrb_value mrb_max; mrb_value mrb_flags; - mrb_min = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "min"))); - mrb_value_to_border_value(mrb, "min", mrb_min, &min_buffer, &min, &min_size); + if (table->header.type == GRN_DB) { + key_domain_id = GRN_DB_SHORT_TEXT; + } else { + key_domain_id = table->header.domain; + } + + mrb_min = grn_mrb_options_get_lit(mrb, mrb_options, "min"); + grn_mrb_value_to_raw_data(mrb, "min", mrb_min, + key_domain_id, &min_buffer, &min, &min_size); - mrb_max = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "max"))); - mrb_value_to_border_value(mrb, "max", mrb_max, &max_buffer, &max, &max_size); + mrb_max = grn_mrb_options_get_lit(mrb, mrb_options, "max"); + grn_mrb_value_to_raw_data(mrb, "max", mrb_max, + key_domain_id, &max_buffer, &max, &max_size); - mrb_flags = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "flags"))); + mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags"); if (!mrb_nil_p(mrb_flags)) { flags = mrb_fixnum(mrb_flags); } @@ -126,6 +89,8 @@ mrb_grn_table_cursor_singleton_open_raw(mrb_state *mrb, mrb_value klass) min, min_size, max, max_size, offset, limit, flags); + grn_mrb_value_to_raw_data_buffer_fin(mrb, &min_buffer); + grn_mrb_value_to_raw_data_buffer_fin(mrb, &max_buffer); grn_mrb_ctx_check(mrb); return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, table_cursor)); diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c index e14073e5fe2..e35a066e560 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c @@ -28,6 +28,7 @@ #include "../grn_output.h" #include "mrb_ctx.h" #include "mrb_writer.h" +#include "mrb_options.h" static mrb_value writer_write(mrb_state *mrb, mrb_value self) @@ -164,14 +165,12 @@ writer_write_table_records(mrb_state *mrb, mrb_value self) mrb_value mrb_offset; mrb_value mrb_limit; - mrb_offset = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "offset"))); + mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset"); if (!mrb_nil_p(mrb_offset)) { offset = mrb_fixnum(mrb_offset); } - mrb_limit = mrb_hash_get(mrb, mrb_options, - mrb_symbol_value(mrb_intern_lit(mrb, "limit"))); + mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit"); if (!mrb_nil_p(mrb_limit)) { limit = mrb_fixnum(mrb_limit); } @@ -195,6 +194,19 @@ writer_write_table_records(mrb_state *mrb, mrb_value self) return mrb_nil_value(); } +static mrb_value +writer_set_content_type(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_content_type content_type; + + mrb_get_args(mrb, "i", &content_type); + + grn_ctx_set_output_type(ctx, content_type); + + return mrb_nil_value(); +} + void grn_mrb_writer_init(grn_ctx *ctx) { @@ -219,5 +231,8 @@ grn_mrb_writer_init(grn_ctx *ctx) writer_write_table_columns, MRB_ARGS_REQ(2)); mrb_define_method(mrb, klass, "write_table_records", writer_write_table_records, MRB_ARGS_ARG(2, 1)); + + mrb_define_method(mrb, klass, "content_type=", + writer_set_content_type, MRB_ARGS_REQ(1)); } #endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am index 631923e2e06..9b6acf8bbda 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am @@ -1,3 +1,9 @@ +SUBDIRS = \ + command_line \ + context \ + initialize \ + logger + include sources.am EXTRA_DIST = \ @@ -5,5 +11,5 @@ EXTRA_DIST = \ $(RUBY_SCRIPT_FILES) if WITH_MRUBY -nobase_ruby_scripts_DATA = $(RUBY_SCRIPT_FILES) +ruby_scripts_DATA = $(RUBY_SCRIPT_FILES) endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb index 68ea9e4b6f2..34f95e968f5 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb @@ -5,16 +5,24 @@ module Groonga match_data = /:(\d+):?/.match(entry) file = match_data.pre_match line = match_data[1].to_i - method = match_data.post_match.gsub(/\Ain /, "") - new(file, line, method) + detail_match_data = /\A(in )?(\S+)\s*/.match(match_data.post_match) + if detail_match_data[1] + method = detail_match_data[2] + message = detail_match_data.post_match + else + method = "" + message = match_data.post_match + end + new(file, line, method, message) end end - attr_reader :file, :line, :method - def initialize(file, line, method) + attr_reader :file, :line, :method, :message + def initialize(file, line, method, message) @file = file @line = line @method = method + @message = message end end end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am new file mode 100644 index 00000000000..8d580810674 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am @@ -0,0 +1,9 @@ +include sources.am + +EXTRA_DIST = \ + $(RUBY_SCRIPT_FILES) + +if WITH_MRUBY +ruby_scripts_command_linedir = $(ruby_scriptsdir)/command_line +ruby_scripts_command_line_DATA = $(RUBY_SCRIPT_FILES) +endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am new file mode 100644 index 00000000000..759948eecd6 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am @@ -0,0 +1,2 @@ +RUBY_SCRIPT_FILES = \ + grndb.rb diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am new file mode 100644 index 00000000000..8d862082cce --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am @@ -0,0 +1,9 @@ +include sources.am + +EXTRA_DIST = \ + $(RUBY_SCRIPT_FILES) + +if WITH_MRUBY +ruby_scripts_contextdir = $(ruby_scriptsdir)/context +ruby_scripts_context_DATA = $(RUBY_SCRIPT_FILES) +endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am new file mode 100644 index 00000000000..1f0d1624ce5 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am @@ -0,0 +1,3 @@ +RUBY_SCRIPT_FILES = \ + error_level.rb \ + rc.rb diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb index 29290e207f2..7b1199b7795 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb @@ -1,3 +1,8 @@ +require "scan_info" +require "scan_info_builder" + +require "expression_size_estimator" + module Groonga class Expression def build_scan_info(op, size) @@ -9,5 +14,23 @@ module Groonga nil end end + + def estimate_size(table) + begin + estimator = ExpressionSizeEstimator.new(self, table) + estimator.estimate + rescue GroongaError => groonga_error + context.set_groonga_error(groonga_error) + table.size + rescue => error + context.record_error(:unknown_error, error) + table.size + end + end + + private + def context + @context ||= Context.instance + end end end 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 new file mode 100644 index 00000000000..73b44cae3dd --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb @@ -0,0 +1,155 @@ +module Groonga + class ExpressionSizeEstimator + def initialize(expression, table) + @expression = expression + @table = table + @table_size = @table.size + end + + def estimate + builder = ScanInfoBuilder.new(@expression, Operator::OR, 0) + data_list = builder.build + return @table_size if data_list.nil? + + or_data_list = group_data_list(data_list) + or_sizes = or_data_list.collect do |and_data_list| + and_sizes = and_data_list.collect do |data| + size = estimate_data(data) + if data.logical_op == Operator::AND_NOT + size = @table_size - size + size = 0 if size < 0 + end + size + end + and_sizes.min + end + or_sizes.max + end + + private + def group_data_list(data_list) + or_data_list = [[]] + data_list.each do |data| + next if data.op == Operator::NOP + + and_data_list = or_data_list.last + if and_data_list.empty? + and_data_list << data + else + case data.logical_op + when Operator::AND, Operator::AND_NOT + and_data_list << data + else + and_data_list = [data] + or_data_list << and_data_list + end + end + end + or_data_list + end + + def estimate_data(data) + search_index = data.search_indexes.first + return @table_size if search_index.nil? + + index_column = resolve_index_column(search_index.index_column, + data.op) + return @table_size if index_column.nil? + + size = nil + case data.op + when Operator::MATCH + size = estimate_match(data, index_column) + when Operator::REGEXP + size = estimate_regexp(data, index_column) + when Operator::EQUAL + size = estimate_equal(data, index_column) + when Operator::LESS, + Operator::LESS_EQUAL, + Operator::GREATER, + Operator::GREATER_EQUAL + size = estimate_range(data, index_column) + when Operator::CALL + procedure = data.args.first + if procedure.is_a?(Procedure) and procedure.name == "between" + size = estimate_between(data, index_column) + end + end + size || @table_size + end + + def resolve_index_column(index_column, operator) + while index_column.is_a?(Accessor) + index_info = index_column.find_index(operator) + return nil if index_info.nil? + index_column = index_info.index + end + + index_column + end + + def estimate_match(data, index_column) + index_column.estimate_size(:query => data.query.value) + end + + def estimate_regexp(data, index_column) + index_column.estimate_size(:query => data.query.value, + :mode => data.op) + end + + def estimate_equal(data, index_column) + lexicon = index_column.lexicon + term_id = lexicon[data.query] + return 0 if term_id.nil? + + index_column.estimate_size(:term_id => term_id) + end + + def estimate_range(data, index_column) + lexicon = index_column.lexicon + value = data.query.value + options = {} + case data.op + when Operator::LESS + options[:max] = value + options[:flags] = TableCursorFlags::LT + when Operator::LESS_EQUAL + options[:max] = value + options[:flags] = TableCursorFlags::LE + when Operator::GREATER + options[:min] = value + options[:flags] = TableCursorFlags::GT + when Operator::GREATER_EQUAL + options[:min] = value + options[:flags] = TableCursorFlags::GE + end + TableCursor.open(lexicon, options) do |cursor| + index_column.estimate_size(:lexicon_cursor => cursor) + end + end + + def estimate_between(data, index_column) + lexicon = index_column.lexicon + _, _, min, min_border, max, max_border = data.args + options = { + :min => min, + :max => max, + :flags => 0, + } + if min_border == "include" + options[:flags] |= TableCursorFlags::LT + else + options[:flags] |= TableCursorFlags::LE + end + if max_border == "include" + options[:flags] |= TableCursorFlags::GT + else + options[:flags] |= TableCursorFlags::GE + end + + TableCursor.open(lexicon, options) do |cursor| + index_column.estimate_size(:lexicon_cursor => cursor) + end + end + end +end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb new file mode 100644 index 00000000000..25ebc149367 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb @@ -0,0 +1,39 @@ +module Groonga + class IndexColumn + private :estimate_size_for_term_id + private :estimate_size_for_query + private :estimate_size_for_lexicon_cursor + + # Estimate the number of matched records for term ID or query. + # + # @overload estimate_size(:term_id => term_id) + # @return [Integer] the number of matched records for the term ID. + # + # @overload estimate_size(:query => query) + # @return [Integer] the number of matched records for the query. + # + # @overload estimate_size(:lexicon_cursor => lexicon_cursor) + # @return [Integer] the number of matched records for the lexicon cursor. + # + def estimate_size(parameters) + term_id = parameters[:term_id] + if term_id + return estimate_size_for_term_id(term_id) + end + + query = parameters[:query] + if query + return estimate_size_for_query(query, parameters) + end + + lexicon_cursor = parameters[:lexicon_cursor] + if lexicon_cursor + return estimate_size_for_lexicon_cursor(lexicon_cursor) + end + + message = + "must specify :term_id, :query, :lexicon_cursor: #{parameters.inspect}" + raise InvalidArgument, message + end + end +end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am new file mode 100644 index 00000000000..e7531fdc029 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am @@ -0,0 +1,9 @@ +include sources.am + +EXTRA_DIST = \ + $(RUBY_SCRIPT_FILES) + +if WITH_MRUBY +ruby_scripts_initializedir = $(ruby_scriptsdir)/initialize +ruby_scripts_initialize_DATA = $(RUBY_SCRIPT_FILES) +endif 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 7110437c200..ea26a031e0a 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb @@ -4,11 +4,15 @@ require "context" require "writer" +require "object" require "database" +require "index_column" require "command" require "table_cursor" require "index_cursor" +require "expression" + require "plugin_loader" require "eval_context" diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb index c9a74a80dd9..99300d11a92 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb @@ -1 +1,3 @@ require "backtrace_entry" + +require "operator" diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am new file mode 100644 index 00000000000..3c26e19b2ae --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am @@ -0,0 +1,3 @@ +RUBY_SCRIPT_FILES = \ + pre.rb \ + post.rb diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb index 33021355824..cb747a418d6 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb @@ -9,12 +9,13 @@ module Groonga message = "#{error.class}: #{error.message}" end backtrace = error.backtrace - first_raw_entry = backtrace.first - if first_raw_entry - first_entry = BacktraceEntry.parse(first_raw_entry) - file = first_entry.file - line = first_entry.line - method = first_entry.method + last_raw_entry = backtrace.last + if last_raw_entry + last_entry = BacktraceEntry.parse(last_raw_entry) + file = last_entry.file + line = last_entry.line + method = last_entry.method + # message = "#{file}:#{line}:#{method}: #{message}" else file = "" line = 0 @@ -22,8 +23,11 @@ module Groonga end log(log_level, file, line, method, message) - backtrace.each do |raw_entry| + backtrace.reverse_each.with_index do |raw_entry, i| + next if i == 0 entry = BacktraceEntry.parse(raw_entry) + message = entry.message + message = raw_entry if message.empty? log(log_level, entry.file, entry.line, entry.method, raw_entry) end end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am new file mode 100644 index 00000000000..448e72ca5bc --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am @@ -0,0 +1,9 @@ +include sources.am + +EXTRA_DIST = \ + $(RUBY_SCRIPT_FILES) + +if WITH_MRUBY +ruby_scripts_loggerdir = $(ruby_scriptsdir)/logger +ruby_scripts_logger_DATA = $(RUBY_SCRIPT_FILES) +endif diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am new file mode 100644 index 00000000000..7231ee4eecb --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am @@ -0,0 +1,2 @@ +RUBY_SCRIPT_FILES = \ + level.rb diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb index f1cc1a6aa79..d98b5069e7f 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb @@ -1,7 +1,11 @@ module Groonga class Object - def inspect - super[0..-2] + ": #{grn_inspect}>" + def domain + Context.instance[domain_id] + end + + def range + Context.instance[range_id] end end end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb new file mode 100644 index 00000000000..349695e1a53 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb @@ -0,0 +1,22 @@ +module Groonga + class Operator + @values = {} + class << self + def register(operator) + const_set(operator.name, operator) + @values[operator.value] = operator + end + + def find(value) + @values[value] + end + end + + attr_reader :name + attr_reader :value + def initialize(name, value) + @name = name + @value = value + end + end +end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb index 64262f8f975..a98cf792a9c 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb @@ -19,14 +19,16 @@ module Groonga if data.similarity_threshold self.similarity_threshold = data.similarity_threshold end - if data.scorer - self.scorer = data.scorer - end data.args.each do |arg| push_arg(arg) end - data.indexes.each do |index, section_id, weight| - put_index(index, section_id, weight) + data.search_indexes.each do |search_index| + put_index(search_index.index_column, + search_index.section_id, + search_index.weight, + search_index.scorer, + search_index.scorer_args_expr, + search_index.scorer_args_expr_offset || 0) end end end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb index b002eaa14c0..dc003f88948 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb @@ -1,11 +1,6 @@ -module Groonga - # TODO: Move me - class ExpressionCode - module Flags - RELATIONAL_EXPRESSION = 0x01 - end - end +require "scan_info_data" +module Groonga class ScanInfoBuilder module Status START = 0 @@ -39,6 +34,7 @@ module Groonga Operator::GEO_WITHINP6, Operator::GEO_WITHINP8, Operator::TERM_EXTRACT, + Operator::REGEXP, ] ARITHMETIC_OPERATORS = [ @@ -294,10 +290,10 @@ module Groonga return false if data.args[0] != next_data.args[0] - data_indexes = data.indexes - return false if data_indexes.empty? + data_search_indexes = data.search_indexes + return false if data_search_indexes.empty? - data_indexes == next_data.indexes + data_search_indexes == next_data.search_indexes end def lower_condition?(operator) @@ -325,7 +321,7 @@ module Groonga between_data.op = Operator::CALL between_data.logical_op = data.logical_op between_data.args = create_between_data_args(data, next_data) - between_data.indexes = data.indexes + between_data.search_indexes = data.search_indexes between_data end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb index b0ebfea3cee..4a6e58a951a 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb @@ -1,3 +1,5 @@ +require "scan_info_search_index" + module Groonga class ScanInfoData attr_accessor :start @@ -6,23 +8,21 @@ module Groonga attr_accessor :logical_op attr_accessor :query attr_accessor :args - attr_accessor :indexes + attr_accessor :search_indexes attr_accessor :flags attr_accessor :max_interval attr_accessor :similarity_threshold - attr_accessor :scorer def initialize(start) @start = start @end = 0 - @op = 0 + @op = Operator::NOP @logical_op = Operator::OR @query = nil @args = [] - @indexes = [] + @search_indexes = [] @flags = ScanInfo::Flags::PUSH @max_interval = nil @similarity_threshold = nil - @scorer = nil end def match_resolve_index @@ -102,6 +102,41 @@ module Groonga self.query = arg end end + if @op == Operator::REGEXP and not index_searchable_regexp?(@query) + @search_indexes.clear + end + end + + def index_searchable_regexp?(pattern) + return false if pattern.nil? + + previous_char = nil + pattern.value.each_char do |char| + if previous_char == "\\" + case char + when "Z" + return false + when "b", "B" + return false + when "d", "D", "h", "H", "p", "s", "S", "w", "W" + return false + when "X" + return false + when "k", "g", "1", "2", "3", "4", "5", "6", "7", "8", "9" + return false + when "\\" + previous_char = nil + next + end + else + case char + when ".", "[", "]", "|", "?", "+", "*", "{", "}", "^", "$", "(", ")" + return false + end + end + previous_char = char + end + true end def match_resolve_index_expression(expression) @@ -109,19 +144,82 @@ module Groonga n_codes = codes.size i = 0 while i < n_codes - i = match_resolve_index_expression_codes(codes, i, n_codes) + i = match_resolve_index_expression_codes(expression, codes, i, n_codes) + end + end + + def match_resolve_index_expression_codes(expression, codes, i, n_codes) + code = codes[i] + value = code.value + return i + 1 if value.nil? + + case value + when Accessor, Column + index_info, offset = + match_resolve_index_expression_find_index(expression, + codes, i, n_codes) + i += offset - 1 + if index_info + if value.is_a?(Accessor) + self.flags |= ScanInfo::Flags::ACCESSOR + end + weight, offset = codes[i].weight + i += offset + put_search_index(index_info.index, index_info.section_id, weight) + end + when Procedure + unless value.scorer? + message = "procedure must be scorer: #{scorer.name}>" + raise ErrorMessage, message + end + scorer = value + i += 1 + index_info, offset = + match_resolve_index_expression_find_index(expression, + codes, i, n_codes) + i += offset + if index_info + scorer_args_expr_offset = 0 + if codes[i].op != Operator::CALL + scorer_args_expr_offset = i + end + while i < n_codes and codes[i].op != Operator::CALL + i += 1 + end + weight, offset = codes[i].weight + i += offset + search_index = ScanInfoSearchIndex.new(index_info.index, + index_info.section_id, + weight, + scorer, + expression, + scorer_args_expr_offset) + @search_indexes << search_index + end + when Table + raise ErrorMessage, "invalid match target: <#{value.name}>" end + i + 1 end - def match_resolve_index_expression_codes(codes, i, n_codes) + def match_resolve_index_expression_find_index(expression, codes, i, n_codes) code = codes[i] value = code.value + index_info = nil + offset = 1 case value when Accessor - match_resolve_index_expression_accessor(code) + accessor = value + index_info = accessor.find_index(@op) + if index_info + if accessor.have_next? and index_info.index != accessor.object + index_info = IndexInfo.new(accessor, index_info.section_id) + end + end when FixedSizeColumn, VariableSizeColumn - match_resolve_index_expression_data_column(code) + index_info = value.find_index(@op) when IndexColumn + index = value section_id = 0 rest_n_codes = n_codes - i if rest_n_codes >= 2 and @@ -130,26 +228,12 @@ module Groonga codes[i + 1].value.domain == ID::INT32) and codes[i + 2].op == Operator::GET_MEMBER section_id = codes[i + 1].value.value + 1 - code = codes[i + 2] - i += 2 + offset += 2 end - put_index(value, section_id, code.weight) - when Procedure - unless value.scorer? - message = "procedure must be scorer: #{scorer.name}>" - raise ErrorMessage, message - end - @scorer = value - rest_n_codes = n_codes - i - if rest_n_codes == 0 - message = "match target is required as an argument: <#{scorer.name}>" - raise ErrorMessage, message - end - i = match_resolve_index_expression_codes(codes, i + 1, n_codes) - when Table - raise ErrorMessage, "invalid match target: <#{value.name}>" + index_info = IndexInfo.new(index, section_id) end - i + 1 + + [index_info, offset] end def match_resolve_index_expression_accessor(expr_code) @@ -157,10 +241,13 @@ module Groonga self.flags |= ScanInfo::Flags::ACCESSOR index_info = accessor.find_index(op) return if index_info.nil? + + section_id = index_info.section_id + weight = expr_code.weight if accessor.next - put_index(accessor, index_info.section_id, expr_code.weight) + put_search_index(accessor, section_id, weight) else - put_index(index_info.index, index_info.section_id, expr_code.weight) + put_search_index(index_info.index, section_id, weight) end end @@ -168,13 +255,13 @@ module Groonga column = expr_code.value index_info = column.find_index(op) return if index_info.nil? - put_index(index_info.index, index_info.section_id, expr_code.weight) + put_search_index(index_info.index, index_info.section_id, expr_code.weight) end def match_resolve_index_db_obj(db_obj) index_info = db_obj.find_index(op) return if index_info.nil? - put_index(index_info.index, index_info.section_id, 1) + put_search_index(index_info.index, index_info.section_id, 1) end def match_resolve_index_accessor(accessor) @@ -182,9 +269,9 @@ module Groonga index_info = accessor.find_index(op) return if index_info.nil? if accessor.next - put_index(accessor, index_info.section_id, 1) + put_search_index(accessor, index_info.section_id, 1) else - put_index(index_info.index, index_info.section_id, 1) + put_search_index(index_info.index, index_info.section_id, 1) end end @@ -202,18 +289,19 @@ module Groonga def call_relational_resolve_index_db_obj(db_obj) index_info = db_obj.find_index(op) return if index_info.nil? - put_index(index_info.index, index_info.section_id, 1) + put_search_index(index_info.index, index_info.section_id, 1) end def call_relational_resolve_index_accessor(accessor) self.flags |= ScanInfo::Flags::ACCESSOR index_info = accessor.find_index(op) return if index_info.nil? - put_index(index_info.index, index_info.section_id, 1) + put_search_index(index_info.index, index_info.section_id, 1) end - def put_index(index, section_id, weight) - @indexes << [index, section_id, weight] + def put_search_index(index, section_id, weight) + search_index = ScanInfoSearchIndex.new(index, section_id, weight) + @search_indexes << search_index end end end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb new file mode 100644 index 00000000000..a2818160310 --- /dev/null +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb @@ -0,0 +1,9 @@ +module Groonga + class ScanInfoSearchIndex < Struct.new(:index_column, + :section_id, + :weight, + :scorer, + :scorer_args_expr, + :scorer_args_expr_offset) + end +end diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am index fa90c59ce23..5ddcba18d4c 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am +++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am @@ -1,24 +1,23 @@ RUBY_SCRIPT_FILES = \ backtrace_entry.rb \ command.rb \ - command_line/grndb.rb \ context.rb \ - context/error_level.rb \ - context/rc.rb \ database.rb \ error.rb \ eval_context.rb \ expression.rb \ + expression_size_estimator.rb \ + index_column.rb \ index_cursor.rb \ index_info.rb \ - initialize/pre.rb \ - initialize/post.rb \ logger.rb \ - logger/level.rb \ + object.rb \ + operator.rb \ plugin_loader.rb \ require.rb \ scan_info.rb \ scan_info_builder.rb \ scan_info_data.rb \ + scan_info_search_index.rb \ table_cursor.rb \ writer.rb diff --git a/storage/mroonga/vendor/groonga/lib/mrb/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/sources.am index c4f02fca639..5cda570bc37 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/sources.am +++ b/storage/mroonga/vendor/groonga/lib/mrb/sources.am @@ -11,6 +11,8 @@ libgrnmrb_la_SOURCES = \ mrb_command.h \ mrb_command_input.c \ mrb_command_input.h \ + mrb_content_type.c \ + mrb_content_type.h \ mrb_converter.c \ mrb_converter.h \ mrb_ctx.c \ @@ -37,8 +39,12 @@ libgrnmrb_la_SOURCES = \ mrb_logger.h \ mrb_object.c \ mrb_object.h \ + mrb_object_flags.c \ + mrb_object_flags.h \ mrb_operator.c \ mrb_operator.h \ + mrb_options.c \ + mrb_options.h \ mrb_patricia_trie.c \ mrb_patricia_trie.h \ mrb_procedure.c \ diff --git a/storage/mroonga/vendor/groonga/lib/normalizer.c b/storage/mroonga/vendor/groonga/lib/normalizer.c index 27d34a4850b..5999bf64317 100644 --- a/storage/mroonga/vendor/groonga/lib/normalizer.c +++ b/storage/mroonga/vendor/groonga/lib/normalizer.c @@ -728,7 +728,7 @@ utf8_normalize(grn_ctx *ctx, grn_string *nstr) nstr->ctypes = ctypes; } } - memcpy(d, p, lp); + grn_memcpy(d, p, lp); d_ = d; d += lp; length++; diff --git a/storage/mroonga/vendor/groonga/lib/operator.c b/storage/mroonga/vendor/groonga/lib/operator.c index 27aa5df5819..14a870cd885 100644 --- a/storage/mroonga/vendor/groonga/lib/operator.c +++ b/storage/mroonga/vendor/groonga/lib/operator.c @@ -19,9 +19,18 @@ #include "grn.h" #include "grn_db.h" #include "grn_str.h" +#include "grn_normalizer.h" #include <string.h> +#ifdef GRN_WITH_ONIGMO +# define GRN_SUPPORT_REGEXP +#endif + +#ifdef GRN_SUPPORT_REGEXP +# include <oniguruma.h> +#endif + static const char *operator_names[] = { "push", "pop", @@ -99,13 +108,16 @@ static const char *operator_names[] = { "table_sort", "table_group", "json_put", - "get_member" + "get_member", + "regexp" }; +#define GRN_OP_LAST GRN_OP_REGEXP + const char * grn_operator_to_string(grn_operator op) { - if (GRN_OP_PUSH <= op && op <= GRN_OP_GET_MEMBER) { + if (op <= GRN_OP_LAST) { return operator_names[op]; } else { return "unknown"; @@ -310,12 +322,16 @@ grn_operator_to_string(grn_operator op) if (!grn_obj_cast(ctx, x, &dest, GRN_FALSE)) {\ r = (GRN_BULK_VSIZE(&dest) == GRN_BULK_VSIZE(y) &&\ !memcmp(GRN_BULK_HEAD(&dest), GRN_BULK_HEAD(y), GRN_BULK_VSIZE(y))); \ + } else {\ + r = GRN_FALSE;\ }\ } else {\ GRN_OBJ_INIT(&dest, GRN_BULK, 0, x->header.domain);\ if (!grn_obj_cast(ctx, y, &dest, GRN_FALSE)) {\ r = (GRN_BULK_VSIZE(&dest) == GRN_BULK_VSIZE(x) &&\ !memcmp(GRN_BULK_HEAD(&dest), GRN_BULK_HEAD(x), GRN_BULK_VSIZE(x))); \ + } else {\ + r = GRN_FALSE;\ }\ }\ GRN_OBJ_FIN(ctx, &dest);\ @@ -594,3 +610,319 @@ grn_operator_exec_greater_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y) DO_COMPARE(x, y, r, >=); GRN_API_RETURN(r); } + +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) +{ + /* TODO: Use more fast algorithm such as Boyer-Moore algorithm that + * is used in snip.c. */ + const char *text_end = text + text_len; + unsigned int sub_text_current = 0; + + for (; text < text_end; text++) { + if (text[0] == sub_text[sub_text_current]) { + sub_text_current++; + if (sub_text_current == sub_text_len) { + return GRN_TRUE; + } + } else { + sub_text_current = 0; + } + } + + return GRN_FALSE; +} + +static grn_bool +string_have_prefix(grn_ctx *ctx, + const char *target, unsigned int target_len, + const char *prefix, unsigned int prefix_len) +{ + return (target_len >= prefix_len && + strncmp(target, prefix, prefix_len) == 0); +} + +static grn_bool +string_match_regexp(grn_ctx *ctx, + const char *target, unsigned int target_len, + const char *pattern, unsigned int pattern_len) +{ +#ifdef GRN_SUPPORT_REGEXP + OnigRegex regex; + OnigEncoding onig_encoding; + int onig_result; + OnigErrorInfo onig_error_info; + + if (ctx->encoding == GRN_ENC_NONE) { + return GRN_FALSE; + } + + switch (ctx->encoding) { + case GRN_ENC_EUC_JP : + onig_encoding = ONIG_ENCODING_EUC_JP; + break; + case GRN_ENC_UTF8 : + onig_encoding = ONIG_ENCODING_UTF8; + break; + case GRN_ENC_SJIS : + onig_encoding = ONIG_ENCODING_CP932; + break; + case GRN_ENC_LATIN1 : + onig_encoding = ONIG_ENCODING_ISO_8859_1; + break; + case GRN_ENC_KOI8R : + onig_encoding = ONIG_ENCODING_KOI8_R; + break; + default : + return GRN_FALSE; + } + + onig_result = onig_new(®ex, + pattern, + pattern + pattern_len, + ONIG_OPTION_ASCII_RANGE, + onig_encoding, + ONIG_SYNTAX_RUBY, + &onig_error_info); + if (onig_result != ONIG_NORMAL) { + char message[ONIG_MAX_ERROR_MESSAGE_LEN]; + onig_error_code_to_str(message, onig_result, onig_error_info); + ERR(GRN_INVALID_ARGUMENT, + "[operator][regexp] " + "failed to create regular expression object: <%.*s>: %s", + pattern_len, pattern, + message); + return GRN_FALSE; + } + + { + OnigPosition position; + position = onig_search(regex, + target, + target + target_len, + target, + target + target_len, + NULL, + ONIG_OPTION_NONE); + onig_free(regex); + return position != ONIG_MISMATCH; + } +#else + return GRN_FALSE; +#endif +} + +static grn_bool +exec_text_operator(grn_ctx *ctx, + grn_operator op, + const char *target, + unsigned int target_len, + const char *query, + unsigned int query_len) +{ + grn_bool matched = GRN_FALSE; + + switch (op) { + case GRN_OP_MATCH : + matched = string_have_sub_text(ctx, target, target_len, query, query_len); + break; + case GRN_OP_PREFIX : + matched = string_have_prefix(ctx, target, target_len, query, query_len); + break; + case GRN_OP_REGEXP : + matched = string_match_regexp(ctx, target, target_len, query, query_len); + break; + default : + matched = GRN_FALSE; + break; + } + + return matched; +} + +static grn_bool +exec_text_operator_raw_text_raw_text(grn_ctx *ctx, + grn_operator op, + const char *target, + unsigned int target_len, + const char *query, + unsigned int query_len) +{ + grn_obj *normalizer; + grn_obj *norm_target; + grn_obj *norm_query; + const char *norm_target_raw; + const char *norm_query_raw; + unsigned int norm_target_raw_length_in_bytes; + unsigned int norm_query_raw_length_in_bytes; + grn_bool matched = GRN_FALSE; + + if (target_len == 0 || query_len == 0) { + return GRN_FALSE; + } + + if (op == GRN_OP_REGEXP) { + return exec_text_operator(ctx, op, + target, target_len, + query, query_len); + } + + normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1); + norm_target = grn_string_open(ctx, target, target_len, normalizer, 0); + norm_query = grn_string_open(ctx, query, query_len, normalizer, 0); + grn_string_get_normalized(ctx, norm_target, + &norm_target_raw, + &norm_target_raw_length_in_bytes, + NULL); + grn_string_get_normalized(ctx, norm_query, + &norm_query_raw, + &norm_query_raw_length_in_bytes, + NULL); + + matched = exec_text_operator(ctx, op, + norm_target_raw, + norm_target_raw_length_in_bytes, + norm_query_raw, + norm_query_raw_length_in_bytes); + + grn_obj_close(ctx, norm_target); + grn_obj_close(ctx, norm_query); + grn_obj_unlink(ctx, normalizer); + + return matched; +} + +static grn_bool +exec_text_operator_record_text(grn_ctx *ctx, + grn_operator op, + grn_obj *record, grn_obj *table, + grn_obj *query) +{ + grn_obj *normalizer; + char record_key[GRN_TABLE_MAX_KEY_SIZE]; + int record_key_len; + grn_bool matched = GRN_FALSE; + + if (table->header.domain != GRN_DB_SHORT_TEXT) { + return GRN_FALSE; + } + + if (GRN_TEXT_LEN(query) == 0) { + return GRN_FALSE; + } + + record_key_len = grn_table_get_key(ctx, table, GRN_RECORD_VALUE(record), + record_key, GRN_TABLE_MAX_KEY_SIZE); + grn_table_get_info(ctx, table, NULL, NULL, NULL, &normalizer, NULL); + if (normalizer && (op != GRN_OP_REGEXP)) { + grn_obj *norm_query; + const char *norm_query_raw; + unsigned int norm_query_raw_length_in_bytes; + norm_query = grn_string_open(ctx, + GRN_TEXT_VALUE(query), + GRN_TEXT_LEN(query), + normalizer, + 0); + grn_string_get_normalized(ctx, norm_query, + &norm_query_raw, + &norm_query_raw_length_in_bytes, + NULL); + matched = exec_text_operator(ctx, + op, + record_key, + record_key_len, + norm_query_raw, + norm_query_raw_length_in_bytes); + grn_obj_close(ctx, norm_query); + } else { + matched = exec_text_operator_raw_text_raw_text(ctx, + op, + record_key, + record_key_len, + GRN_TEXT_VALUE(query), + GRN_TEXT_LEN(query)); + } + + return matched; +} + +static grn_bool +exec_text_operator_text_text(grn_ctx *ctx, + grn_operator op, + grn_obj *target, + grn_obj *query) +{ + return exec_text_operator_raw_text_raw_text(ctx, + op, + GRN_TEXT_VALUE(target), + GRN_TEXT_LEN(target), + GRN_TEXT_VALUE(query), + GRN_TEXT_LEN(query)); +} + +static grn_bool +exec_text_operator_bulk_bulk(grn_ctx *ctx, + grn_operator op, + grn_obj *target, + grn_obj *query) +{ + switch (target->header.domain) { + case GRN_DB_SHORT_TEXT : + case GRN_DB_TEXT : + case GRN_DB_LONG_TEXT : + switch (query->header.domain) { + case GRN_DB_SHORT_TEXT : + case GRN_DB_TEXT : + case GRN_DB_LONG_TEXT : + return exec_text_operator_text_text(ctx, op, target, query); + default : + break; + } + return GRN_FALSE; + default: + { + grn_obj *domain; + domain = grn_ctx_at(ctx, target->header.domain); + if (GRN_OBJ_TABLEP(domain)) { + switch (query->header.domain) { + case GRN_DB_SHORT_TEXT : + case GRN_DB_TEXT : + case GRN_DB_LONG_TEXT : + return exec_text_operator_record_text(ctx, op, target, domain, query); + default : + break; + } + } + } + return GRN_FALSE; + } +} + +grn_bool +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); + GRN_API_RETURN(matched); +} + +grn_bool +grn_operator_exec_prefix(grn_ctx *ctx, grn_obj *target, grn_obj *prefix) +{ + grn_bool matched; + GRN_API_ENTER; + matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_PREFIX, target, prefix); + GRN_API_RETURN(matched); +} + +grn_bool +grn_operator_exec_regexp(grn_ctx *ctx, grn_obj *target, grn_obj *pattern) +{ + grn_bool matched; + GRN_API_ENTER; + matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_REGEXP, target, pattern); + GRN_API_RETURN(matched); +} diff --git a/storage/mroonga/vendor/groonga/lib/output.c b/storage/mroonga/vendor/groonga/lib/output.c index 20bd2a8694a..0036e9a8619 100644 --- a/storage/mroonga/vendor/groonga/lib/output.c +++ b/storage/mroonga/vendor/groonga/lib/output.c @@ -54,6 +54,8 @@ put_delimiter(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type) case GRN_CONTENT_MSGPACK : // do nothing break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -88,6 +90,8 @@ grn_output_array_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_typ msgpack_pack_array(&ctx->impl->msgpacker, nelements); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -119,6 +123,8 @@ grn_output_array_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_ty case GRN_CONTENT_MSGPACK : // do nothing break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -155,6 +161,8 @@ grn_output_map_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, msgpack_pack_map(&ctx->impl->msgpacker, nelements); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -186,6 +194,8 @@ grn_output_map_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type case GRN_CONTENT_MSGPACK : // do nothing break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -214,6 +224,9 @@ grn_output_int32(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, in msgpack_pack_int32(&ctx->impl->msgpacker, value); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_itoa(ctx, outbuf, value); + break; case GRN_CONTENT_NONE: break; } @@ -241,6 +254,9 @@ grn_output_int64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, in msgpack_pack_int64(&ctx->impl->msgpacker, value); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_lltoa(ctx, outbuf, value); + break; case GRN_CONTENT_NONE: break; } @@ -268,6 +284,9 @@ grn_output_uint64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, i msgpack_pack_uint64(&ctx->impl->msgpacker, value); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_ulltoa(ctx, outbuf, value); + break; case GRN_CONTENT_NONE: break; } @@ -295,6 +314,9 @@ grn_output_float(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, do msgpack_pack_double(&ctx->impl->msgpacker, value); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_ftoa(ctx, outbuf, value); + break; case GRN_CONTENT_NONE: break; } @@ -320,10 +342,13 @@ grn_output_str(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, break; case GRN_CONTENT_MSGPACK : #ifdef GRN_WITH_MESSAGE_PACK - msgpack_pack_raw(&ctx->impl->msgpacker, value_len); - msgpack_pack_raw_body(&ctx->impl->msgpacker, value, value_len); + msgpack_pack_str(&ctx->impl->msgpacker, value_len); + msgpack_pack_str_body(&ctx->impl->msgpacker, value, value_len); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + GRN_TEXT_PUT(ctx, outbuf, value, value_len); + break; case GRN_CONTENT_NONE: break; } @@ -362,6 +387,9 @@ grn_output_bool(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn } #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + GRN_TEXT_PUTS(ctx, outbuf, value ? "true" : "false"); + break; case GRN_CONTENT_NONE: break; } @@ -386,6 +414,8 @@ grn_output_null(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type) msgpack_pack_nil(&ctx->impl->msgpacker); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -426,6 +456,9 @@ grn_output_time(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, int msgpack_pack_double(&ctx->impl->msgpacker, dv); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_ftoa(ctx, outbuf, dv); + break; case GRN_CONTENT_NONE: break; } @@ -477,8 +510,8 @@ grn_output_geo_point(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type grn_text_itoa(ctx, &buf, value->latitude); GRN_TEXT_PUTC(ctx, &buf, 'x'); grn_text_itoa(ctx, &buf, value->longitude); - msgpack_pack_raw(&ctx->impl->msgpacker, GRN_TEXT_LEN(&buf)); - msgpack_pack_raw_body(&ctx->impl->msgpacker, + msgpack_pack_str(&ctx->impl->msgpacker, GRN_TEXT_LEN(&buf)); + msgpack_pack_str_body(&ctx->impl->msgpacker, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf)); grn_obj_close(ctx, &buf); @@ -487,6 +520,17 @@ grn_output_geo_point(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type } #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + if (value) { + GRN_TEXT_PUTC(ctx, outbuf, '"'); + grn_text_itoa(ctx, outbuf, value->latitude); + GRN_TEXT_PUTC(ctx, outbuf, 'x'); + grn_text_itoa(ctx, outbuf, value->longitude); + GRN_TEXT_PUTC(ctx, outbuf, '"'); + } else { + GRN_TEXT_PUTS(ctx, outbuf, "\"\""); + } + break; case GRN_CONTENT_NONE: break; } @@ -1802,7 +1846,7 @@ typedef struct { } msgpack_writer_ctx; static inline int -msgpack_buffer_writer(void* data, const char* buf, unsigned int len) +msgpack_buffer_writer(void* data, const char* buf, msgpack_size_t len) { msgpack_writer_ctx *writer_ctx = (msgpack_writer_ctx *)data; return grn_bulk_write(writer_ctx->ctx, writer_ctx->buffer, buf, len); @@ -1980,8 +2024,8 @@ grn_output_envelope(grn_ctx *ctx, msgpack_pack_double(&header_packer, elapsed); if (rc != GRN_SUCCESS) { - msgpack_pack_raw(&header_packer, strlen(ctx->errbuf)); - msgpack_pack_raw_body(&header_packer, ctx->errbuf, strlen(ctx->errbuf)); + msgpack_pack_str(&header_packer, strlen(ctx->errbuf)); + msgpack_pack_str_body(&header_packer, ctx->errbuf, strlen(ctx->errbuf)); if (ctx->errfunc && ctx->errfile) { grn_obj *command = GRN_CTX_USER_DATA(ctx)->ptr; int error_detail_size; @@ -1996,33 +2040,35 @@ grn_output_envelope(grn_ctx *ctx, } msgpack_pack_array(&header_packer, error_detail_size); - msgpack_pack_raw(&header_packer, strlen(ctx->errfunc)); - msgpack_pack_raw_body(&header_packer, ctx->errfunc, strlen(ctx->errfunc)); + msgpack_pack_str(&header_packer, strlen(ctx->errfunc)); + msgpack_pack_str_body(&header_packer, ctx->errfunc, strlen(ctx->errfunc)); - msgpack_pack_raw(&header_packer, strlen(ctx->errfile)); - msgpack_pack_raw_body(&header_packer, ctx->errfile, strlen(ctx->errfile)); + msgpack_pack_str(&header_packer, strlen(ctx->errfile)); + msgpack_pack_str_body(&header_packer, ctx->errfile, strlen(ctx->errfile)); msgpack_pack_int(&header_packer, ctx->errline); if (command) { if (file) { - msgpack_pack_raw(&header_packer, strlen(file)); - msgpack_pack_raw_body(&header_packer, file, strlen(file)); + msgpack_pack_str(&header_packer, strlen(file)); + msgpack_pack_str_body(&header_packer, file, strlen(file)); } else { - msgpack_pack_raw(&header_packer, 7); - msgpack_pack_raw_body(&header_packer, "(stdin)", 7); + msgpack_pack_str(&header_packer, 7); + msgpack_pack_str_body(&header_packer, "(stdin)", 7); } msgpack_pack_int(&header_packer, line); - msgpack_pack_raw(&header_packer, GRN_TEXT_LEN(command)); - msgpack_pack_raw_body(&header_packer, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command)); + msgpack_pack_str(&header_packer, GRN_TEXT_LEN(command)); + msgpack_pack_str_body(&header_packer, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command)); } } } } #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } diff --git a/storage/mroonga/vendor/groonga/lib/pat.c b/storage/mroonga/vendor/groonga/lib/pat.c index add8469a009..e24dbe7bbf0 100644 --- a/storage/mroonga/vendor/groonga/lib/pat.c +++ b/storage/mroonga/vendor/groonga/lib/pat.c @@ -202,7 +202,7 @@ key_put(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, int len) uint8_t *dest; KEY_AT(pat, res, dest, GRN_TABLE_ADD); if (!dest) { return 0; } - memcpy(dest, key, len); + grn_memcpy(dest, key, len); } pat->header->curr_key += len; return res; @@ -227,7 +227,7 @@ pat_node_set_key(grn_ctx *ctx, grn_pat *pat, pat_node *n, const uint8_t *key, un PAT_LEN_SET(n, len); if (len <= sizeof(uint32_t)) { PAT_IMD_ON(n); - memcpy(&n->key, key, len); + grn_memcpy(&n->key, key, len); } else { PAT_IMD_OFF(n); n->key = key_put(ctx, pat, key, len); @@ -725,7 +725,7 @@ _grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint pat->header->garbages[size2] = rn->lr[0]; if (!(keybuf = pat_node_get_key(ctx, pat, rn))) { return 0; } PAT_LEN_SET(rn, size); - memcpy(keybuf, key, size); + grn_memcpy(keybuf, key, size); } else { if (!(rn = pat_node_new(ctx, pat, &r))) { return 0; } pat_node_set_key(ctx, pat, rn, key, size); @@ -1137,14 +1137,18 @@ _grn_pat_del(grn_ctx *ctx, grn_pat *pat, const char *key, uint32_t key_size, int di->stat = DL_PHASE2; di->d = r; if (otherside) { - PAT_AT(pat, otherside, rno); - if (rno && c0 < PAT_CHK(rno) && PAT_CHK(rno) <= c) { - if (!delinfo_search(pat, otherside)) { - GRN_LOG(ctx, GRN_LOG_ERROR, "no delinfo found %d", otherside); + if (otherside == r) { + otherside = 0; + } else { + PAT_AT(pat, otherside, rno); + if (rno && c0 < PAT_CHK(rno) && PAT_CHK(rno) <= c) { + if (!delinfo_search(pat, otherside)) { + GRN_LOG(ctx, GRN_LOG_DEBUG, "no delinfo found %d", otherside); + } + PAT_CHK_SET(rno, 0); } - PAT_CHK_SET(rno, 0); + if (proot == p0 && !rno->check) { rno->lr[0] = rno->lr[1] = otherside; } } - if (proot == p0 && !rno->check) { rno->lr[0] = rno->lr[1] = otherside; } } *p0 = otherside; } else { @@ -1201,14 +1205,18 @@ _grn_pat_del(grn_ctx *ctx, grn_pat *pat, const char *key, uint32_t key_size, int if (proot == p0 && !rn0->check) { rn0->lr[0] = rn0->lr[1] = otherside; } } else { if (otherside) { - PAT_AT(pat, otherside, rno); - if (rno && c0 < PAT_CHK(rno) && PAT_CHK(rno) <= c) { - if (!delinfo_search(pat, otherside)) { - GRN_LOG(ctx, GRN_LOG_ERROR, "no delinfo found %d", otherside); + if (otherside == r) { + otherside = 0; + } else { + PAT_AT(pat, otherside, rno); + if (rno && c0 < PAT_CHK(rno) && PAT_CHK(rno) <= c) { + if (!delinfo_search(pat, otherside)) { + GRN_LOG(ctx, GRN_LOG_ERROR, "no delinfo found %d", otherside); + } + PAT_CHK_SET(rno, 0); } - PAT_CHK_SET(rno, 0); + if (proot == p0 && !rno->check) { rno->lr[0] = rno->lr[1] = otherside; } } - if (proot == p0 && !rno->check) { rno->lr[0] = rno->lr[1] = otherside; } } *p0 = otherside; } @@ -1295,7 +1303,7 @@ grn_pat_get_key(grn_ctx *ctx, grn_pat *pat, grn_id id, void *keybuf, int bufsize if (KEY_NEEDS_CONVERT(pat, len)) { KEY_DEC(pat, keybuf, key, len); } else { - memcpy(keybuf, key, len); + grn_memcpy(keybuf, key, len); } } return len; @@ -1341,9 +1349,9 @@ grn_pat_get_value(grn_ctx *ctx, grn_pat *pat, grn_id id, void *valuebuf) if (v) { if (valuebuf) { if (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) { - memcpy(valuebuf, v + sizeof(sis_node), value_size); + grn_memcpy(valuebuf, v + sizeof(sis_node), value_size); } else { - memcpy(valuebuf, v, value_size); + grn_memcpy(valuebuf, v, value_size); } } return value_size; @@ -1377,7 +1385,7 @@ grn_pat_set_value(grn_ctx *ctx, grn_pat *pat, grn_id id, if (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) { v += sizeof(sis_node); } switch ((flags & GRN_OBJ_SET_MASK)) { case GRN_OBJ_SET : - memcpy(v, value, value_size); + grn_memcpy(v, value, value_size); return GRN_SUCCESS; case GRN_OBJ_INCR : switch (value_size) { @@ -2773,7 +2781,7 @@ rk_emit(rk_tree_node *rn, char **str) #define RK_OUTPUT(e,l) do {\ if (oc < oe) {\ uint32_t l_ = (oc + (l) < oe) ? (l) : (oe - oc);\ - memcpy(oc, (e), l_);\ + grn_memcpy(oc, (e), l_);\ oc += l_;\ ic_ = ic;\ }\ @@ -2863,7 +2871,7 @@ search_push(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c, if (l + key_len <= GRN_TABLE_MAX_KEY_SIZE) { int ch = c0; grn_id i; - memcpy(key + key_len, e, l); + grn_memcpy(key + key_len, e, l); if ((i = sub_search(ctx, pat, id, &ch, key, key_len + l))) { search_push(ctx, pat, c, key, key_len + l, rn->next, i, ch, flags); } diff --git a/storage/mroonga/vendor/groonga/lib/plugin.c b/storage/mroonga/vendor/groonga/lib/plugin.c index 7fd0fbd1971..48ccded0b92 100644 --- a/storage/mroonga/vendor/groonga/lib/plugin.c +++ b/storage/mroonga/vendor/groonga/lib/plugin.c @@ -45,10 +45,6 @@ static grn_hash *grn_plugins = NULL; static grn_critical_section grn_plugins_lock; -#ifdef GRN_WITH_MRUBY -static const char *grn_plugin_mrb_suffix = ".rb"; -#endif /* GRN_WITH_MRUBY */ - #ifdef HAVE_DLFCN_H # include <dlfcn.h> # define grn_dl_open(filename) dlopen(filename, RTLD_LAZY | RTLD_LOCAL) @@ -68,6 +64,8 @@ static const char *grn_plugin_mrb_suffix = ".rb"; # define grn_dl_clear_error() #endif +#define GRN_PLUGIN_KEY_SIZE(filename) (strlen((filename)) + 1) + static int compute_name_size(const char *name, int name_size) { @@ -88,7 +86,8 @@ grn_plugin_reference(grn_ctx *ctx, const char *filename) grn_plugin **plugin = NULL; CRITICAL_SECTION_ENTER(grn_plugins_lock); - id = grn_hash_get(&grn_gctx, grn_plugins, filename, strlen(filename), + id = grn_hash_get(&grn_gctx, grn_plugins, + filename, GRN_PLUGIN_KEY_SIZE(filename), (void **)&plugin); if (plugin) { (*plugin)->refcount++; @@ -102,7 +101,8 @@ const char * grn_plugin_path(grn_ctx *ctx, grn_id id) { const char *path; - uint32_t key_size; + grn_plugin *plugin; + int value_size; const char *system_plugins_dir; size_t system_plugins_dir_size; @@ -111,13 +111,14 @@ grn_plugin_path(grn_ctx *ctx, grn_id id) } CRITICAL_SECTION_ENTER(grn_plugins_lock); - path = _grn_hash_key(&grn_gctx, grn_plugins, id, &key_size); + value_size = grn_hash_get_value(&grn_gctx, grn_plugins, id, &plugin); CRITICAL_SECTION_LEAVE(grn_plugins_lock); - if (!path) { + if (!plugin) { return NULL; } + path = plugin->path; system_plugins_dir = grn_plugin_get_system_plugins_dir(); system_plugins_dir_size = strlen(system_plugins_dir); if (strncmp(system_plugins_dir, path, system_plugins_dir_size) == 0) { @@ -254,6 +255,11 @@ grn_plugin_open_mrb(grn_ctx *ctx, const char *filename, size_t filename_size) grn_id id = GRN_ID_NIL; grn_plugin **plugin = NULL; + if (!ctx->impl->mrb.state) { + ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "mruby support isn't enabled"); + return GRN_ID_NIL; + } + id = grn_hash_add(&grn_gctx, grn_plugins, filename, filename_size, (void **)&plugin, NULL); if (!id) { @@ -266,6 +272,7 @@ grn_plugin_open_mrb(grn_ctx *ctx, const char *filename, size_t filename_size) return GRN_ID_NIL; } + grn_memcpy((*plugin)->path, filename, filename_size); (*plugin)->dl = NULL; (*plugin)->init_func = NULL; (*plugin)->register_func = NULL; @@ -284,7 +291,7 @@ grn_plugin_open(grn_ctx *ctx, const char *filename) grn_plugin **plugin = NULL; size_t filename_size; - filename_size = strlen(filename); + filename_size = GRN_PLUGIN_KEY_SIZE(filename); CRITICAL_SECTION_ENTER(grn_plugins_lock); if ((id = grn_hash_get(&grn_gctx, grn_plugins, filename, filename_size, @@ -294,11 +301,15 @@ grn_plugin_open(grn_ctx *ctx, const char *filename) } #ifdef GRN_WITH_MRUBY - if (filename_size > strlen(grn_plugin_mrb_suffix) && - strcmp(filename + (filename_size - strlen(grn_plugin_mrb_suffix)), - grn_plugin_mrb_suffix) == 0) { - id = grn_plugin_open_mrb(ctx, filename, filename_size); - goto exit; + { + const char *mrb_suffix; + mrb_suffix = grn_plugin_get_ruby_suffix(); + if (filename_size > strlen(mrb_suffix) && + strcmp(filename + (strlen(filename) - strlen(mrb_suffix)), + mrb_suffix) == 0) { + id = grn_plugin_open_mrb(ctx, filename, filename_size); + goto exit; + } } #endif /* GRN_WITH_MRUBY */ @@ -307,6 +318,7 @@ grn_plugin_open(grn_ctx *ctx, const char *filename) (void **)&plugin, NULL))) { *plugin = GRN_GMALLOCN(grn_plugin, 1); if (*plugin) { + grn_memcpy((*plugin)->path, filename, filename_size); if (grn_plugin_initialize(ctx, *plugin, dl, id, filename)) { GRN_GFREE(*plugin); *plugin = NULL; @@ -439,6 +451,12 @@ grn_plugin_get_suffix(void) return GRN_PLUGIN_SUFFIX; } +const char * +grn_plugin_get_ruby_suffix(void) +{ + return ".rb"; +} + grn_rc grn_plugin_register_by_path(grn_ctx *ctx, const char *path) { @@ -476,9 +494,9 @@ grn_plugin_get_default_system_plugins_dir(void) base_dir = grn_win32_base_dir(); base_dir_length = strlen(base_dir); - strcpy(win32_plugins_dir_buffer, base_dir); - strcat(win32_plugins_dir_buffer, "/"); - strcat(win32_plugins_dir_buffer, relative_path); + grn_strcpy(win32_plugins_dir_buffer, PATH_MAX, base_dir); + grn_strcat(win32_plugins_dir_buffer, PATH_MAX, "/"); + grn_strcat(win32_plugins_dir_buffer, PATH_MAX, relative_path); win32_plugins_dir = win32_plugins_dir_buffer; } return win32_plugins_dir; @@ -495,14 +513,16 @@ grn_plugin_get_default_system_plugins_dir(void) const char * grn_plugin_get_system_plugins_dir(void) { - const char *plugins_dir; + static char plugins_dir[GRN_ENV_BUFFER_SIZE]; - plugins_dir = getenv("GRN_PLUGINS_DIR"); - if (!plugins_dir) { - plugins_dir = grn_plugin_get_default_system_plugins_dir(); + grn_getenv("GRN_PLUGINS_DIR", + plugins_dir, + GRN_ENV_BUFFER_SIZE); + if (plugins_dir[0]) { + return plugins_dir; + } else { + return grn_plugin_get_default_system_plugins_dir(); } - - return plugins_dir; } static char * @@ -521,14 +541,19 @@ grn_plugin_find_path_raw(grn_ctx *ctx, const char *path) return GRN_STRDUP(path); } -#if GRN_WITH_MRUBY +#ifdef GRN_WITH_MRUBY static char * grn_plugin_find_path_mrb(grn_ctx *ctx, const char *path, size_t path_len) { char mrb_path[PATH_MAX]; - const char *mrb_suffix = grn_plugin_mrb_suffix; + const char *mrb_suffix; size_t mrb_path_len; + mrb_suffix = grn_plugin_get_ruby_suffix(); + if (!ctx->impl->mrb.state) { + return NULL; + } + mrb_path_len = path_len + strlen(mrb_suffix); if (mrb_path_len >= PATH_MAX) { ERR(GRN_FILENAME_TOO_LONG, @@ -537,8 +562,8 @@ grn_plugin_find_path_mrb(grn_ctx *ctx, const char *path, size_t path_len) return NULL; } - strcpy(mrb_path, path); - strcat(mrb_path, mrb_suffix); + grn_strcpy(mrb_path, PATH_MAX, path); + grn_strcat(mrb_path, PATH_MAX, mrb_suffix); return grn_plugin_find_path_raw(ctx, mrb_path); } #else /* GRN_WITH_MRUBY */ @@ -565,8 +590,8 @@ grn_plugin_find_path_so(grn_ctx *ctx, const char *path, size_t path_len) return NULL; } - strcpy(so_path, path); - strcat(so_path, so_suffix); + grn_strcpy(so_path, PATH_MAX, path); + grn_strcat(so_path, PATH_MAX, so_suffix); return grn_plugin_find_path_raw(ctx, so_path); } @@ -598,10 +623,10 @@ grn_plugin_find_path_libs_so(grn_ctx *ctx, const char *path, size_t path_len) } libs_so_path[0] = '\0'; - strncat(libs_so_path, path, base_name - path); - strcat(libs_so_path, libs_path); - strcat(libs_so_path, base_name); - strcat(libs_so_path, so_suffix); + grn_strncat(libs_so_path, PATH_MAX, path, base_name - path); + grn_strcat(libs_so_path, PATH_MAX, libs_path); + grn_strcat(libs_so_path, PATH_MAX, base_name); + grn_strcat(libs_so_path, PATH_MAX, so_suffix); return grn_plugin_find_path_raw(ctx, libs_so_path); } @@ -620,11 +645,11 @@ grn_plugin_find_path(grn_ctx *ctx, const char *name) path[0] = '\0'; } else { plugins_dir = grn_plugin_get_system_plugins_dir(); - strcpy(path, plugins_dir); + grn_strcpy(path, PATH_MAX, plugins_dir); dir_last_char = plugins_dir[strlen(path) - 1]; if (dir_last_char != '/') { - strcat(path, "/"); + grn_strcat(path, PATH_MAX, "/"); } } @@ -637,7 +662,7 @@ grn_plugin_find_path(grn_ctx *ctx, const char *name) path, name); goto exit; } - strcat(path, name); + grn_strcat(path, PATH_MAX, name); found_path = grn_plugin_find_path_raw(ctx, path); if (found_path) { @@ -673,6 +698,30 @@ exit : GRN_API_RETURN(found_path); } +static void +grn_plugin_set_name_resolve_error(grn_ctx *ctx, const char *name, + const char *tag) +{ + const char *prefix, *prefix_separator, *suffix; + + if (name[0] == '/') { + prefix = ""; + prefix_separator = ""; + suffix = ""; + } else { + prefix = grn_plugin_get_system_plugins_dir(); + if (prefix[strlen(prefix) - 1] != '/') { + prefix_separator = "/"; + } else { + prefix_separator = ""; + } + suffix = grn_plugin_get_suffix(); + } + ERR(GRN_NO_SUCH_FILE_OR_DIRECTORY, + "%s cannot find plugin file: <%s%s%s%s>", + tag, prefix, prefix_separator, name, suffix); +} + grn_rc grn_plugin_register(grn_ctx *ctx, const char *name) { @@ -686,23 +735,86 @@ grn_plugin_register(grn_ctx *ctx, const char *name) GRN_FREE(path); } else { if (ctx->rc == GRN_SUCCESS) { - const char *prefix, *prefix_separator, *suffix; - if (name[0] == '/') { - prefix = ""; - prefix_separator = ""; - suffix = ""; + grn_plugin_set_name_resolve_error(ctx, name, "[plugin][register]"); + } + rc = ctx->rc; + } + GRN_API_RETURN(rc); +} + +grn_rc +grn_plugin_unregister_by_path(grn_ctx *ctx, const char *path) +{ + grn_obj *db; + grn_id plugin_id; + + if (!ctx || !ctx->impl) { + ERR(GRN_INVALID_ARGUMENT, "[plugin][unregister] ctx isn't initialized"); + return ctx->rc; + } + + db = ctx->impl->db; + if (!db) { + ERR(GRN_INVALID_ARGUMENT, "[plugin][unregister] DB isn't initialized"); + return ctx->rc; + } + + GRN_API_ENTER; + + CRITICAL_SECTION_ENTER(grn_plugins_lock); + plugin_id = grn_hash_get(&grn_gctx, grn_plugins, + path, GRN_PLUGIN_KEY_SIZE(path), + NULL); + CRITICAL_SECTION_LEAVE(grn_plugins_lock); + + if (plugin_id == GRN_ID_NIL) { + GRN_API_RETURN(ctx->rc); + } + + { + grn_table_cursor *cursor; + grn_id id; + + cursor = grn_table_cursor_open(ctx, db, + NULL, 0, + NULL, 0, + 0, -1, GRN_CURSOR_BY_ID); + if (!cursor) { + GRN_API_RETURN(ctx->rc); + } + + while ((id = grn_table_cursor_next(ctx, cursor))) { + grn_obj *obj; + obj = grn_ctx_at(ctx, id); + if (!obj) { + continue; + } + if (obj->header.type == GRN_PROC && DB_OBJ(obj)->range == plugin_id) { + grn_obj_remove(ctx, obj); } else { - prefix = grn_plugin_get_system_plugins_dir(); - if (prefix[strlen(prefix) - 1] != '/') { - prefix_separator = "/"; - } else { - prefix_separator = ""; - } - suffix = grn_plugin_get_suffix(); + grn_obj_unlink(ctx, obj); } - ERR(GRN_NO_SUCH_FILE_OR_DIRECTORY, - "cannot find plugin file: <%s%s%s%s>", - prefix, prefix_separator, name, suffix); + } + grn_table_cursor_close(ctx, cursor); + } + + GRN_API_RETURN(ctx->rc); +} + +grn_rc +grn_plugin_unregister(grn_ctx *ctx, const char *name) +{ + grn_rc rc; + char *path; + + GRN_API_ENTER; + path = grn_plugin_find_path(ctx, name); + if (path) { + rc = grn_plugin_unregister_by_path(ctx, path); + GRN_FREE(path); + } else { + if (ctx->rc == GRN_SUCCESS) { + grn_plugin_set_name_resolve_error(ctx, name, "[plugin][unregister]"); } rc = ctx->rc; } diff --git a/storage/mroonga/vendor/groonga/lib/proc.c b/storage/mroonga/vendor/groonga/lib/proc.c index 03deb0c4b70..fc6aa690e74 100644 --- a/storage/mroonga/vendor/groonga/lib/proc.c +++ b/storage/mroonga/vendor/groonga/lib/proc.c @@ -27,19 +27,18 @@ #include "grn_expr.h" #include <string.h> -#include <float.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> +#ifdef WIN32 +# include <share.h> +#endif /* WIN32 */ + #ifndef O_NOFOLLOW #define O_NOFOLLOW 0 #endif -#ifndef O_BINARY -#define O_BINARY 0 -#endif - typedef grn_rc (*grn_substitute_term_func) (grn_ctx *ctx, const char *term, unsigned int term_len, @@ -65,7 +64,8 @@ grn_bulk_put_from_file(grn_ctx *ctx, grn_obj *bulk, const char *path) /* FIXME: implement more smartly with grn_bulk */ int fd, ret = 0; struct stat stat; - if ((fd = GRN_OPEN(path, O_RDONLY|O_NOFOLLOW|O_BINARY)) == -1) { + grn_open(fd, path, O_RDONLY|O_NOFOLLOW|GRN_OPEN_FLAG_BINARY); + if (fd == -1) { switch (errno) { case EACCES : ERR(GRN_OPERATION_NOT_PERMITTED, "request is not allowed: <%s>", path); @@ -91,7 +91,7 @@ grn_bulk_put_from_file(grn_ctx *ctx, grn_obj *bulk, const char *path) if ((buf = GRN_MALLOC(rest))) { ssize_t ss; for (bp = buf; rest; rest -= ss, bp += ss) { - if ((ss = GRN_READ(fd, bp, rest)) == -1) { goto exit; } + if ((ss = grn_read(fd, bp, rest)) == -1) { goto exit; } } GRN_TEXT_PUT(ctx, bulk, buf, stat.st_size); ret = 1; @@ -101,7 +101,7 @@ grn_bulk_put_from_file(grn_ctx *ctx, grn_obj *bulk, const char *path) ERR(GRN_INVALID_ARGUMENT, "cannot stat file: <%s>", path); } exit : - GRN_CLOSE(fd); + grn_close(fd); return ret; } @@ -866,7 +866,7 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len, grn_obj *outbuf = ctx->impl->outbuf; grn_content_type output_type = ctx->impl->output_type; grn_obj *table_, *match_columns_ = NULL, *cond = NULL, *scorer_, *res = NULL, *sorted; - char cache_key[GRN_TABLE_MAX_KEY_SIZE]; + char cache_key[GRN_CACHE_MAX_KEY_SIZE]; uint32_t cache_key_size; long long int threshold, original_threshold = 0; grn_cache *cache_obj = grn_cache_current_get(ctx); @@ -887,52 +887,57 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len, sizeof(int) * 2; } } - if (cache_key_size <= GRN_TABLE_MAX_KEY_SIZE) { + if (cache_key_size <= GRN_CACHE_MAX_KEY_SIZE) { grn_obj *cache_value; char *cp = cache_key; - memcpy(cp, table, table_len); + grn_memcpy(cp, table, table_len); cp += table_len; *cp++ = '\0'; - memcpy(cp, match_columns, match_columns_len); + grn_memcpy(cp, match_columns, match_columns_len); cp += match_columns_len; *cp++ = '\0'; - memcpy(cp, query, query_len); + grn_memcpy(cp, query, query_len); cp += query_len; *cp++ = '\0'; - memcpy(cp, filter, filter_len); + grn_memcpy(cp, filter, filter_len); cp += filter_len; *cp++ = '\0'; - memcpy(cp, scorer, scorer_len); + grn_memcpy(cp, scorer, scorer_len); cp += scorer_len; *cp++ = '\0'; - memcpy(cp, sortby, sortby_len); + grn_memcpy(cp, sortby, sortby_len); cp += sortby_len; *cp++ = '\0'; - memcpy(cp, output_columns, output_columns_len); + grn_memcpy(cp, output_columns, output_columns_len); cp += output_columns_len; *cp++ = '\0'; { unsigned int i; for (i = 0; i < n_drilldowns; i++) { drilldown_info *drilldown = &(drilldowns[i]); - memcpy(cp, drilldown->keys, drilldown->keys_len); + grn_memcpy(cp, drilldown->keys, drilldown->keys_len); cp += drilldown->keys_len; *cp++ = '\0'; - memcpy(cp, drilldown->sortby, drilldown->sortby_len); + grn_memcpy(cp, drilldown->sortby, drilldown->sortby_len); cp += drilldown->sortby_len; *cp++ = '\0'; - memcpy(cp, drilldown->output_columns, drilldown->output_columns_len); + grn_memcpy(cp, drilldown->output_columns, drilldown->output_columns_len); cp += drilldown->output_columns_len; *cp++ = '\0'; } } - memcpy(cp, match_escalation_threshold, match_escalation_threshold_len); + grn_memcpy(cp, match_escalation_threshold, match_escalation_threshold_len); cp += match_escalation_threshold_len; *cp++ = '\0'; - memcpy(cp, query_expander, query_expander_len); + grn_memcpy(cp, query_expander, query_expander_len); cp += query_expander_len; *cp++ = '\0'; - memcpy(cp, query_flags, query_flags_len); + grn_memcpy(cp, query_flags, query_flags_len); cp += query_flags_len; *cp++ = '\0'; - memcpy(cp, adjuster, adjuster_len); + grn_memcpy(cp, adjuster, adjuster_len); cp += adjuster_len; *cp++ = '\0'; - memcpy(cp, &output_type, sizeof(grn_content_type)); cp += sizeof(grn_content_type); - memcpy(cp, &offset, sizeof(int)); cp += sizeof(int); - memcpy(cp, &limit, sizeof(int)); cp += sizeof(int); + grn_memcpy(cp, &output_type, sizeof(grn_content_type)); + cp += sizeof(grn_content_type); + grn_memcpy(cp, &offset, sizeof(int)); + cp += sizeof(int); + grn_memcpy(cp, &limit, sizeof(int)); + cp += sizeof(int); { unsigned int i; for (i = 0; i < n_drilldowns; i++) { drilldown_info *drilldown = &(drilldowns[i]); - memcpy(cp, &(drilldown->offset), sizeof(int)); cp += sizeof(int); - memcpy(cp, &(drilldown->limit), sizeof(int)); cp += sizeof(int); + grn_memcpy(cp, &(drilldown->offset), sizeof(int)); + cp += sizeof(int); + grn_memcpy(cp, &(drilldown->limit), sizeof(int)); + cp += sizeof(int); } } cache_value = grn_cache_fetch(ctx, cache_obj, cache_key, cache_key_size); @@ -1138,7 +1143,7 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len, GRN_OUTPUT_ARRAY_OPEN("RESULT", 0); } GRN_OUTPUT_ARRAY_CLOSE(); - if (!ctx->rc && cacheable && cache_key_size <= GRN_TABLE_MAX_KEY_SIZE + if (!ctx->rc && cacheable && cache_key_size <= GRN_CACHE_MAX_KEY_SIZE && (!cache || cache_len != 2 || *cache != 'n' || *(cache + 1) != 'o')) { grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf); } @@ -1257,8 +1262,10 @@ proc_select(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) drilldown->label_len = label_len; #define GET_VAR(name)\ - snprintf(key_name, GRN_TABLE_MAX_KEY_SIZE,\ - "drilldown[%.*s]." # name, label_len, label);\ + grn_snprintf(key_name, \ + GRN_TABLE_MAX_KEY_SIZE, \ + GRN_TABLE_MAX_KEY_SIZE, \ + "drilldown[%.*s]." # name, label_len, label); \ name = GRN_PROC_GET_VAR(key_name); GET_VAR(keys); @@ -1943,7 +1950,7 @@ proc_column_remove(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_ if ((fullname_len = grn_obj_name(ctx, table, fullname, GRN_TABLE_MAX_KEY_SIZE))) { fullname[fullname_len] = GRN_DB_DELIMITER; - memcpy((fullname + fullname_len + 1), colname, colname_len); + grn_memcpy((fullname + fullname_len + 1), colname, colname_len); fullname_len += colname_len + 1; //TODO:check fullname_len < GRN_TABLE_MAX_KEY_SIZE col = grn_ctx_get(ctx, fullname, fullname_len); @@ -2336,7 +2343,7 @@ proc_missing(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) } if ((plen = GRN_TEXT_LEN(VAR(0))) + grn_document_root_len < PATH_MAX) { char path[PATH_MAX]; - memcpy(path, grn_document_root, grn_document_root_len); + grn_memcpy(path, grn_document_root, grn_document_root_len); path[grn_document_root_len] = '/'; grn_str_url_path_normalize(ctx, GRN_TEXT_VALUE(VAR(0)), @@ -2605,7 +2612,7 @@ proc_delete(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) GRN_EXPR_SYNTAX_SCRIPT); if (ctx->rc) { char original_error_message[GRN_CTX_MSGSIZE]; - strcpy(original_error_message, ctx->errbuf); + grn_strcpy(original_error_message, GRN_CTX_MSGSIZE, ctx->errbuf); rc = ctx->rc; ERR(rc, "[table][record][delete] failed to parse filter: " @@ -2644,6 +2651,110 @@ exit : static const size_t DUMP_FLUSH_THRESHOLD_SIZE = 256 * 1024; static void +dump_plugins(grn_ctx *ctx, grn_obj *outbuf) +{ + grn_obj *db = ctx->impl->db; + grn_table_cursor *cursor; + grn_id id; + grn_hash *processed_paths; + const char *system_plugins_dir; + const char *native_plugin_suffix; + const char *ruby_plugin_suffix; + + cursor = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, + GRN_CURSOR_BY_ID); + if (!cursor) { + return; + } + + processed_paths = grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, 0, + GRN_OBJ_TABLE_HASH_KEY | + GRN_OBJ_KEY_VAR_SIZE); + if (!processed_paths) { + grn_table_cursor_close(ctx, cursor); + return; + } + + system_plugins_dir = grn_plugin_get_system_plugins_dir(); + native_plugin_suffix = grn_plugin_get_suffix(); + ruby_plugin_suffix = grn_plugin_get_ruby_suffix(); + while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { + grn_obj *object; + const char *path; + grn_id processed_path_id; + + object = grn_ctx_at(ctx, id); + if (!object) { + ERRCLR(ctx); + continue; + } + + if (!grn_obj_is_proc(ctx, object)) { + grn_obj_unlink(ctx, object); + continue; + } + + if (grn_obj_is_builtin(ctx, object)) { + grn_obj_unlink(ctx, object); + continue; + } + + path = grn_obj_path(ctx, object); + if (!path) { + grn_obj_unlink(ctx, object); + continue; + } + + processed_path_id = grn_hash_get(ctx, processed_paths, + path, strlen(path), + NULL); + if (processed_path_id != GRN_ID_NIL) { + grn_obj_unlink(ctx, object); + continue; + } + + grn_hash_add(ctx, processed_paths, + path, strlen(path), + NULL, NULL); + + { + const char *relative_path; + const char *libs_path = "/.libs/"; + const char *start_libs; + char name[PATH_MAX]; + + name[0] = '\0'; + if (strncmp(path, system_plugins_dir, strlen(system_plugins_dir)) == 0) { + relative_path = path + strlen(system_plugins_dir); + } else { + relative_path = path; + } + start_libs = strstr(relative_path, libs_path); + if (start_libs) { + grn_strncat(name, PATH_MAX, relative_path, start_libs - relative_path); + grn_strcat(name, PATH_MAX, "/"); + grn_strcat(name, PATH_MAX, start_libs + strlen(libs_path)); + } else { + grn_strcat(name, PATH_MAX, relative_path); + } + if (strlen(name) > strlen(native_plugin_suffix) && + strcmp(name + strlen(name) - strlen(native_plugin_suffix), + native_plugin_suffix) == 0) { + name[strlen(name) - strlen(native_plugin_suffix)] = '\0'; + } else if (strlen(name) > strlen(ruby_plugin_suffix) && + strcmp(name + strlen(name) - strlen(ruby_plugin_suffix), + ruby_plugin_suffix) == 0) { + name[strlen(name) - strlen(ruby_plugin_suffix)] = '\0'; + } + grn_text_printf(ctx, outbuf, "plugin_register %s\n", name); + } + } + grn_table_cursor_close(ctx, cursor); + + grn_hash_close(ctx, processed_paths); +} + +static void dump_name(grn_ctx *ctx, grn_obj *outbuf, const char *name, int name_len) { grn_obj escaped_name; @@ -2771,7 +2882,7 @@ reference_column_p(grn_ctx *ctx, grn_obj *column) static void dump_columns(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table, - grn_obj *pending_columns) + grn_obj *pending_reference_columns) { grn_hash *columns; columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, @@ -2787,8 +2898,10 @@ dump_columns(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table, GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, { grn_obj *column; if ((column = grn_ctx_at(ctx, *key))) { - if (reference_column_p(ctx, column)) { - GRN_PTR_PUT(ctx, pending_columns, column); + if (GRN_OBJ_INDEX_COLUMNP(column)) { + /* do nothing */ + } else if (reference_column_p(ctx, column)) { + GRN_PTR_PUT(ctx, pending_reference_columns, column); } else { dump_column(ctx, outbuf, table, column); grn_obj_unlink(ctx, column); @@ -2834,6 +2947,8 @@ dump_records(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table) grn_table_cursor *cursor; int i, ncolumns, n_use_columns; grn_obj columnbuf, delete_commands, use_columns, column_name; + grn_bool have_index_column = GRN_FALSE; + grn_bool have_data_column = GRN_FALSE; switch (table->header.type) { case GRN_TABLE_HASH_KEY: @@ -2849,12 +2964,6 @@ dump_records(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table) return; } - GRN_TEXT_INIT(&delete_commands, 0); - - GRN_TEXT_PUTS(ctx, outbuf, "load --table "); - dump_obj_name(ctx, outbuf, table); - GRN_TEXT_PUTS(ctx, outbuf, "\n[\n"); - GRN_PTR_INIT(&columnbuf, GRN_OBJ_VECTOR, GRN_ID_NIL); grn_obj_columns(ctx, table, DUMP_COLUMNS, strlen(DUMP_COLUMNS), &columnbuf); columns = (grn_obj **)GRN_BULK_HEAD(&columnbuf); @@ -2864,27 +2973,47 @@ dump_records(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table) GRN_TEXT_INIT(&column_name, 0); for (i = 0; i < ncolumns; i++) { if (GRN_OBJ_INDEX_COLUMNP(columns[i])) { + have_index_column = GRN_TRUE; continue; } + + if (columns[i]->header.type != GRN_ACCESSOR) { + have_data_column = GRN_TRUE; + } + GRN_BULK_REWIND(&column_name); grn_column_name_(ctx, columns[i], &column_name); - if (((table->header.type == GRN_TABLE_HASH_KEY || - table->header.type == GRN_TABLE_PAT_KEY || - table->header.type == GRN_TABLE_DAT_KEY) && - GRN_TEXT_LEN(&column_name) == GRN_COLUMN_NAME_ID_LEN && - !memcmp(GRN_TEXT_VALUE(&column_name), - GRN_COLUMN_NAME_ID, - GRN_COLUMN_NAME_ID_LEN)) || - (table->header.type == GRN_TABLE_NO_KEY && - GRN_TEXT_LEN(&column_name) == GRN_COLUMN_NAME_KEY_LEN && - !memcmp(GRN_TEXT_VALUE(&column_name), - GRN_COLUMN_NAME_KEY, - GRN_COLUMN_NAME_KEY_LEN))) { + if (table->header.type != GRN_TABLE_NO_KEY && + GRN_TEXT_LEN(&column_name) == GRN_COLUMN_NAME_ID_LEN && + memcmp(GRN_TEXT_VALUE(&column_name), + GRN_COLUMN_NAME_ID, + GRN_COLUMN_NAME_ID_LEN) == 0) { + continue; + } + + if (table->header.type == GRN_TABLE_NO_KEY && + GRN_TEXT_LEN(&column_name) == GRN_COLUMN_NAME_KEY_LEN && + memcmp(GRN_TEXT_VALUE(&column_name), + GRN_COLUMN_NAME_KEY, + GRN_COLUMN_NAME_KEY_LEN) == 0) { continue; } + GRN_PTR_PUT(ctx, &use_columns, columns[i]); } + if (have_index_column && !have_data_column) { + goto exit; + } + + if (GRN_TEXT_LEN(outbuf) > 0) { + GRN_TEXT_PUTC(ctx, outbuf, '\n'); + } + + GRN_TEXT_PUTS(ctx, outbuf, "load --table "); + dump_obj_name(ctx, outbuf, table); + GRN_TEXT_PUTS(ctx, outbuf, "\n[\n"); + n_use_columns = GRN_BULK_VSIZE(&use_columns) / sizeof(grn_obj *); GRN_TEXT_PUTC(ctx, outbuf, '['); for (i = 0; i < n_use_columns; i++) { @@ -2897,6 +3026,7 @@ dump_records(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table) } GRN_TEXT_PUTS(ctx, outbuf, "],\n"); + GRN_TEXT_INIT(&delete_commands, 0); cursor = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_KEY); for (i = 0; (id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL; @@ -2984,14 +3114,16 @@ dump_records(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table) grn_ctx_output_flush(ctx, 0); } } + grn_table_cursor_close(ctx, cursor); GRN_TEXT_PUTS(ctx, outbuf, "\n]\n"); GRN_TEXT_PUT(ctx, outbuf, GRN_TEXT_VALUE(&delete_commands), GRN_TEXT_LEN(&delete_commands)); grn_obj_unlink(ctx, &delete_commands); + +exit : grn_obj_unlink(ctx, &column_name); grn_obj_unlink(ctx, &use_columns); - grn_table_cursor_close(ctx, cursor); for (i = 0; i < ncolumns; i++) { grn_obj_unlink(ctx, columns[i]); } @@ -3000,7 +3132,7 @@ dump_records(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table) static void dump_table(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table, - grn_obj *pending_columns) + grn_obj *pending_reference_columns) { grn_obj *domain = NULL, *range = NULL; grn_obj_flags default_flags = GRN_OBJ_PERSISTENT; @@ -3018,6 +3150,11 @@ dump_table(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table, break; } + if (GRN_TEXT_LEN(outbuf) > 0) { + GRN_TEXT_PUTC(ctx, outbuf, '\n'); + grn_ctx_output_flush(ctx, 0); + } + GRN_TEXT_PUTS(ctx, outbuf, "table_create "); dump_obj_name(ctx, outbuf, table); GRN_TEXT_PUTC(ctx, outbuf, ' '); @@ -3081,68 +3218,77 @@ dump_table(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table, grn_obj_unlink(ctx, domain); } - dump_columns(ctx, outbuf, table, pending_columns); + dump_columns(ctx, outbuf, table, pending_reference_columns); } -/* can we move this to groonga.h? */ -#define GRN_PTR_POP(obj,value) do {\ - if (GRN_BULK_VSIZE(obj) >= sizeof(grn_obj *)) {\ - GRN_BULK_INCR_LEN((obj), -(sizeof(grn_obj *)));\ - value = *(grn_obj **)(GRN_BULK_CURR(obj));\ - } else {\ - value = NULL;\ - }\ -} while (0) +static void +dump_pending_columns(grn_ctx *ctx, grn_obj *outbuf, grn_obj *pending_columns) +{ + size_t i, n_columns; + + n_columns = GRN_BULK_VSIZE(pending_columns) / sizeof(grn_obj *); + if (n_columns == 0) { + return; + } + + if (GRN_TEXT_LEN(outbuf) > 0) { + GRN_TEXT_PUTC(ctx, outbuf, '\n'); + grn_ctx_output_flush(ctx, 0); + } + + for (i = 0; i < n_columns; i++) { + grn_obj *table, *column; + + column = GRN_PTR_VALUE_AT(pending_columns, i); + table = grn_ctx_at(ctx, column->header.domain); + dump_column(ctx, outbuf, table, column); + grn_obj_unlink(ctx, column); + grn_obj_unlink(ctx, table); + } +} static void dump_schema(grn_ctx *ctx, grn_obj *outbuf) { grn_obj *db = ctx->impl->db; grn_table_cursor *cur; - if ((cur = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, - GRN_CURSOR_BY_ID))) { - grn_id id; - grn_obj pending_columns; + grn_id id; + grn_obj pending_reference_columns; - GRN_PTR_INIT(&pending_columns, GRN_OBJ_VECTOR, GRN_ID_NIL); - while ((id = grn_table_cursor_next(ctx, cur)) != GRN_ID_NIL) { - grn_obj *object; - - if ((object = grn_ctx_at(ctx, id))) { - switch (object->header.type) { - case GRN_TABLE_HASH_KEY: - case GRN_TABLE_PAT_KEY: - case GRN_TABLE_DAT_KEY: - case GRN_TABLE_NO_KEY: - dump_table(ctx, outbuf, object, &pending_columns); - break; - default: - break; - } - grn_obj_unlink(ctx, object); - } else { - /* XXX: this clause is executed when MeCab tokenizer is enabled in - database but the groonga isn't supported MeCab. - We should return error mesage about it and error exit status - but it's too difficult for this architecture. :< */ - ERRCLR(ctx); - } - } - grn_table_cursor_close(ctx, cur); + cur = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, + GRN_CURSOR_BY_ID); + if (!cur) { + return; + } + + GRN_PTR_INIT(&pending_reference_columns, GRN_OBJ_VECTOR, GRN_ID_NIL); + while ((id = grn_table_cursor_next(ctx, cur)) != GRN_ID_NIL) { + grn_obj *object; - while (GRN_TRUE) { - grn_obj *table, *column; - GRN_PTR_POP(&pending_columns, column); - if (!column) { + if ((object = grn_ctx_at(ctx, id))) { + switch (object->header.type) { + case GRN_TABLE_HASH_KEY: + case GRN_TABLE_PAT_KEY: + case GRN_TABLE_DAT_KEY: + case GRN_TABLE_NO_KEY: + dump_table(ctx, outbuf, object, &pending_reference_columns); + break; + default: break; } - table = grn_ctx_at(ctx, column->header.domain); - dump_column(ctx, outbuf, table, column); - grn_obj_unlink(ctx, column); - grn_obj_unlink(ctx, table); + grn_obj_unlink(ctx, object); + } else { + /* XXX: this clause is executed when MeCab tokenizer is enabled in + database but the groonga isn't supported MeCab. + We should return error mesage about it and error exit status + but it's too difficult for this architecture. :< */ + ERRCLR(ctx); } - grn_obj_close(ctx, &pending_columns); } + grn_table_cursor_close(ctx, cur); + + dump_pending_columns(ctx, outbuf, &pending_reference_columns); + grn_obj_close(ctx, &pending_reference_columns); } static void @@ -3227,21 +3373,114 @@ dump_all_records(grn_ctx *ctx, grn_obj *outbuf) } } +static void +dump_indexes(grn_ctx *ctx, grn_obj *outbuf) +{ + grn_obj *db = ctx->impl->db; + grn_table_cursor *cursor; + grn_id id; + grn_bool is_first_index_column = GRN_TRUE; + + cursor = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, + GRN_CURSOR_BY_ID); + if (!cursor) { + return; + } + + while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { + grn_obj *object; + + object = grn_ctx_at(ctx, id); + if (!object) { + /* XXX: this clause is executed when MeCab tokenizer is enabled in + database but the groonga isn't supported MeCab. + We should return error mesage about it and error exit status + but it's too difficult for this architecture. :< */ + ERRCLR(ctx); + continue; + } + + if (object->header.type == GRN_COLUMN_INDEX) { + grn_obj *table; + grn_obj *column = object; + + if (is_first_index_column && GRN_TEXT_LEN(outbuf) > 0) { + GRN_TEXT_PUTC(ctx, outbuf, '\n'); + } + is_first_index_column = GRN_FALSE; + + table = grn_ctx_at(ctx, column->header.domain); + dump_column(ctx, outbuf, table, column); + grn_obj_unlink(ctx, table); + } + grn_obj_unlink(ctx, object); + } + grn_table_cursor_close(ctx, cursor); +} + +static grn_bool +bool_option_value(grn_obj *option, grn_bool default_value) +{ + const char *value; + size_t value_length; + + value = GRN_TEXT_VALUE(option); + value_length = GRN_TEXT_LEN(option); + + if (value_length == 0) { + return default_value; + } + + if (value_length == strlen("yes") && + strncmp(value, "yes", value_length) == 0) { + return GRN_TRUE; + } else if (value_length == strlen("no") && + strncmp(value, "no", value_length) == 0) { + return GRN_FALSE; + } else { + return default_value; + } +} + static grn_obj * proc_dump(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { grn_obj *outbuf = ctx->impl->outbuf; - ctx->impl->output_type = GRN_CONTENT_NONE; - ctx->impl->mime_type = "text/x-groonga-command-list"; - dump_schema(ctx, outbuf); - grn_ctx_output_flush(ctx, 0); - /* To update index columns correctly, we first create the whole schema, then - load non-derivative records, while skipping records of index columns. That - way, groonga will silently do the job of updating index columns for us. */ - if (GRN_TEXT_LEN(VAR(0)) > 0) { - dump_selected_tables_records(ctx, outbuf, VAR(0)); - } else { - dump_all_records(ctx, outbuf); + grn_obj *tables = VAR(0); + grn_obj *dump_plugins_raw = VAR(1); + grn_obj *dump_schema_raw = VAR(2); + grn_obj *dump_records_raw = VAR(3); + grn_obj *dump_indexes_raw = VAR(4); + grn_bool is_dump_plugins; + grn_bool is_dump_schema; + grn_bool is_dump_records; + grn_bool is_dump_indexes; + + grn_ctx_set_output_type(ctx, GRN_CONTENT_GROONGA_COMMAND_LIST); + + is_dump_plugins = bool_option_value(dump_plugins_raw, GRN_TRUE); + is_dump_schema = bool_option_value(dump_schema_raw, GRN_TRUE); + is_dump_records = bool_option_value(dump_records_raw, GRN_TRUE); + is_dump_indexes = bool_option_value(dump_indexes_raw, GRN_TRUE); + + if (is_dump_plugins) { + dump_plugins(ctx, outbuf); + } + if (is_dump_schema) { + dump_schema(ctx, outbuf); + } + if (is_dump_records) { + /* To update index columns correctly, we first create the whole schema, then + load non-derivative records, while skipping records of index columns. That + way, groonga will silently do the job of updating index columns for us. */ + if (GRN_TEXT_LEN(tables) > 0) { + dump_selected_tables_records(ctx, outbuf, tables); + } else { + dump_all_records(ctx, outbuf); + } + } + if (is_dump_indexes) { + dump_indexes(ctx, outbuf); } /* remove the last newline because another one will be added by the caller. @@ -5476,9 +5715,11 @@ selector_between_sequential_search(grn_ctx *ctx, double too_many_index_match_ratio = 0.01; { - const char *too_many_index_match_ratio_env = - getenv("GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO"); - if (too_many_index_match_ratio_env) { + 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); } } @@ -5721,14 +5962,15 @@ func_highlight_html(grn_ctx *ctx, int nargs, grn_obj **args, } if (condition) { + size_t i, n_keywords; grn_obj current_keywords; GRN_PTR_INIT(¤t_keywords, GRN_OBJ_VECTOR, GRN_ID_NIL); grn_expr_get_keywords(ctx, condition, ¤t_keywords); - for (;;) { + n_keywords = GRN_BULK_VSIZE(¤t_keywords) / sizeof(grn_obj *); + for (i = 0; i < n_keywords; i++) { grn_obj *keyword; - GRN_PTR_POP(¤t_keywords, keyword); - if (!keyword) { break; } + keyword = GRN_PTR_VALUE_AT(¤t_keywords, i); grn_table_add(ctx, keywords, GRN_TEXT_VALUE(keyword), GRN_TEXT_LEN(keyword), @@ -5971,9 +6213,11 @@ selector_in_values_sequential_search(grn_ctx *ctx, double too_many_index_match_ratio = 0.01; { - const char *too_many_index_match_ratio_env = - getenv("GRN_IN_VALUES_TOO_MANY_INDEX_MATCH_RATIO"); - if (too_many_index_match_ratio_env) { + 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); } } @@ -6433,6 +6677,38 @@ proc_request_cancel(grn_ctx *ctx, int nargs, grn_obj **args, return NULL; } +static grn_obj * +proc_plugin_register(grn_ctx *ctx, int nargs, grn_obj **args, + grn_user_data *user_data) +{ + if (GRN_TEXT_LEN(VAR(0))) { + const char *name; + GRN_TEXT_PUTC(ctx, VAR(0), '\0'); + name = GRN_TEXT_VALUE(VAR(0)); + grn_plugin_register(ctx, name); + } else { + ERR(GRN_INVALID_ARGUMENT, "[plugin_register] name is missing"); + } + GRN_OUTPUT_BOOL(!ctx->rc); + return NULL; +} + +static grn_obj * +proc_plugin_unregister(grn_ctx *ctx, int nargs, grn_obj **args, + grn_user_data *user_data) +{ + if (GRN_TEXT_LEN(VAR(0))) { + const char *name; + GRN_TEXT_PUTC(ctx, VAR(0), '\0'); + name = GRN_TEXT_VALUE(VAR(0)); + grn_plugin_unregister(ctx, name); + } else { + ERR(GRN_INVALID_ARGUMENT, "[plugin_unregister] name is missing"); + } + GRN_OUTPUT_BOOL(!ctx->rc); + return NULL; +} + #define DEF_VAR(v,name_str) do {\ (v).name = (name_str);\ (v).name_size = GRN_STRLEN(name_str);\ @@ -6559,8 +6835,13 @@ grn_db_init_builtin_query(grn_ctx *ctx) DEF_COMMAND("cache_limit", proc_cache_limit, 1, vars); DEF_VAR(vars[0], "tables"); - DEF_COMMAND("dump", proc_dump, 1, vars); + DEF_VAR(vars[1], "dump_plugins"); + DEF_VAR(vars[2], "dump_schema"); + DEF_VAR(vars[3], "dump_records"); + DEF_VAR(vars[4], "dump_indexes"); + DEF_COMMAND("dump", proc_dump, 5, vars); + /* Deprecated. Use "plugin_register" instead. */ DEF_VAR(vars[0], "path"); DEF_COMMAND("register", proc_register, 1, vars); @@ -6700,4 +6981,10 @@ grn_db_init_builtin_query(grn_ctx *ctx) DEF_VAR(vars[0], "id"); DEF_COMMAND("request_cancel", proc_request_cancel, 1, vars); + + DEF_VAR(vars[0], "name"); + DEF_COMMAND("plugin_register", proc_plugin_register, 1, vars); + + DEF_VAR(vars[0], "name"); + DEF_COMMAND("plugin_unregister", proc_plugin_unregister, 1, vars); } diff --git a/storage/mroonga/vendor/groonga/lib/scorer.c b/storage/mroonga/vendor/groonga/lib/scorer.c index f5bc0435108..2670bb3d4c6 100644 --- a/storage/mroonga/vendor/groonga/lib/scorer.c +++ b/storage/mroonga/vendor/groonga/lib/scorer.c @@ -100,6 +100,61 @@ grn_scorer_matched_record_get_weight(grn_ctx *ctx, return record->weight; } +grn_obj * +grn_scorer_matched_record_get_arg(grn_ctx *ctx, + grn_scorer_matched_record *record, + unsigned int i) +{ + grn_expr *expr; + grn_expr_code *codes_original; + uint32_t codes_curr_original; + grn_obj *arg; + + if (!record->args_expr) { + return NULL; + } + + expr = (grn_expr *)(record->args_expr); + /* TODO: support getting column value */ + codes_original = expr->codes; + codes_curr_original = expr->codes_curr; + expr->codes += record->args_expr_offset; + expr->codes_curr = 1; /* TODO: support 1 or more codes */ + arg = grn_expr_exec(ctx, (grn_obj *)expr, 0); + expr->codes_curr = codes_curr_original; + expr->codes = codes_original; + + return arg; +} + +unsigned int +grn_scorer_matched_record_get_n_args(grn_ctx *ctx, + grn_scorer_matched_record *record) +{ + grn_expr *expr; + grn_expr_code *codes; + unsigned int n_args = 0; + + if (!record->args_expr) { + return 0; + } + + expr = (grn_expr *)(record->args_expr); + codes = expr->codes + record->args_expr_offset; + if (codes[0].op == GRN_OP_CALL) { + return 0; + } + + n_args++; + for (; codes[0].op != GRN_OP_CALL; codes++) { + if (codes[0].op == GRN_OP_COMMA) { + n_args++; + } + } + + return n_args; +} + grn_rc grn_scorer_register(grn_ctx *ctx, const char *plugin_name_ptr, diff --git a/storage/mroonga/vendor/groonga/lib/scorers.c b/storage/mroonga/vendor/groonga/lib/scorers.c index b039e011920..dcec87c8ecc 100644 --- a/storage/mroonga/vendor/groonga/lib/scorers.c +++ b/storage/mroonga/vendor/groonga/lib/scorers.c @@ -16,6 +16,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "grn_db.h" + #include <groonga/scorer.h> #include <math.h> @@ -49,9 +51,46 @@ scorer_tf_idf(grn_ctx *ctx, grn_scorer_matched_record *record) } } +static double +scorer_tf_at_most(grn_ctx *ctx, grn_scorer_matched_record *record) +{ + double tf; + double max; + grn_obj *max_raw; + + tf = grn_scorer_matched_record_get_n_occurrences(ctx, record) + + grn_scorer_matched_record_get_total_term_weights(ctx, record); + max_raw = grn_scorer_matched_record_get_arg(ctx, record, 0); + + if (!max_raw) { + return tf; + } + + if (max_raw->header.type != GRN_BULK) { + return tf; + } + + if (max_raw->header.domain == GRN_DB_FLOAT) { + max = GRN_FLOAT_VALUE(max_raw); + } else { + grn_obj casted_max_raw; + GRN_FLOAT_INIT(&casted_max_raw, 0); + if (grn_obj_cast(ctx, max_raw, &casted_max_raw, GRN_FALSE) != GRN_SUCCESS) { + GRN_OBJ_FIN(ctx, &casted_max_raw); + return tf; + } else { + max = GRN_FLOAT_VALUE(&casted_max_raw); + } + GRN_OBJ_FIN(ctx, &casted_max_raw); + } + + return fmin(tf, max); +} + grn_rc grn_db_init_builtin_scorers(grn_ctx *ctx) { grn_scorer_register(ctx, "scorer_tf_idf", -1, scorer_tf_idf); + grn_scorer_register(ctx, "scorer_tf_at_most", -1, scorer_tf_at_most); return GRN_SUCCESS; } diff --git a/storage/mroonga/vendor/groonga/lib/snip.c b/storage/mroonga/vendor/groonga/lib/snip.c index 739ee345738..da5ba704c85 100644 --- a/storage/mroonga/vendor/groonga/lib/snip.c +++ b/storage/mroonga/vendor/groonga/lib/snip.c @@ -306,7 +306,7 @@ grn_snip_strndup(grn_ctx *ctx, const char *string, unsigned int string_len) if (!copied_string) { return NULL; } - memcpy(copied_string, string, string_len); + grn_memcpy(copied_string, string, string_len); copied_string[string_len]= '\0'; /* not required, but for ql use */ return copied_string; } @@ -775,7 +775,9 @@ grn_snip_get_result(grn_ctx *ctx, grn_obj *snip, const unsigned int index, char if (snip_->tag_result[j].end_offset > sres->end_offset) { continue; } - memcpy(p, snip_->tag_result[j].cond->opentag, snip_->tag_result[j].cond->opentag_len); + grn_memcpy(p, + snip_->tag_result[j].cond->opentag, + snip_->tag_result[j].cond->opentag_len); p += snip_->tag_result[j].cond->opentag_len; } @@ -820,8 +822,9 @@ grn_snip_get_result(grn_ctx *ctx, grn_obj *snip, const unsigned int index, char snip_->tag_result[k].end_offset <= sres->end_offset; k--) { /* TODO: avoid all loop */ if (snip_->tag_result[k].end_offset == i + 1) { - memcpy(p, snip_->tag_result[k].cond->closetag, - snip_->tag_result[k].cond->closetag_len); + grn_memcpy(p, + snip_->tag_result[k].cond->closetag, + snip_->tag_result[k].cond->closetag_len); p += snip_->tag_result[k].cond->closetag_len; } if (k <= sres->first_tag_result_idx) { diff --git a/storage/mroonga/vendor/groonga/lib/sources.am b/storage/mroonga/vendor/groonga/lib/sources.am index 25e5df5fd4d..459b73792ab 100644 --- a/storage/mroonga/vendor/groonga/lib/sources.am +++ b/storage/mroonga/vendor/groonga/lib/sources.am @@ -24,8 +24,11 @@ libgroonga_la_SOURCES = \ grn_ii.h \ io.c \ grn_io.h \ + logger.c \ + grn_logger.h \ mrb.c \ grn_mrb.h \ + grn_msgpack.h \ nfkc.c \ normalizer.c \ grn_normalizer.h \ diff --git a/storage/mroonga/vendor/groonga/lib/store.c b/storage/mroonga/vendor/groonga/lib/store.c index 6b3b01ce4be..027f86baac8 100644 --- a/storage/mroonga/vendor/groonga/lib/store.c +++ b/storage/mroonga/vendor/groonga/lib/store.c @@ -338,8 +338,6 @@ struct grn_ja_header { #define SEGMENTS_GINFO_ON(ja,seg,width) (SEGMENTS_AT(ja,seg) = SEG_GINFO|(width)) #define SEGMENTS_OFF(ja,seg) (SEGMENTS_AT(ja,seg) = 0) -grn_bool grn_ja_skip_same_value_put = GRN_TRUE; - static grn_ja * _grn_ja_create(grn_ctx *ctx, grn_ja *ja, const char *path, unsigned int max_element_size, uint32_t flags) @@ -881,12 +879,12 @@ set_value(grn_ctx *ctx, grn_ja *ja, grn_id id, void *value, uint32_t value_len, if ((rc = grn_ja_alloc(ctx, ja, id, value_len + sizeof(uint32_t), einfo, &iw))) { return rc; } - memcpy(iw.addr, value, value_len); + grn_memcpy(iw.addr, value, value_len); memset((byte *)iw.addr + value_len, 0, sizeof(uint32_t)); grn_io_win_unmap(&iw); } else { if ((rc = grn_ja_alloc(ctx, ja, id, value_len, einfo, &iw))) { return rc; } - memcpy(iw.addr, value, value_len); + grn_memcpy(iw.addr, value, value_len); grn_io_win_unmap(&iw); } return rc; @@ -901,8 +899,7 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_io_win iw; grn_ja_einfo einfo; - if (grn_ja_skip_same_value_put && - (flags & GRN_OBJ_SET_MASK) == GRN_OBJ_SET && + if ((flags & GRN_OBJ_SET_MASK) == GRN_OBJ_SET && value_len > 0) { grn_io_win jw; uint32_t old_len; @@ -935,11 +932,11 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, GRN_ASSERT(pos < el); if (el <= pos + value_len) { uint32_t rest = el - pos; - memcpy(b + pos, value, rest); - memcpy(b, (byte *)value + rest, value_len - rest); + grn_memcpy(b + pos, value, rest); + grn_memcpy(b, (byte *)value + rest, value_len - rest); *((uint32_t *)(b + el)) = value_len - rest; } else { - memcpy(b + pos, value, value_len); + grn_memcpy(b + pos, value, value_len); *((uint32_t *)(b + el)) = pos + value_len; } return GRN_SUCCESS; @@ -950,8 +947,8 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_ja_unref(ctx, &jw); return rc; } - memcpy(iw.addr, oldvalue, old_len); - memcpy((byte *)iw.addr + old_len, value, value_len); + grn_memcpy(iw.addr, oldvalue, old_len); + grn_memcpy((byte *)iw.addr + old_len, value, value_len); memset((byte *)iw.addr + old_len + value_len, 0, sizeof(uint32_t)); grn_io_win_unmap(&iw); } @@ -960,8 +957,8 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_ja_unref(ctx, &jw); return rc; } - memcpy(iw.addr, oldvalue, old_len); - memcpy((byte *)iw.addr + old_len, value, value_len); + grn_memcpy(iw.addr, oldvalue, old_len); + grn_memcpy((byte *)iw.addr + old_len, value, value_len); grn_io_win_unmap(&iw); } grn_ja_unref(ctx, &jw); @@ -985,11 +982,11 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, GRN_ASSERT(pos < el); if (pos < value_len) { uint32_t rest = value_len - pos; - memcpy(b, (byte *)value + rest, pos); - memcpy(b + el - rest, value, rest); + grn_memcpy(b, (byte *)value + rest, pos); + grn_memcpy(b + el - rest, value, rest); *((uint32_t *)(b + el)) = el - rest; } else { - memcpy(b + pos - value_len, value, value_len); + grn_memcpy(b + pos - value_len, value, value_len); *((uint32_t *)(b + el)) = pos - value_len; } return GRN_SUCCESS; @@ -1000,8 +997,8 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_ja_unref(ctx, &jw); return rc; } - memcpy(iw.addr, value, value_len); - memcpy((byte *)iw.addr + value_len, oldvalue, old_len); + grn_memcpy(iw.addr, value, value_len); + grn_memcpy((byte *)iw.addr + value_len, oldvalue, old_len); memset((byte *)iw.addr + value_len + old_len, 0, sizeof(uint32_t)); grn_io_win_unmap(&iw); } @@ -1010,8 +1007,8 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_ja_unref(ctx, &jw); return rc; } - memcpy(iw.addr, value, value_len); - memcpy((byte *)iw.addr + value_len, oldvalue, old_len); + grn_memcpy(iw.addr, value, value_len); + grn_memcpy((byte *)iw.addr + value_len, oldvalue, old_len); grn_io_win_unmap(&iw); } grn_ja_unref(ctx, &jw); @@ -1100,9 +1097,13 @@ grn_ja_putv(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_obj *vector, int flags) size_t sizev = body ? GRN_BULK_VSIZE(body) : 0; size_t sizef = GRN_BULK_VSIZE(&footer); if ((rc = grn_ja_alloc(ctx, ja, id, sizeh + sizev + sizef, &einfo, &iw))) { goto exit; } - memcpy(iw.addr, GRN_BULK_HEAD(&header), sizeh); - if (body) { memcpy((char *)iw.addr + sizeh, GRN_BULK_HEAD(body), sizev); } - if (f) { memcpy((char *)iw.addr + sizeh + sizev, GRN_BULK_HEAD(&footer), sizef); } + grn_memcpy(iw.addr, GRN_BULK_HEAD(&header), sizeh); + if (body) { + grn_memcpy((char *)iw.addr + sizeh, GRN_BULK_HEAD(body), sizev); + } + if (f) { + grn_memcpy((char *)iw.addr + sizeh + sizev, GRN_BULK_HEAD(&footer), sizef); + } grn_io_win_unmap(&iw); rc = grn_ja_replace(ctx, ja, id, &einfo, NULL); } diff --git a/storage/mroonga/vendor/groonga/lib/str.c b/storage/mroonga/vendor/groonga/lib/str.c index f91b89c96c0..1bbe43a591c 100644 --- a/storage/mroonga/vendor/groonga/lib/str.c +++ b/storage/mroonga/vendor/groonga/lib/str.c @@ -27,6 +27,14 @@ #endif /* _ISOC99_SOURCE */ #include <math.h> +#if defined(HAVE__GMTIME64_S) && defined(__GNUC__) +# ifdef _WIN64 +# define gmtime_s(tm, time) _gmtime64_s(tm, time) +# else /* _WIN64 */ +# define gmtime_s(tm, time) _gmtime32_s(tm, time) +# endif /* _WIN64 */ +#endif /* defined(HAVE__GMTIME64_S) && defined(__GNUC__) */ + /* For Visual C++ 2010. Drop the code when we drop Visual C++ 2010 support. */ #if defined(_MSC_VER) && _MSC_VER < 1800 # define va_copy(destination, source) destination = source @@ -530,7 +538,7 @@ normalize_utf8(grn_ctx *ctx, grn_str *nstr) nstr->ctypes = ctypes; } } - memcpy(d, p, lp); + grn_memcpy(d, p, lp); d_ = d; d += lp; length++; @@ -1146,7 +1154,7 @@ grn_fakenstr_open(grn_ctx *ctx, const char *str, size_t str_len, grn_encoding en } nstr->orig = str; nstr->orig_blen = str_len; - memcpy(nstr->norm, str, str_len); + grn_memcpy(nstr->norm, str, str_len); nstr->norm[str_len] = '\0'; nstr->norm_blen = str_len; nstr->ctypes = NULL; @@ -1492,6 +1500,20 @@ grn_atoll(const char *nptr, const char *end, const char **rest) return n ? -v : v; } +uint64_t +grn_atoull(const char *nptr, const char *end, const char **rest) +{ + uint64_t v = 0, t; + while (nptr < end && *nptr >= '0' && *nptr <= '9') { + t = v * 10 + (*nptr - '0'); + if (t < v) { v = 0; break; } + v = t; + nptr++; + } + if (rest) { *rest = nptr; } + return v; +} + unsigned int grn_htoui(const char *nptr, const char *end, const char **rest) { @@ -1916,7 +1938,7 @@ grn_bulk_resize(grn_ctx *ctx, grn_obj *buf, unsigned int newsize) if (rounded_newsize < newsize) { return GRN_NOT_ENOUGH_SPACE; } newsize = rounded_newsize; if (!(head = GRN_MALLOC(newsize))) { return GRN_NO_MEMORY_AVAILABLE; } - memcpy(head, GRN_BULK_HEAD(buf), GRN_BULK_VSIZE(buf)); + grn_memcpy(head, GRN_BULK_HEAD(buf), GRN_BULK_VSIZE(buf)); buf->u.b.curr = head + grn_bulk_margin_size + GRN_BULK_VSIZE(buf); buf->u.b.head = head + grn_bulk_margin_size; buf->u.b.tail = head + newsize; @@ -1942,7 +1964,7 @@ grn_bulk_write(grn_ctx *ctx, grn_obj *buf, const char *str, unsigned int len) if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + len))) { return rc; } } curr = GRN_BULK_CURR(buf); - memcpy(curr, str, len); + grn_memcpy(curr, str, len); GRN_BULK_INCR_LEN(buf, len); return rc; } @@ -2074,26 +2096,30 @@ grn_text_ulltoa(grn_ctx *ctx, grn_obj *buf, unsigned long long int i) inline static void ftoa_(grn_ctx *ctx, grn_obj *buf, double d) { - char *curr; + char *start; + size_t before_size; size_t len; #define DIGIT_NUMBER 15 - grn_bulk_reserve(ctx, buf, DIGIT_NUMBER + 1); - curr = GRN_BULK_CURR(buf); - len = sprintf(curr, "%#.*g", DIGIT_NUMBER, d); +#define FIRST_BUFFER_SIZE (DIGIT_NUMBER + 4) + before_size = GRN_BULK_VSIZE(buf); + grn_bulk_reserve(ctx, buf, FIRST_BUFFER_SIZE); + grn_text_printf(ctx, buf, "%#.*g", DIGIT_NUMBER, d); + len = GRN_BULK_VSIZE(buf) - before_size; + start = GRN_BULK_CURR(buf) - len; +#undef FIRST_BUFFER_SIZE #undef DIGIT_NUMBER - if (curr[len - 1] == '.') { - GRN_BULK_INCR_LEN(buf, len); + if (start[len - 1] == '.') { GRN_TEXT_PUTC(ctx, buf, '0'); } else { char *p, *q; - curr[len] = '\0'; - if ((p = strchr(curr, 'e'))) { + start[len] = '\0'; + if ((p = strchr(start, 'e'))) { for (q = p; *(q - 2) != '.' && *(q - 1) == '0'; q--) { len--; } - memmove(q, p, curr + len - q); + grn_memmove(q, p, start + len - q); } else { - for (q = curr + len; *(q - 2) != '.' && *(q - 1) == '0'; q--) { len--; } + for (q = start + len; *(q - 2) != '.' && *(q - 1) == '0'; q--) { len--; } } - GRN_BULK_INCR_LEN(buf, len); + grn_bulk_truncate(ctx, buf, before_size + len); } } @@ -2491,9 +2517,11 @@ grn_text_printf(grn_ctx *ctx, grn_obj *bulk, const char *format, ...) grn_rc grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args) { - int rest_size, written_size; + grn_bool is_written = GRN_FALSE; + int written_size; { + int rest_size; va_list copied_args; rest_size = GRN_BULK_REST(bulk); @@ -2501,9 +2529,43 @@ grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args) written_size = vsnprintf(GRN_BULK_CURR(bulk), rest_size, format, copied_args); va_end(copied_args); + + if (written_size < rest_size) { + is_written = GRN_TRUE; + } } - if (written_size >= rest_size) { +#ifdef WIN32 + if (written_size == -1 && errno == ERANGE) { +# define N_NEW_SIZES 3 + int i; + int new_sizes[N_NEW_SIZES]; + + new_sizes[0] = GRN_BULK_REST(bulk) + strlen(format) * 2; + new_sizes[1] = new_sizes[0] + 4096; + new_sizes[2] = new_sizes[0] + 65536; + + for (i = 0; i < N_NEW_SIZES; i++) { + grn_rc rc; + int new_size = new_sizes[i]; + va_list copied_args; + + rc = grn_bulk_reserve(ctx, bulk, GRN_BULK_VSIZE(bulk) + new_size); + if (rc) { + return rc; + } + va_copy(copied_args, args); + written_size = vsnprintf(GRN_BULK_CURR(bulk), new_size, + format, copied_args); + va_end(copied_args); + if (written_size != -1) { + break; + } + } +# undef N_NEW_SIZES + } +#else /* WIN32 */ + if (!is_written) { grn_rc rc; int required_size = written_size + 1; /* "+ 1" for terminate '\0'. */ @@ -2514,6 +2576,7 @@ grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args) written_size = vsnprintf(GRN_BULK_CURR(bulk), required_size, format, args); } +#endif /* WIN32 */ if (written_size < 0) { return GRN_INVALID_ARGUMENT; @@ -3148,7 +3211,7 @@ grn_str_url_path_normalize(grn_ctx *ctx, const char *path, size_t path_len, } } if (be - b >= pc - p) { - memcpy(b, p, (pc - p)); + grn_memcpy(b, p, (pc - p)); b += pc - p; p = pc; if (p < pe && *pc == '/' && be > b) { diff --git a/storage/mroonga/vendor/groonga/lib/string.c b/storage/mroonga/vendor/groonga/lib/string.c index 132d51257ac..3249865b900 100644 --- a/storage/mroonga/vendor/groonga/lib/string.c +++ b/storage/mroonga/vendor/groonga/lib/string.c @@ -54,7 +54,7 @@ grn_fake_string_open(grn_ctx *ctx, grn_string *string) if (!grn_tokenizer_is_tokenized_delimiter(ctx, source_current, char_length, ctx->encoding)) { - memcpy(destination, source_current, char_length); + grn_memcpy(destination, source_current, char_length); destination += char_length; destination_length += char_length; } @@ -63,7 +63,7 @@ grn_fake_string_open(grn_ctx *ctx, grn_string *string) nstr->normalized[destination_length] = '\0'; nstr->normalized_length_in_bytes = destination_length; } else { - memcpy(nstr->normalized, str, str_len); + grn_memcpy(nstr->normalized, str, str_len); nstr->normalized[str_len] = '\0'; nstr->normalized_length_in_bytes = str_len; } @@ -140,8 +140,21 @@ grn_string_open_(grn_ctx *ctx, const char *str, unsigned int str_len, return NULL; } + is_normalizer_auto = (normalizer == GRN_NORMALIZER_AUTO); + if (is_normalizer_auto) { + normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1); + if (!normalizer) { + ERR(GRN_INVALID_ARGUMENT, + "[string][open] NormalizerAuto normalizer isn't available"); + return NULL; + } + } + string = GRN_MALLOCN(grn_string, 1); if (!string) { + if (is_normalizer_auto) { + grn_obj_unlink(ctx, normalizer); + } GRN_LOG(ctx, GRN_LOG_ALERT, "[string][open] failed to allocate memory"); return NULL; @@ -163,12 +176,6 @@ grn_string_open_(grn_ctx *ctx, const char *str, unsigned int str_len, return (grn_obj *)grn_fake_string_open(ctx, string); } - is_normalizer_auto = (normalizer == GRN_NORMALIZER_AUTO); - if (is_normalizer_auto) { - normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1); - } - - /* TODO: check rc */ grn_normalizer_normalize(ctx, normalizer, (grn_obj *)string); if (ctx->rc) { grn_obj_close(ctx, obj); diff --git a/storage/mroonga/vendor/groonga/lib/token_cursor.c b/storage/mroonga/vendor/groonga/lib/token_cursor.c index d3e2e2d8523..d98d1d46342 100644 --- a/storage/mroonga/vendor/groonga/lib/token_cursor.c +++ b/storage/mroonga/vendor/groonga/lib/token_cursor.c @@ -216,15 +216,17 @@ grn_token_cursor_next(grn_ctx *ctx, grn_token_cursor *token_cursor) token_cursor->force_prefix = GRN_TRUE; } if (token_cursor->curr_size == 0) { - char tokenizer_name[GRN_TABLE_MAX_KEY_SIZE]; - int tokenizer_name_length; - tokenizer_name_length = - grn_obj_name(ctx, token_cursor->tokenizer, - tokenizer_name, GRN_TABLE_MAX_KEY_SIZE); - GRN_LOG(ctx, GRN_WARN, - "[token_next] ignore an empty token: <%.*s>: <%.*s>", - tokenizer_name_length, tokenizer_name, - token_cursor->orig_blen, token_cursor->orig); + if (token_cursor->status != GRN_TOKEN_CURSOR_DONE) { + char tokenizer_name[GRN_TABLE_MAX_KEY_SIZE]; + int tokenizer_name_length; + tokenizer_name_length = + grn_obj_name(ctx, token_cursor->tokenizer, + tokenizer_name, GRN_TABLE_MAX_KEY_SIZE); + GRN_LOG(ctx, GRN_WARN, + "[token_next] ignore an empty token: <%.*s>: <%.*s>", + tokenizer_name_length, tokenizer_name, + token_cursor->orig_blen, token_cursor->orig); + } continue; } if (token_cursor->curr_size > GRN_TABLE_MAX_KEY_SIZE) { diff --git a/storage/mroonga/vendor/groonga/lib/tokenizer.c b/storage/mroonga/vendor/groonga/lib/tokenizer.c index ef9eb5bf7b5..e72d3b43d2b 100644 --- a/storage/mroonga/vendor/groonga/lib/tokenizer.c +++ b/storage/mroonga/vendor/groonga/lib/tokenizer.c @@ -167,7 +167,7 @@ grn_tokenizer_query_open(grn_ctx *ctx, int num_args, grn_obj **args, return NULL; } query->normalized_query = normalized_query; - memcpy(query_buf, GRN_TEXT_VALUE(query_str), query_length); + grn_memcpy(query_buf, GRN_TEXT_VALUE(query_str), query_length); query_buf[query_length] = '\0'; query->query_buf = query_buf; query->ptr = query_buf; diff --git a/storage/mroonga/vendor/groonga/lib/tokenizers.c b/storage/mroonga/vendor/groonga/lib/tokenizers.c index 3f6df15a690..8ed0b8c37fa 100644 --- a/storage/mroonga/vendor/groonga/lib/tokenizers.c +++ b/storage/mroonga/vendor/groonga/lib/tokenizers.c @@ -1,6 +1,6 @@ /* -*- 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 @@ -467,6 +467,260 @@ ngram_fin(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) return NULL; } +/* regexp tokenizer */ + +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_overlapping; + const char *next; + const char *end; + 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; + grn_tokenizer_query *query; + const char *normalized; + unsigned int normalized_length_in_bytes; + grn_regexp_tokenizer *tokenizer; + + query = grn_tokenizer_query_open(ctx, nargs, args, normalize_flags); + if (!query) { + return NULL; + } + + tokenizer = GRN_MALLOC(sizeof(grn_regexp_tokenizer)); + if (!tokenizer) { + grn_tokenizer_query_close(ctx, query); + ERR(GRN_NO_MEMORY_AVAILABLE, + "[tokenizer][regexp] failed to allocate memory"); + return NULL; + } + user_data->ptr = tokenizer; + + 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_overlapping = GRN_FALSE; + + grn_string_get_normalized(ctx, tokenizer->query->normalized_query, + &normalized, &normalized_length_in_bytes, + 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); + } + } + } + + GRN_TEXT_INIT(&(tokenizer->buffer), 0); + + return NULL; +} + +static grn_obj * +regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) +{ + int char_len; + grn_token_status status = 0; + grn_regexp_tokenizer *tokenizer = user_data->ptr; + unsigned int n_characters = 0; + int ngram_unit = 2; + grn_obj *buffer = &(tokenizer->buffer); + const char *current = tokenizer->next; + const char *end = tokenizer->end; + grn_tokenize_mode mode = tokenizer->query->tokenize_mode; + grn_bool escaping = GRN_FALSE; + + GRN_BULK_REWIND(buffer); + + if (mode == GRN_TOKEN_GET) { + if (tokenizer->get.have_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) { + status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; + grn_tokenizer_token_push(ctx, + &(tokenizer->token), + GRN_TOKENIZER_END_MARK_UTF8, + GRN_TOKENIZER_END_MARK_UTF8_LEN, + status); + return NULL; + } + } else { + if (tokenizer->is_begin) { + 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) { + status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END; + grn_tokenizer_token_push(ctx, + &(tokenizer->token), + GRN_TOKENIZER_END_MARK_UTF8, + GRN_TOKENIZER_END_MARK_UTF8_LEN, + 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; + } + + 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; + } + } + + char_len = grn_charlen_(ctx, (const char *)current, (const char *)end, + tokenizer->query->encoding); + if (char_len == 0) { + break; + } + } + + if (tokenizer->is_overlapping) { + status |= GRN_TOKEN_OVERLAP; + } + if (n_characters < ngram_unit) { + status |= GRN_TOKEN_UNMATURED; + } + 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; + } + } + } else { + if (tokenizer->get.n_skip_tokens > 0) { + tokenizer->get.n_skip_tokens--; + status |= GRN_TOKEN_SKIP; + } else { + tokenizer->get.n_skip_tokens = ngram_unit - 1; + } + } + } else { + if (tokenizer->next == end) { + tokenizer->is_end = GRN_TRUE; + } + } + + grn_tokenizer_token_push(ctx, + &(tokenizer->token), + GRN_TEXT_VALUE(buffer), + GRN_TEXT_LEN(buffer), + status); + tokenizer->is_first_token = GRN_FALSE; + + return NULL; +} + +static grn_obj * +regexp_fin(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) +{ + grn_regexp_tokenizer *tokenizer = user_data->ptr; + if (!tokenizer) { + return NULL; + } + grn_tokenizer_token_fin(ctx, &(tokenizer->token)); + grn_tokenizer_query_close(ctx, tokenizer->query); + GRN_OBJ_FIN(ctx, &(tokenizer->buffer)); + GRN_FREE(tokenizer); + return NULL; +} + /* external */ grn_rc @@ -560,5 +814,7 @@ grn_db_init_builtin_tokenizers(grn_ctx *ctx) bigramisad_init, ngram_next, ngram_fin, vars); DEF_TOKENIZER("TokenDelimitNull", delimit_null_init, delimited_next, delimited_fin, vars); + DEF_TOKENIZER("TokenRegexp", + regexp_init, regexp_next, regexp_fin, vars); return GRN_SUCCESS; } diff --git a/storage/mroonga/vendor/groonga/lib/util.c b/storage/mroonga/vendor/groonga/lib/util.c index dd703b53928..17172d6cfeb 100644 --- a/storage/mroonga/vendor/groonga/lib/util.c +++ b/storage/mroonga/vendor/groonga/lib/util.c @@ -20,9 +20,18 @@ #include "grn_ii.h" #include "grn_util.h" #include "grn_string.h" +#include "grn_expr.h" #include <string.h> #include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/stat.h> + +#ifdef WIN32 +# include <io.h> +# include <share.h> +#endif /* WIN32 */ grn_rc grn_normalize_offset_and_limit(grn_ctx *ctx, int size, int *p_offset, int *p_limit) @@ -211,8 +220,13 @@ grn_inspect_type(grn_ctx *ctx, grn_obj *buf, unsigned char type) break; default: { - char type_in_hex[5]; /* "0xXX" */ - sprintf(type_in_hex, "%#02x", type); +#define TYPE_IN_HEX_SIZE 5 /* "0xXX" */ + char type_in_hex[TYPE_IN_HEX_SIZE]; + grn_snprintf(type_in_hex, + TYPE_IN_HEX_SIZE, + TYPE_IN_HEX_SIZE, + "%#02x", type); +#undef TYPE_IN_HEX_SIZE GRN_TEXT_PUTS(ctx, buf, "(unknown: "); GRN_TEXT_PUTS(ctx, buf, type_in_hex); GRN_TEXT_PUTS(ctx, buf, ")"); @@ -279,6 +293,36 @@ grn_proc_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj) } grn_rc +grn_expr_code_inspect_indented(grn_ctx *ctx, + grn_obj *buffer, + grn_expr_code *code, + const char *indent) +{ + if (!code) { + GRN_TEXT_PUTS(ctx, buffer, "(NULL)"); + return GRN_SUCCESS; + } + + GRN_TEXT_PUTS(ctx, buffer, "<"); + GRN_TEXT_PUTS(ctx, buffer, grn_operator_to_string(code->op)); + GRN_TEXT_PUTS(ctx, buffer, " "); + GRN_TEXT_PUTS(ctx, buffer, "n_args:"); + grn_text_itoa(ctx, buffer, code->nargs); + GRN_TEXT_PUTS(ctx, buffer, ", "); + GRN_TEXT_PUTS(ctx, buffer, "flags:"); + grn_text_itoh(ctx, buffer, code->flags, 1); + GRN_TEXT_PUTS(ctx, buffer, ", "); + GRN_TEXT_PUTS(ctx, buffer, "modify:"); + grn_text_itoa(ctx, buffer, code->modify); + GRN_TEXT_PUTS(ctx, buffer, ", "); + GRN_TEXT_PUTS(ctx, buffer, "value:"); + grn_inspect_indented(ctx, buffer, code->value, " "); + GRN_TEXT_PUTS(ctx, buffer, ">"); + + return GRN_SUCCESS; +} + +grn_rc grn_expr_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *expr) { grn_expr *e = (grn_expr *)expr; @@ -305,33 +349,15 @@ grn_expr_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *expr) } { - uint32_t i, j; - grn_expr_var *var; + uint32_t i; grn_expr_code *code; GRN_TEXT_PUTS(ctx, buffer, "\n codes:{"); - for (j = 0, code = e->codes; j < e->codes_curr; j++, code++) { - if (j) { GRN_TEXT_PUTC(ctx, buffer, ','); } + for (i = 0, code = e->codes; i < e->codes_curr; i++, code++) { + if (i) { GRN_TEXT_PUTC(ctx, buffer, ','); } GRN_TEXT_PUTS(ctx, buffer, "\n "); - grn_text_itoa(ctx, buffer, j); - GRN_TEXT_PUTS(ctx, buffer, ":<"); - GRN_TEXT_PUTS(ctx, buffer, grn_operator_to_string(code->op)); - GRN_TEXT_PUTS(ctx, buffer, "("); - for (i = 0, var = e->vars; i < e->nvars; i++, var++) { - if (i) { GRN_TEXT_PUTC(ctx, buffer, ','); } - GRN_TEXT_PUTC(ctx, buffer, '?'); - if (var->name_size) { - GRN_TEXT_PUT(ctx, buffer, var->name, var->name_size); - } else { - grn_text_itoa(ctx, buffer, (int)i); - } - } - GRN_TEXT_PUTS(ctx, buffer, "), "); - GRN_TEXT_PUTS(ctx, buffer, "modify:"); - grn_text_itoa(ctx, buffer, code->modify); - GRN_TEXT_PUTS(ctx, buffer, ", "); - GRN_TEXT_PUTS(ctx, buffer, "value:"); - grn_inspect_indented(ctx, buffer, code->value, " "); - GRN_TEXT_PUTS(ctx, buffer, ">"); + grn_text_itoa(ctx, buffer, i); + GRN_TEXT_PUTS(ctx, buffer, ":"); + grn_expr_code_inspect_indented(ctx, buffer, code, " "); } GRN_TEXT_PUTS(ctx, buffer, "\n }"); } @@ -1256,6 +1282,17 @@ grn_p_ii_values(grn_ctx *ctx, grn_obj *ii) grn_obj_unlink(ctx, &buffer); } +void +grn_p_expr_code(grn_ctx *ctx, grn_expr_code *code) +{ + grn_obj buffer; + + GRN_TEXT_INIT(&buffer, 0); + grn_expr_code_inspect_indented(ctx, &buffer, code, ""); + printf("%.*s\n", (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer)); + grn_obj_unlink(ctx, &buffer); +} + #ifdef WIN32 static char *win32_base_dir = NULL; const char * @@ -1271,7 +1308,7 @@ grn_win32_base_dir(void) absolute_dll_filename, MAX_PATH); if (absolute_dll_filename_size == 0) { - win32_base_dir = strdup("."); + win32_base_dir = grn_strdup_raw("."); } else { DWORD ansi_dll_filename_size; ansi_dll_filename_size = @@ -1279,7 +1316,7 @@ grn_win32_base_dir(void) absolute_dll_filename, absolute_dll_filename_size, NULL, 0, NULL, NULL); if (ansi_dll_filename_size == 0) { - win32_base_dir = strdup("."); + win32_base_dir = grn_strdup_raw("."); } else { char *path; win32_base_dir = malloc(ansi_dll_filename_size + 1); @@ -1310,3 +1347,41 @@ grn_win32_base_dir(void) return win32_base_dir; } #endif + +#ifdef WIN32 +int +grn_mkstemp(char *path_template) +{ + errno_t error; + size_t path_template_size; + int fd; + + path_template_size = strlen(path_template) + 1; + error = _mktemp_s(path_template, path_template_size); + if (error != 0) { + return -1; + } + + error = _sopen_s(&fd, + path_template, + _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY, + _SH_DENYNO, + _S_IREAD | _S_IWRITE); + if (error != 0) { + return -1; + } + + return fd; +} +#else /* WIN32 */ +int +grn_mkstemp(char *path_template) +{ +# ifdef HAVE_MKSTEMP + return mkstemp(path_template); +# else /* HAVE_MKSTEMP */ + mktemp(path_template); + return open(path_template, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); +# endif /* HAVE_MKSTEMP */ +} +#endif /* WIN32 */ |