susumu.yata
null+****@clear*****
Tue Nov 17 13:28:52 JST 2015
susumu.yata 2015-11-17 13:28:52 +0900 (Tue, 17 Nov 2015) New Revision: 6ef5dd526bd14015f831629da553d630ded7bb9e https://github.com/groonga/groonga/commit/6ef5dd526bd14015f831629da553d630ded7bb9e Message: grn_ts: modify the spec and fix a bug of grn_ts_expr_node_deref() Modified files: lib/ts/ts_expr_builder.c lib/ts/ts_expr_node.c lib/ts/ts_expr_node.h Modified: lib/ts/ts_expr_builder.c (+2 -2) =================================================================== --- lib/ts/ts_expr_builder.c 2015-11-17 12:47:06 +0900 (99b8ffd) +++ lib/ts/ts_expr_builder.c 2015-11-17 13:28:52 +0900 (1f0b521) @@ -145,7 +145,7 @@ grn_ts_expr_builder_complete(grn_ctx *ctx, grn_ts_expr_builder *builder, if (!builder || (builder->n_nodes != 1) || builder->n_bridges || !expr) { GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument"); } - rc = grn_ts_expr_node_deref(ctx, &builder->nodes[0]); + rc = grn_ts_expr_node_deref(ctx, builder->nodes[0], &builder->nodes[0]); if (rc != GRN_SUCCESS) { return rc; } @@ -648,7 +648,7 @@ grn_ts_expr_builder_push_op(grn_ctx *ctx, grn_ts_expr_builder *builder, * FIXME: Operators "==" and "!=" should compare arguments as references * if possible. */ - rc = grn_ts_expr_node_deref(ctx, &args[i]); + rc = grn_ts_expr_node_deref(ctx, args[i], &args[i]); if (rc != GRN_SUCCESS) { return rc; } Modified: lib/ts/ts_expr_node.c (+49 -20) =================================================================== --- lib/ts/ts_expr_node.c 2015-11-17 12:47:06 +0900 (c2b5fb6) +++ lib/ts/ts_expr_node.c 2015-11-17 13:28:52 +0900 (5392d99) @@ -4660,34 +4660,63 @@ grn_ts_expr_node_close(grn_ctx *ctx, grn_ts_expr_node *node) } #undef GRN_TS_EXPR_NODE_CLOSE_CASE +static grn_rc +grn_ts_expr_node_deref_once(grn_ctx *ctx, grn_ts_expr_node *in, + grn_ts_expr_node **out) +{ + grn_rc rc; + grn_id table_id = in->data_type; + grn_ts_expr_node *key_node, *bridge_node; + grn_obj *table = grn_ctx_at(ctx, table_id); + if (!table) { + GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "grn_ctx_at failed: %d", table_id); + } + if (!grn_ts_obj_is_table(ctx, table)) { + grn_obj_unlink(ctx, table); + GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "not table: %d", table_id); + } + rc = grn_ts_expr_key_node_open(ctx, table, &key_node); + grn_obj_unlink(ctx, table); + if (rc != GRN_SUCCESS) { + return rc; + } + rc = grn_ts_expr_bridge_node_open(ctx, in, key_node, &bridge_node); + if (rc != GRN_SUCCESS) { + grn_ts_expr_node_close(ctx, key_node); + return rc; + } + *out = bridge_node; + return GRN_SUCCESS; +} + grn_rc -grn_ts_expr_node_deref(grn_ctx *ctx, grn_ts_expr_node **node_ptr) +grn_ts_expr_node_deref(grn_ctx *ctx, grn_ts_expr_node *in, + grn_ts_expr_node **out) { - grn_ts_expr_node *node = *node_ptr; + grn_ts_expr_node *node = in, **in_ptr = NULL; while (node->data_kind == GRN_TS_REF) { - grn_rc rc; - grn_ts_expr_node *key_node, *bridge_node; - grn_id table_id = node->data_type; - grn_obj *table = grn_ctx_at(ctx, table_id); - if (!table) { - return GRN_OBJECT_CORRUPT; - } - if (!grn_ts_obj_is_table(ctx, table)) { - grn_obj_unlink(ctx, table); - return GRN_OBJECT_CORRUPT; - } - rc = grn_ts_expr_key_node_open(ctx, table, &key_node); - grn_obj_unlink(ctx, table); + grn_ts_expr_node *new_node; + grn_rc rc = grn_ts_expr_node_deref_once(ctx, node, &new_node); if (rc != GRN_SUCCESS) { + if (node != in) { + if (in_ptr) { + *in_ptr = NULL; + } + grn_ts_expr_node_close(ctx, node); + } return rc; } - rc = grn_ts_expr_bridge_node_open(ctx, node, key_node, &bridge_node); - if (rc != GRN_SUCCESS) { - return rc; + if (node == in) { + grn_ts_expr_bridge_node *bridge_node; + bridge_node = (grn_ts_expr_bridge_node *)new_node; + if (bridge_node->src != node) { + GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "broken bridge node"); + } + in_ptr = &bridge_node->src; } - node = bridge_node; + node = new_node; } - *node_ptr = node; + *out = node; return GRN_SUCCESS; } Modified: lib/ts/ts_expr_node.h (+6 -8) =================================================================== --- lib/ts/ts_expr_node.h 2015-11-17 12:47:06 +0900 (5205e80) +++ lib/ts/ts_expr_node.h 2015-11-17 13:28:52 +0900 (32a3d90) @@ -94,15 +94,13 @@ void grn_ts_expr_node_close(grn_ctx *ctx, grn_ts_expr_node *node); /* * grn_ts_expr_node_deref() resolves references. * - * If *node_ptr refers to a reference node, grn_ts_expr_node_deref() creates a - * key node associated with the destination table and creates a bridge node - * from *node_ptr to the key node. Then, *node_ptr is modified to refer to the - * bridge node. If the data kind of the bridge node is GRN_TS_REF, references - * are recursively resolved. - * - * Note that references may be partially resolved on failure. + * If *in refers to a reference node, grn_ts_expr_node_deref() creates a key + * node associated with the destination table and creates a bridge node from + * *in to the key node. If the data kind of the bridge node is GRN_TS_REF, + * references are recursively resolved. */ -grn_rc grn_ts_expr_node_deref(grn_ctx *ctx, grn_ts_expr_node **node_ptr); +grn_rc grn_ts_expr_node_deref(grn_ctx *ctx, grn_ts_expr_node *in, + grn_ts_expr_node **out); /* grn_ts_expr_node_evaluate() evaluates a subtree. */ grn_rc grn_ts_expr_node_evaluate(grn_ctx *ctx, grn_ts_expr_node *node, -------------- next part -------------- HTML����������������������������...Download