[Groonga-commit] groonga/groonga at 6ef5dd5 [master] grn_ts: modify the spec and fix a bug of grn_ts_expr_node_deref()

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index