Kouhei Sutou
null+****@clear*****
Fri Sep 26 16:39:51 JST 2014
Kouhei Sutou 2014-09-26 16:39:51 +0900 (Fri, 26 Sep 2014) New Revision: 644eaff5fa2203a6d330f66111cea90be904a35f https://github.com/groonga/groonga/commit/644eaff5fa2203a6d330f66111cea90be904a35f Message: column_create: improve validation * Report error for nonexistent source. (Before: Just ignored.) * Remove the column when error is occurred while setting sources. Added files: test/command/suite/column_create/index/source/multi_column/trailing_space.expected test/command/suite/column_create/index/source/multi_column/trailing_space.test test/command/suite/column_create/index/source/nonexistent.expected test/command/suite/column_create/index/source/nonexistent.test test/command/suite/column_create/index/source/pseudo_column/_id.expected test/command/suite/column_create/index/source/pseudo_column/_id.test Modified files: lib/proc.c Modified: lib/proc.c (+118 -23) =================================================================== --- lib/proc.c 2014-09-26 15:07:20 +0900 (e147347) +++ lib/proc.c 2014-09-26 16:39:51 +0900 (9e4dc19) @@ -1316,9 +1316,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 +1421,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 +1440,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 +1456,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; Added: test/command/suite/column_create/index/source/multi_column/trailing_space.expected (+17 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/column_create/index/source/multi_column/trailing_space.expected 2014-09-26 16:39:51 +0900 (d1afcea) @@ -0,0 +1,17 @@ +table_create Memos TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Memos title COLUMN_SCALAR ShortText +[[0,0.0,0.0],true] +column_create Memos content COLUMN_SCALAR Text +[[0,0.0,0.0],true] +table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NomralizerAuto +[[0,0.0,0.0],true] +column_create Terms memos_index COLUMN_INDEX|WITH_POSITION|WITH_SECTION Memos "title, content " +[[0,0.0,0.0],true] +dump +table_create Memos TABLE_NO_KEY +column_create Memos content COLUMN_SCALAR Text +column_create Memos title COLUMN_SCALAR ShortText +table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram +column_create Terms memos_index COLUMN_INDEX|WITH_SECTION|WITH_POSITION Memos title,content + Added: test/command/suite/column_create/index/source/multi_column/trailing_space.test (+11 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/column_create/index/source/multi_column/trailing_space.test 2014-09-26 16:39:51 +0900 (aebf200) @@ -0,0 +1,11 @@ +table_create Memos TABLE_NO_KEY +column_create Memos title COLUMN_SCALAR ShortText +column_create Memos content COLUMN_SCALAR Text + +table_create Terms TABLE_PAT_KEY ShortText \ + --default_tokenizer TokenBigram \ + --normalizer NomralizerAuto +column_create Terms memos_index COLUMN_INDEX|WITH_POSITION|WITH_SECTION \ + Memos "title, content " + +dump Added: test/command/suite/column_create/index/source/nonexistent.expected (+14 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/column_create/index/source/nonexistent.expected 2014-09-26 16:39:51 +0900 (5cb4d89) @@ -0,0 +1,14 @@ +table_create Memos TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Memos content COLUMN_SCALAR Text +[[0,0.0,0.0],true] +table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NomralizerAuto +[[0,0.0,0.0],true] +column_create Terms memos_index COLUMN_INDEX|WITH_POSITION Memos nonexistent +[[[-22,0.0,0.0],"[column][create] nonexistent source: <nonexistent>"],false] +#|e| [column][create] nonexistent source: <nonexistent> +dump +table_create Memos TABLE_NO_KEY +column_create Memos content COLUMN_SCALAR Text +table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram + Added: test/command/suite/column_create/index/source/nonexistent.test (+9 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/column_create/index/source/nonexistent.test 2014-09-26 16:39:51 +0900 (09653e1) @@ -0,0 +1,9 @@ +table_create Memos TABLE_NO_KEY +column_create Memos content COLUMN_SCALAR Text + +table_create Terms TABLE_PAT_KEY ShortText \ + --default_tokenizer TokenBigram \ + --normalizer NomralizerAuto +column_create Terms memos_index COLUMN_INDEX|WITH_POSITION Memos nonexistent + +dump Added: test/command/suite/column_create/index/source/pseudo_column/_id.expected (+24 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/column_create/index/source/pseudo_column/_id.expected 2014-09-26 16:39:51 +0900 (af62b55) @@ -0,0 +1,24 @@ +table_create Memos TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Memos content COLUMN_SCALAR Text +[[0,0.0,0.0],true] +table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NomralizerAuto +[[0,0.0,0.0],true] +column_create Terms memos_index COLUMN_INDEX|WITH_POSITION Memos _id +[ + [ + [ + -22, + 0.0, + 0.0 + ], + "[column][create] pseudo column except <_key> is invalid: <_id>" + ], + false +] +#|e| [column][create] pseudo column except <_key> is invalid: <_id> +dump +table_create Memos TABLE_NO_KEY +column_create Memos content COLUMN_SCALAR Text +table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram + Added: test/command/suite/column_create/index/source/pseudo_column/_id.test (+9 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/column_create/index/source/pseudo_column/_id.test 2014-09-26 16:39:51 +0900 (d399b04) @@ -0,0 +1,9 @@ +table_create Memos TABLE_NO_KEY +column_create Memos content COLUMN_SCALAR Text + +table_create Terms TABLE_PAT_KEY ShortText \ + --default_tokenizer TokenBigram \ + --normalizer NomralizerAuto +column_create Terms memos_index COLUMN_INDEX|WITH_POSITION Memos _id + +dump -------------- next part -------------- HTML����������������������������... ダウンロード