diff options
Diffstat (limited to 'storage/mroonga/vendor/groonga/lib/proc.c')
-rw-r--r-- | storage/mroonga/vendor/groonga/lib/proc.c | 317 |
1 files changed, 276 insertions, 41 deletions
diff --git a/storage/mroonga/vendor/groonga/lib/proc.c b/storage/mroonga/vendor/groonga/lib/proc.c index e1473472f55..37b7ae67d35 100644 --- a/storage/mroonga/vendor/groonga/lib/proc.c +++ b/storage/mroonga/vendor/groonga/lib/proc.c @@ -1102,6 +1102,12 @@ grn_parse_column_create_flags(grn_ctx *ctx, const char *nptr, const char *end) } else if (!memcmp(nptr, "COLUMN_INDEX", 12)) { flags |= GRN_OBJ_COLUMN_INDEX; nptr += 12; + } else if (!memcmp(nptr, "COMPRESS_ZLIB", 13)) { + flags |= GRN_OBJ_COMPRESS_ZLIB; + nptr += 13; + } else if (!memcmp(nptr, "COMPRESS_LZO", 12)) { + flags |= GRN_OBJ_COMPRESS_LZO; + nptr += 12; } else if (!memcmp(nptr, "WITH_SECTION", 12)) { flags |= GRN_OBJ_WITH_SECTION; nptr += 12; @@ -1194,6 +1200,116 @@ grn_column_create_flags_to_text(grn_ctx *ctx, grn_obj *buf, grn_obj_flags flags) } } +static grn_bool +proc_table_create_set_token_filters_put(grn_ctx *ctx, + grn_obj *token_filters, + const char *token_filter_name, + int token_filter_name_length) +{ + grn_obj *token_filter; + + token_filter = grn_ctx_get(ctx, + token_filter_name, + token_filter_name_length); + if (token_filter) { + GRN_PTR_PUT(ctx, token_filters, token_filter); + return GRN_TRUE; + } else { + ERR(GRN_INVALID_ARGUMENT, + "[table][create][token-filter] nonexistent token filter: <%.*s>", + token_filter_name_length, token_filter_name); + return GRN_FALSE; + } +} + +static grn_bool +proc_table_create_set_token_filters_fill(grn_ctx *ctx, + grn_obj *token_filters, + grn_obj *token_filter_names) +{ + const char *start, *current, *end; + const char *name_start, *name_end; + const char *last_name_end; + + start = GRN_TEXT_VALUE(token_filter_names); + end = start + GRN_TEXT_LEN(token_filter_names); + current = start; + name_start = NULL; + name_end = NULL; + last_name_end = start; + while (current < end) { + switch (current[0]) { + case ' ' : + if (name_start && !name_end) { + name_end = current; + } + break; + case ',' : + if (!name_start) { + goto break_loop; + } + if (!name_end) { + name_end = current; + } + proc_table_create_set_token_filters_put(ctx, + token_filters, + name_start, + name_end - name_start); + last_name_end = name_end + 1; + name_start = NULL; + name_end = NULL; + break; + default : + if (!name_start) { + name_start = current; + } + break; + } + current++; + } + +break_loop: + if (!name_start) { + ERR(GRN_INVALID_ARGUMENT, + "[table][create][token-filter] empty token filter name: " + "<%.*s|%.*s|%.*s>", + (int)(last_name_end - start), start, + (int)(current - last_name_end), last_name_end, + (int)(end - current), current); + return GRN_FALSE; + } + + if (!name_end) { + name_end = current; + } + proc_table_create_set_token_filters_put(ctx, + token_filters, + name_start, + name_end - name_start); + + return GRN_TRUE; +} + +static void +proc_table_create_set_token_filters(grn_ctx *ctx, + grn_obj *table, + grn_obj *token_filter_names) +{ + grn_obj token_filters; + + if (GRN_TEXT_LEN(token_filter_names) == 0) { + return; + } + + GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, 0); + if (proc_table_create_set_token_filters_fill(ctx, + &token_filters, + token_filter_names)) { + grn_obj_set_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters); + } + grn_obj_unlink(ctx, &token_filters); +} + static grn_obj * proc_table_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { @@ -1251,6 +1367,7 @@ proc_table_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_d GRN_TEXT_VALUE(normalizer_name), GRN_TEXT_LEN(normalizer_name))); } + proc_table_create_set_token_filters(ctx, table, VAR(6)); grn_obj_unlink(ctx, table); } } else { @@ -1316,9 +1433,104 @@ exit: return NULL; } +static grn_rc +proc_column_create_resolve_source_name(grn_ctx *ctx, + grn_obj *table, + const char *source_name, + int source_name_length, + grn_obj *source_ids) +{ + grn_obj *column; + + column = grn_obj_column(ctx, table, source_name, source_name_length); + if (!column) { + ERR(GRN_INVALID_ARGUMENT, + "[column][create] nonexistent source: <%.*s>", + source_name_length, source_name); + return ctx->rc; + } + + if (column->header.type == GRN_ACCESSOR) { + if (strncmp(source_name, "_key", source_name_length) == 0) { + grn_id source_id = grn_obj_id(ctx, table); + GRN_UINT32_PUT(ctx, source_ids, source_id); + } else { + ERR(GRN_INVALID_ARGUMENT, + "[column][create] pseudo column except <_key> is invalid: <%.*s>", + source_name_length, source_name); + } + } else { + grn_id source_id = grn_obj_id(ctx, column); + GRN_UINT32_PUT(ctx, source_ids, source_id); + } + grn_obj_unlink(ctx, column); + + return ctx->rc; +} + +static grn_rc +proc_column_create_resolve_source_names(grn_ctx *ctx, + grn_obj *table, + grn_obj *source_names, + grn_obj *source_ids) +{ + int i, names_length; + int start, source_name_length; + const char *names; + + names = GRN_TEXT_VALUE(source_names); + start = 0; + source_name_length = 0; + names_length = GRN_TEXT_LEN(source_names); + for (i = 0; i < names_length; i++) { + switch (names[i]) { + case ' ' : + if (source_name_length == 0) { + start++; + } + break; + case ',' : + { + grn_rc rc; + const char *source_name = names + start; + rc = proc_column_create_resolve_source_name(ctx, + table, + source_name, + source_name_length, + source_ids); + if (rc) { + return rc; + } + start = i + 1; + source_name_length = 0; + } + break; + default : + source_name_length++; + break; + } + } + + if (source_name_length > 0) { + grn_rc rc; + const char *source_name = names + start; + rc = proc_column_create_resolve_source_name(ctx, + table, + source_name, + source_name_length, + source_ids); + if (rc) { + return rc; + } + } + + return GRN_SUCCESS; +} + static grn_obj * proc_column_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { + grn_bool succeeded = GRN_TRUE; grn_obj *column, *table = NULL, *type = NULL; const char *rest; grn_obj_flags flags = grn_atoi(GRN_TEXT_VALUE(VAR(2)), @@ -1326,13 +1538,17 @@ proc_column_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_ if (GRN_TEXT_VALUE(VAR(2)) == rest) { flags = grn_parse_column_create_flags(ctx, GRN_TEXT_VALUE(VAR(2)), GRN_BULK_CURR(VAR(2))); - if (ctx->rc) { goto exit; } + if (ctx->rc) { + succeeded = GRN_FALSE; + goto exit; + } } table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0))); if (!table) { ERR(GRN_INVALID_ARGUMENT, "[column][create] table doesn't exist: <%.*s>", (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0))); + succeeded = GRN_FALSE; goto exit; } type = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(3)), @@ -1341,12 +1557,14 @@ proc_column_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_ ERR(GRN_INVALID_ARGUMENT, "[column][create] type doesn't exist: <%.*s>", (int)GRN_TEXT_LEN(VAR(3)), GRN_TEXT_VALUE(VAR(3))) ; + succeeded = GRN_FALSE; goto exit; } if (GRN_TEXT_LEN(VAR(1))) { flags |= GRN_OBJ_PERSISTENT; } else { ERR(GRN_INVALID_ARGUMENT, "[column][create] name is missing"); + succeeded = GRN_FALSE; goto exit; } column = grn_column_create(ctx, table, @@ -1355,36 +1573,30 @@ proc_column_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_ NULL, flags, type); if (column) { if (GRN_TEXT_LEN(VAR(4))) { - grn_obj sources, source_ids, **p, **pe; - GRN_PTR_INIT(&sources, GRN_OBJ_VECTOR, GRN_ID_NIL); + grn_rc rc; + grn_obj source_ids; GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR); - grn_obj_columns(ctx, type, - GRN_TEXT_VALUE(VAR(4)), - GRN_TEXT_LEN(VAR(4)), - &sources); - p = (grn_obj **)GRN_BULK_HEAD(&sources); - pe = (grn_obj **)GRN_BULK_CURR(&sources); - for (; p < pe; p++) { - grn_id source_id = grn_obj_id(ctx, *p); - if ((*p)->header.type == GRN_ACCESSOR) { - /* todo : if "_key" assigned */ - source_id = grn_obj_id(ctx, type); - } - if (source_id) { - GRN_UINT32_PUT(ctx, &source_ids, source_id); - } - grn_obj_unlink(ctx, *p); - } - if (GRN_BULK_VSIZE(&source_ids)) { + rc = proc_column_create_resolve_source_names(ctx, + type, + VAR(4), + &source_ids); + if (!rc && GRN_BULK_VSIZE(&source_ids)) { grn_obj_set_info(ctx, column, GRN_INFO_SOURCE, &source_ids); + rc = ctx->rc; } GRN_OBJ_FIN(ctx, &source_ids); - GRN_OBJ_FIN(ctx, &sources); + if (rc) { + grn_obj_remove(ctx, column); + succeeded = GRN_FALSE; + goto exit; + } } grn_obj_unlink(ctx, column); + } else { + succeeded = GRN_FALSE; } exit: - GRN_OUTPUT_BOOL(!ctx->rc); + GRN_OUTPUT_BOOL(succeeded); if (table) { grn_obj_unlink(ctx, table); } if (type) { grn_obj_unlink(ctx, type); } return NULL; @@ -2544,6 +2756,26 @@ dump_table(grn_ctx *ctx, grn_obj *outbuf, grn_obj *table, GRN_TEXT_PUTS(ctx, outbuf, " --normalizer "); dump_obj_name(ctx, outbuf, normalizer); } + if (table->header.type != GRN_TABLE_NO_KEY) { + grn_obj token_filters; + int n_token_filters; + + GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_ID_NIL); + grn_obj_get_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters); + n_token_filters = GRN_BULK_VSIZE(&token_filters) / sizeof(grn_obj *); + if (n_token_filters > 0) { + int i; + GRN_TEXT_PUTS(ctx, outbuf, " --token_filters "); + for (i = 0; i < n_token_filters; i++) { + grn_obj *token_filter = GRN_PTR_VALUE_AT(&token_filters, i); + if (i > 0) { + GRN_TEXT_PUTC(ctx, outbuf, ','); + } + dump_obj_name(ctx, outbuf, token_filter); + } + } + GRN_OBJ_FIN(ctx, &token_filters); + } GRN_TEXT_PUTC(ctx, outbuf, '\n'); @@ -3274,17 +3506,18 @@ static void tokenize(grn_ctx *ctx, grn_hash *lexicon, grn_obj *string, grn_token_mode mode, unsigned int flags, grn_obj *tokens) { - grn_token *token; + grn_token_cursor *token_cursor; - token = grn_token_open(ctx, (grn_obj *)lexicon, - GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string), - mode, flags); - if (!token) { + token_cursor = + grn_token_cursor_open(ctx, (grn_obj *)lexicon, + GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string), + mode, flags); + if (!token_cursor) { return; } - while (token->status == GRN_TOKEN_DOING) { - grn_id token_id = grn_token_next(ctx, token); + while (token_cursor->status == GRN_TOKEN_DOING) { + grn_id token_id = grn_token_cursor_next(ctx, token_cursor); tokenize_token *current_token; if (token_id == GRN_ID_NIL) { continue; @@ -3292,9 +3525,9 @@ tokenize(grn_ctx *ctx, grn_hash *lexicon, grn_obj *string, grn_token_mode mode, grn_bulk_space(ctx, tokens, sizeof(tokenize_token)); current_token = ((tokenize_token *)(GRN_BULK_CURR(tokens))) - 1; current_token->id = token_id; - current_token->position = token->pos; + current_token->position = token_cursor->pos; } - grn_token_close(ctx, token); + grn_token_cursor_close(ctx, token_cursor); } static grn_obj * @@ -3348,15 +3581,16 @@ proc_tokenize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) GRN_OBJ_FIN(ctx, &tokens); } else if (MODE_NAME_EQUAL("GET")) { { - grn_token *token; - token = grn_token_open(ctx, (grn_obj *)lexicon, - GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string), - GRN_TOKEN_ADD, flags); - if (token) { - while (token->status == GRN_TOKEN_DOING) { - grn_token_next(ctx, token); + grn_token_cursor *token_cursor; + token_cursor = + grn_token_cursor_open(ctx, (grn_obj *)lexicon, + GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string), + GRN_TOKEN_ADD, flags); + if (token_cursor) { + while (token_cursor->status == GRN_TOKEN_DOING) { + grn_token_cursor_next(ctx, token_cursor); } - grn_token_close(ctx, token); + grn_token_cursor_close(ctx, token_cursor); } } @@ -5076,7 +5310,8 @@ grn_db_init_builtin_query(grn_ctx *ctx) DEF_VAR(vars[3], "value_type"); DEF_VAR(vars[4], "default_tokenizer"); DEF_VAR(vars[5], "normalizer"); - DEF_COMMAND("table_create", proc_table_create, 6, vars); + DEF_VAR(vars[6], "token_filters"); + DEF_COMMAND("table_create", proc_table_create, 7, vars); DEF_VAR(vars[0], "name"); DEF_COMMAND("table_remove", proc_table_remove, 1, vars); |