MRN_API my_bool mroonga_escape_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { EscapeInfo *info = NULL; initid->ptr = NULL; if (!(1 <= args->arg_count && args->arg_count <= 2)) { sprintf(message, "mroonga_escape(): Incorrect number of arguments: %u for 1..2", args->arg_count); goto error; } if (args->arg_type[0] != STRING_RESULT) { strcpy(message, "mroonga_escape(): The 1st argument must be query as string"); goto error; } if (args->arg_count == 2) { if (args->arg_type[1] != STRING_RESULT) { strcpy(message, "mroonga_escape(): " "The 2st argument must be escape target characters as string"); goto error; } } initid->maybe_null = 1; initid->const_item = 0; info = (EscapeInfo *)mrn_my_malloc(sizeof(EscapeInfo), MYF(MY_WME | MY_ZEROFILL)); if (!info) { strcpy(message, "mroonga_escape(): out of memory"); goto error; } grn_ctx_init(&(info->ctx), 0); GRN_TEXT_INIT(&(info->target_characters), 0); GRN_TEXT_INIT(&(info->escaped_query), 0); initid->ptr = (char *)info; return FALSE; error: if (info) { grn_ctx_fin(&(info->ctx)); my_free(info); } return TRUE; }
MRN_API my_bool mroonga_normalize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { st_mrn_normalize_info *info = NULL; String *result_str = NULL; initid->ptr = NULL; if (!(1 <= args->arg_count && args->arg_count <= 2)) { sprintf(message, "mroonga_normalize(): Incorrect number of arguments: %u for 1..2", args->arg_count); goto error; } if (args->arg_type[0] != STRING_RESULT) { strcpy(message, "mroonga_normalize(): The 1st argument must be query as string"); goto error; } if (args->arg_count == 2) { if (args->arg_type[1] != STRING_RESULT) { strcpy(message, "mroonga_normalize(): " "The 2st argument must be normalizer name as string"); goto error; } } initid->maybe_null = 1; info = (st_mrn_normalize_info *)mrn_my_malloc(sizeof(st_mrn_normalize_info), MYF(MY_WME | MY_ZEROFILL)); if (!info) { strcpy(message, "mroonga_normalize(): out of memory"); goto error; } info->ctx = mrn_context_pool->pull(); { const char *current_db_path = MRN_THD_DB_PATH(current_thd); const char *action; if (current_db_path) { action = "open database"; mrn::Database *db; int error = mrn_db_manager->open(current_db_path, &db); if (error == 0) { info->db = db->get(); grn_ctx_use(info->ctx, info->db); info->use_shared_db = true; } } else { action = "create anonymous database"; info->db = grn_db_create(info->ctx, NULL, NULL); info->use_shared_db = false; } if (!info->db) { sprintf(message, "mroonga_normalize(): failed to %s: %s", action, info->ctx->errbuf); goto error; } } if (args->arg_count == 1) { info->normalizer = grn_ctx_get(info->ctx, DEFAULT_NORMALIZER_NAME, -1); } else { info->normalizer = grn_ctx_get(info->ctx, args->args[1], args->lengths[1]); } if (!info->normalizer) { sprintf(message, "mroonga_normalize(): nonexistent normalizer %.*s", (int)args->lengths[1], args->args[1]); goto error; } info->flags = 0; result_str = &(info->result_str); mrn::encoding::set_raw(info->ctx, system_charset_info); result_str->set_charset(system_charset_info); initid->ptr = (char *)info; return FALSE; error: if (info) { if (!info->use_shared_db) { grn_obj_close(info->ctx, info->db); } mrn_context_pool->release(info->ctx); my_free(info); } return TRUE; }
MRN_API mrn_bool mroonga_snippet_html_init(UDF_INIT *init, UDF_ARGS *args, char *message) { MRN_DBUG_ENTER_FUNCTION(); mrn_snippet_html_info *info = NULL; init->ptr = NULL; if (args->arg_count < 1) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): wrong number of arguments: %u for 1+", args->arg_count); goto error; } for (unsigned int i = 0; i < args->arg_count; ++i) { switch (args->arg_type[i]) { case STRING_RESULT: /* OK */ break; case REAL_RESULT: snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): all arguments must be string: " "<%u>=<%g>", i, *((double *)(args->args[i]))); goto error; break; case INT_RESULT: snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): all arguments must be string: " "<%u>=<%lld>", i, *((longlong *)(args->args[i]))); goto error; break; default: snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): all arguments must be string: <%u>", i); goto error; break; } } init->maybe_null = 1; info = (mrn_snippet_html_info *)mrn_my_malloc(sizeof(mrn_snippet_html_info), MYF(MY_WME | MY_ZEROFILL)); if (!info) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): failed to allocate memory"); goto error; } info->ctx = mrn_context_pool->pull(); { const char *current_db_path = MRN_THD_DB_PATH(current_thd); const char *action; if (current_db_path) { action = "open database"; mrn::Database *db; int error = mrn_db_manager->open(current_db_path, &db); if (error == 0) { info->db = db->get(); grn_ctx_use(info->ctx, info->db); info->use_shared_db = true; } } else { action = "create anonymous database"; info->db = grn_db_create(info->ctx, NULL, NULL); info->use_shared_db = false; } if (!info->db) { sprintf(message, "mroonga_snippet_html(): failed to %s: %s", action, info->ctx->errbuf); goto error; } } info->query_mode.used = false; if (args->arg_count == 2 && args->attribute_lengths[1] == strlen("query") && strncmp(args->attributes[1], "query", strlen("query")) == 0) { info->query_mode.used = true; info->query_mode.table = NULL; info->query_mode.default_column = NULL; } { bool all_keywords_are_constant = true; for (unsigned int i = 1; i < args->arg_count; ++i) { if (!args->args[i]) { all_keywords_are_constant = false; break; } } if (all_keywords_are_constant) { if (mrn_snippet_html_prepare(info, args, message, &(info->snippet))) { goto error; } } else { info->snippet = NULL; } } init->ptr = (char *)info; DBUG_RETURN(false); error: if (info) { if (!info->use_shared_db) { grn_obj_close(info->ctx, info->db); } mrn_context_pool->release(info->ctx); my_free(info); } DBUG_RETURN(true); }
static char *mrn_get_string_between_quote(const char *ptr) { const char *start_ptr, *end_ptr, *tmp_ptr, *esc_ptr; bool find_flg = FALSE, esc_flg = FALSE; MRN_DBUG_ENTER_FUNCTION(); start_ptr = strchr(ptr, '\''); end_ptr = strchr(ptr, '"'); if (start_ptr && (!end_ptr || start_ptr < end_ptr)) { tmp_ptr = ++start_ptr; while (!find_flg) { if (!(end_ptr = strchr(tmp_ptr, '\''))) DBUG_RETURN(NULL); esc_ptr = tmp_ptr; while (!find_flg) { esc_ptr = strchr(esc_ptr, '\\'); if (!esc_ptr || esc_ptr > end_ptr) find_flg = TRUE; else if (esc_ptr == end_ptr - 1) { esc_flg = TRUE; tmp_ptr = end_ptr + 1; break; } else { esc_flg = TRUE; esc_ptr += 2; } } } } else if (end_ptr) { start_ptr = end_ptr; tmp_ptr = ++start_ptr; while (!find_flg) { if (!(end_ptr = strchr(tmp_ptr, '"'))) DBUG_RETURN(NULL); esc_ptr = tmp_ptr; while (!find_flg) { esc_ptr = strchr(esc_ptr, '\\'); if (!esc_ptr || esc_ptr > end_ptr) find_flg = TRUE; else if (esc_ptr == end_ptr - 1) { esc_flg = TRUE; tmp_ptr = end_ptr + 1; break; } else { esc_flg = TRUE; esc_ptr += 2; } } } } else DBUG_RETURN(NULL); size_t length = end_ptr - start_ptr; char *extracted_string = (char *)mrn_my_malloc(length + 1, MYF(MY_WME)); if (esc_flg) { size_t extracted_index = 0; const char *current_ptr = start_ptr; while (current_ptr < end_ptr) { if (*current_ptr != '\\') { extracted_string[extracted_index] = *current_ptr; ++extracted_index; current_ptr++; continue; } if (current_ptr + 1 == end_ptr) { break; } switch (*(current_ptr + 1)) { case 'b': extracted_string[extracted_index] = '\b'; break; case 'n': extracted_string[extracted_index] = '\n'; break; case 'r': extracted_string[extracted_index] = '\r'; break; case 't': extracted_string[extracted_index] = '\t'; break; default: extracted_string[extracted_index] = *(current_ptr + 1); break; } ++extracted_index; } } else { memcpy(extracted_string, start_ptr, length); extracted_string[length] = '\0'; } DBUG_RETURN(extracted_string); }
MRN_API mrn_bool mroonga_query_expand_init(UDF_INIT *init, UDF_ARGS *args, char *message) { mrn::QueryExpandInfo *info = NULL; MRN_DBUG_ENTER_FUNCTION(); init->ptr = NULL; if (args->arg_count != 4) { sprintf(message, "mroonga_query_expand(): wrong number of arguments: %u for 4", args->arg_count); goto error; } if (args->arg_type[0] != STRING_RESULT) { strcpy(message, "mroonga_query_expand(): " "the 1st argument must be table name as string"); goto error; } if (args->arg_type[1] != STRING_RESULT) { strcpy(message, "mroonga_query_expand(): " "the 2nd argument must be term column name as string"); goto error; } if (args->arg_type[2] != STRING_RESULT) { strcpy(message, "mroonga_query_expand(): " "the 3nd argument must be expanded term column name as string"); goto error; } if (args->arg_type[3] != STRING_RESULT) { strcpy(message, "mroonga_query_expand(): " "the 4th argument must be query as string"); goto error; } init->maybe_null = 1; info = static_cast<mrn::QueryExpandInfo *>( mrn_my_malloc(sizeof(mrn::QueryExpandInfo), MYF(MY_WME | MY_ZEROFILL))); if (!info) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): failed to allocate memory"); goto error; } { const char *current_db_path = MRN_THD_DB_PATH(current_thd); if (!current_db_path) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): no current database"); goto error; } mrn::Database *db; int error = mrn_db_manager->open(current_db_path, &db); if (error != 0) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): failed to open database: %s", mrn_db_manager->error_message()); goto error; } info->ctx = mrn_context_pool->pull(); grn_ctx_use(info->ctx, db->get()); } GRN_TEXT_INIT(&(info->expanded_query), 0); { const char *table_name = args->args[0]; unsigned int table_name_length = args->lengths[0]; grn_obj *table = grn_ctx_get(info->ctx, table_name, table_name_length); if (!table) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): table doesn't exist: <%.*s>", static_cast<int>(table_name_length), table_name); goto error; } const char *term_column_name = args->args[1]; unsigned int term_column_name_length = args->lengths[1]; info->term_column = grn_obj_column(info->ctx, table, term_column_name, term_column_name_length); if (!info->term_column) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): term column doesn't exist: <%.*s.%.*s>", static_cast<int>(table_name_length), table_name, static_cast<int>(term_column_name_length), term_column_name); goto error; } const char *expanded_term_column_name = args->args[2]; unsigned int expanded_term_column_name_length = args->lengths[2]; info->expanded_term_column = grn_obj_column(info->ctx, table, expanded_term_column_name, expanded_term_column_name_length); if (!info->expanded_term_column) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): " "expanded term column doesn't exist: <%.*s.%.*s>", static_cast<int>(table_name_length), table_name, static_cast<int>(expanded_term_column_name_length), expanded_term_column_name); goto error; } } init->ptr = reinterpret_cast<char *>(info); DBUG_RETURN(false); error: mrn_query_expand_info_free(info); DBUG_RETURN(true); }
MRN_API my_bool mroonga_command_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { CommandInfo *info = NULL; initid->ptr = NULL; if (args->arg_count != 1) { sprintf(message, "mroonga_command(): Incorrect number of arguments: %u for 1", args->arg_count); goto error; } if (args->arg_type[0] != STRING_RESULT) { strcpy(message, "mroonga_command(): The 1st argument must be command as string"); goto error; } initid->maybe_null = 1; initid->const_item = 0; info = (CommandInfo *)mrn_my_malloc(sizeof(CommandInfo), MYF(MY_WME | MY_ZEROFILL)); if (!info) { strcpy(message, "mroonga_command(): out of memory"); goto error; } info->ctx = mrn_context_pool->pull(); { const char *current_db_path = MRN_THD_DB_PATH(current_thd); const char *action; if (current_db_path) { action = "open database"; mrn::Database *db; int error = mrn_db_manager->open(current_db_path, &db); if (error == 0) { info->db= db->get(); grn_ctx_use(info->ctx, info->db); info->use_shared_db = true; } } else { action = "create anonymous database"; info->db = grn_db_create(info->ctx, NULL, NULL); info->use_shared_db = false; } if (!info->db) { sprintf(message, "mroonga_command(): failed to %s: %s", action, info->ctx->errbuf); goto error; } } initid->ptr = (char *)info; return FALSE; error: if (info) { if (!info->use_shared_db) { grn_obj_close(info->ctx, info->db); } mrn_context_pool->release(info->ctx); my_free(info); } return TRUE; }