Susumu Yata
null+****@clear*****
Fri Mar 4 15:42:53 JST 2016
Susumu Yata 2016-03-04 15:42:53 +0900 (Fri, 04 Mar 2016) New Revision: b21f136224eeb0cbb470f7565648e4827cde50a3 https://github.com/groonga/groonga/commit/b21f136224eeb0cbb470f7565648e4827cde50a3 Message: load: check --columns more precisely GitHub: #496 Modified files: lib/ctx.c lib/db.c lib/grn_ctx_impl.h Modified: lib/ctx.c (+1 -0) =================================================================== --- lib/ctx.c 2016-03-04 14:54:55 +0900 (6cfe141) +++ lib/ctx.c 2016-03-04 15:42:53 +0900 (aed8072) @@ -507,6 +507,7 @@ grn_loader_init(grn_loader *loader) GRN_TEXT_INIT(&loader->values, 0); GRN_UINT32_INIT(&loader->level, GRN_OBJ_VECTOR); GRN_PTR_INIT(&loader->columns, GRN_OBJ_VECTOR, GRN_ID_NIL); + loader->id_offset = -1; loader->key_offset = -1; loader->table = NULL; loader->last = NULL; Modified: lib/db.c (+73 -38) =================================================================== --- lib/db.c 2016-03-04 14:54:55 +0900 (e3603e6) +++ lib/db.c 2016-03-04 15:42:53 +0900 (53aec71) @@ -12761,7 +12761,7 @@ bracket_close(grn_ctx *ctx, grn_loader *loader) value++; } if (loader->key_offset == -1) { - ERR(GRN_INVALID_ARGUMENT, "missing key column"); + ERR(GRN_INVALID_ARGUMENT, "missing id or key column"); grn_loader_save_error(ctx, loader); loader->columns_status = GRN_LOADER_COLUMNS_BROKEN; goto exit; @@ -13350,33 +13350,83 @@ json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned int str_le #undef JSON_READ_OPEN_BRACE /* - * parse_load_columns parses a columns parameter of load. Columns are appended - * to res. + * grn_loader_parse_columns parses a columns parameter. + * Columns except _id and _key are appended to loader->columns. + * If it contains _id or _key, loader->id_offset or loader->key_offset is set. */ static grn_rc -parse_load_columns(grn_ctx *ctx, grn_obj *table, - const char *str, unsigned int str_size, grn_obj *res) +grn_loader_parse_columns(grn_ctx *ctx, grn_loader *loader, + const char *str, unsigned int str_size) { - const char *p = str, *pe = p + str_size, *rest; - const char *tokbuf[256], *tok; - while (p < pe) { - int i, n = tokenize(p, pe - p, tokbuf, 256, &rest); + const char *ptr = str, *ptr_end = ptr + str_size, *rest; + const char *tokens[256], *token_end; + while (ptr < ptr_end) { + int i, n = tokenize(ptr, ptr_end - ptr, tokens, 256, &rest); for (i = 0; i < n; i++) { - grn_obj *col; - tok = tokbuf[i]; - while (p < tok && (' ' == *p || ',' == *p)) { p++; } - col = grn_obj_column(ctx, table, p, tok - p); - if (!col) { + grn_obj *column; + token_end = tokens[i]; + while (ptr < token_end && (' ' == *ptr || ',' == *ptr)) { + ptr++; + } + column = grn_obj_column(ctx, loader->table, ptr, token_end - ptr); + if (!column) { ERR(GRN_INVALID_ARGUMENT, "nonexistent column: <%.*s>", - (int)(tok - p), p); - goto exit; + (int)(token_end - ptr), ptr); + return ctx->rc; + } + if (name_equal(ptr, token_end - ptr, GRN_COLUMN_NAME_ID)) { + grn_obj_unlink(ctx, column); + if (loader->id_offset != -1 || loader->key_offset != -1) { + /* _id and _key must not appear more than once. */ + if (loader->id_offset != -1) { + ERR(GRN_INVALID_ARGUMENT, + "duplicated id and key columns: <%s> at %d and <%s> at %d", + GRN_COLUMN_NAME_ID, i, + GRN_COLUMN_NAME_ID, loader->id_offset); + } else { + ERR(GRN_INVALID_ARGUMENT, + "duplicated id and key columns: <%s> at %d and <%s> at %d", + GRN_COLUMN_NAME_ID, i, + GRN_COLUMN_NAME_KEY, loader->key_offset); + } + return ctx->rc; + } + loader->id_offset = i; + } else if (name_equal(ptr, token_end - ptr, GRN_COLUMN_NAME_KEY)) { + grn_obj_unlink(ctx, column); + if (loader->id_offset != -1 || loader->key_offset != -1) { + /* _id and _key must not appear more than once. */ + if (loader->id_offset != -1) { + ERR(GRN_INVALID_ARGUMENT, + "duplicated id and key columns: <%s> at %d and <%s> at %d", + GRN_COLUMN_NAME_KEY, i, + GRN_COLUMN_NAME_ID, loader->id_offset); + } else { + ERR(GRN_INVALID_ARGUMENT, + "duplicated id and key columns: <%s> at %d and <%s> at %d", + GRN_COLUMN_NAME_KEY, i, + GRN_COLUMN_NAME_KEY, loader->key_offset); + } + return ctx->rc; + } + loader->key_offset = i; + } else { + GRN_PTR_PUT(ctx, &loader->columns, column); } - GRN_PTR_PUT(ctx, res, col); - p = tok; + ptr = token_end; } - p = rest; + ptr = rest; + } + switch (loader->table->header.type) { + case GRN_TABLE_HASH_KEY : + case GRN_TABLE_PAT_KEY : + case GRN_TABLE_DAT_KEY : + if (loader->id_offset == -1 && loader->key_offset == -1) { + ERR(GRN_INVALID_ARGUMENT, "missing id or key column"); + return ctx->rc; + } + break; } -exit: return ctx->rc; } @@ -13414,27 +13464,12 @@ grn_load_(grn_ctx *ctx, grn_content_type input_type, return; } if (columns && columns_len) { - int i, n_columns; - grn_obj parsed_columns; - GRN_PTR_INIT(&parsed_columns, GRN_OBJ_VECTOR, GRN_ID_NIL); - if (parse_load_columns(ctx, loader->table, columns, columns_len, - &parsed_columns) != GRN_SUCCESS) { + grn_rc rc = grn_loader_parse_columns(ctx, loader, columns, columns_len); + if (rc != GRN_SUCCESS) { + loader->columns_status = GRN_LOADER_COLUMNS_BROKEN; loader->stat = GRN_LOADER_END; - GRN_OBJ_FIN(ctx, &parsed_columns); return; } - n_columns = GRN_BULK_VSIZE(&parsed_columns) / sizeof(grn_obj *); - for (i = 0; i < n_columns; i++) { - grn_obj *column = GRN_PTR_VALUE_AT(&parsed_columns, i); - if (column->header.type == GRN_ACCESSOR && - ((grn_accessor *)column)->action == GRN_ACCESSOR_GET_KEY) { - loader->key_offset = i; - grn_obj_unlink(ctx, column); - } else { - GRN_PTR_PUT(ctx, &loader->columns, column); - } - } - GRN_OBJ_FIN(ctx, &parsed_columns); loader->columns_status = GRN_LOADER_COLUMNS_SET; } if (ifexists && ifexists_len) { Modified: lib/grn_ctx_impl.h (+2 -1) =================================================================== --- lib/grn_ctx_impl.h 2016-03-04 14:54:55 +0900 (cb3421f) +++ lib/grn_ctx_impl.h 2016-03-04 15:42:53 +0900 (b843edd) @@ -75,7 +75,8 @@ typedef struct { grn_obj level; grn_obj columns; uint32_t emit_level; - int32_t key_offset; + int32_t id_offset; /* Position of _id in values or -1 if _id is N/A. */ + int32_t key_offset; /* Position of _key in values or -1 if _key is N/A. */ grn_obj *table; grn_obj *last; grn_obj *ifexists; -------------- next part -------------- HTML����������������������������...Descargar