[Groonga-commit] groonga/groonga at 77c3d20 [master] grn_ts: implement typecast operators Int -> Float and Text -> Time

アーカイブの一覧に戻る

susumu.yata null+****@clear*****
Tue Nov 17 16:56:45 JST 2015


susumu.yata	2015-11-17 16:56:45 +0900 (Tue, 17 Nov 2015)

  New Revision: 77c3d201cc40210b2a3024f23b7a04fd6b345861
  https://github.com/groonga/groonga/commit/77c3d201cc40210b2a3024f23b7a04fd6b345861

  Message:
    grn_ts: implement typecast operators Int -> Float and Text -> Time
    
    GitHub: #388

  Modified files:
    lib/ts/ts_expr_node.c
    lib/ts/ts_op.c
    lib/ts/ts_op.h

  Modified: lib/ts/ts_expr_node.c (+172 -54)
===================================================================
--- lib/ts/ts_expr_node.c    2015-11-17 15:44:44 +0900 (b54bbdf)
+++ lib/ts/ts_expr_node.c    2015-11-17 16:56:45 +0900 (3ed846f)
@@ -369,6 +369,27 @@ grn_ts_op_negative_float(grn_ts_float arg)
   return -arg;
 }
 
+/* grn_ts_op_float() returns (Float)arg. */
+static grn_rc
+grn_ts_op_float(grn_ctx *ctx, grn_ts_int arg, grn_ts_float *out)
+{
+  *out = (grn_ts_float)arg;
+  return GRN_SUCCESS;
+}
+
+/* grn_ts_op_time() returns (Time)arg. */
+static grn_rc
+grn_ts_op_time(grn_ctx *ctx, grn_ts_text arg, grn_ts_time *out)
+{
+  grn_timeval value;
+  grn_rc rc = grn_str2timeval(arg.ptr, arg.size, &value);
+  if (rc != GRN_SUCCESS) {
+/*    GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "grn_str2timeval failed");*/
+  }
+  *out = (grn_ts_time)((value.tv_sec * 1000000) + (value.tv_nsec / 1000));
+  return GRN_SUCCESS;
+}
+
 /* grn_ts_op_bitwise_and_bool() returns lhs & rhs. */
 inline static grn_ts_bool
 grn_ts_op_bitwise_and_bool(grn_ts_bool lhs, grn_ts_bool rhs)
@@ -2803,6 +2824,60 @@ grn_ts_expr_op_node_fin(grn_ctx *ctx, grn_ts_expr_op_node *node)
 }
 
 /*
+ * grn_ts_expr_op_node_deref_args_for_equal() resolves references if required.
+ */
+static grn_rc
+grn_ts_expr_op_node_deref_args_for_equal(grn_ctx *ctx,
+                                         grn_ts_expr_op_node *node)
+{
+  grn_rc rc;
+  if (node->n_args != 2) {
+    GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid #args: %" GRN_FMT_SIZE,
+                      node->n_args);
+  }
+  if ((node->args[0]->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
+    return grn_ts_expr_node_deref(ctx, &node->args[1]);
+  }
+  if ((node->args[1]->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
+    return grn_ts_expr_node_deref(ctx, &node->args[0]);
+  }
+
+  /* FIXME: Arguments should be compared as references if possible. */
+  rc = grn_ts_expr_node_deref(ctx, &node->args[0]);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  rc = grn_ts_expr_node_deref(ctx, &node->args[1]);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_op_node_deref_args() resolves references if required. */
+static grn_rc
+grn_ts_expr_op_node_deref_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
+{
+  switch (node->op_type) {
+    case GRN_TS_OP_EQUAL:
+    case GRN_TS_OP_NOT_EQUAL: {
+      return grn_ts_expr_op_node_deref_args_for_equal(ctx, node);
+    }
+    /* TODO: Add a ternary operator. */
+    default: {
+      size_t i;
+      for (i = 0; i < node->n_args; i++) {
+        grn_rc rc = grn_ts_expr_node_deref(ctx, &node->args[i]);
+        if (rc != GRN_SUCCESS) {
+          return rc;
+        }
+      }
+      return GRN_SUCCESS;
+    }
+  }
+}
+
+/*
  * grn_ts_op_plus_check_args() checks arguments. Note that arguments are
  * rearranged in some cases.
  */
@@ -2973,6 +3048,24 @@ grn_ts_expr_op_node_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
       node->data_type = grn_ts_data_kind_to_type(node->data_kind);
       return GRN_SUCCESS;
     }
+    case GRN_TS_OP_FLOAT: {
+      if (node->args[0]->data_kind != GRN_TS_INT) {
+        GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+                          node->args[0]->data_kind);
+      }
+      node->data_kind = GRN_TS_FLOAT;
+      node->data_type = GRN_DB_FLOAT;
+      return GRN_SUCCESS;
+    }
+    case GRN_TS_OP_TIME: {
+      if (node->args[0]->data_kind != GRN_TS_TEXT) {
+        GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
+                          node->args[0]->data_kind);
+      }
+      node->data_kind = GRN_TS_TIME;
+      node->data_type = GRN_DB_TIME;
+      return GRN_SUCCESS;
+    }
     case GRN_TS_OP_LOGICAL_AND:
     case GRN_TS_OP_LOGICAL_OR:
     case GRN_TS_OP_LOGICAL_SUB: {
@@ -3102,60 +3195,6 @@ grn_ts_expr_op_node_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
   }
 }
 
-/*
- * grn_ts_expr_op_node_deref_args_for_equal() resolves references if required.
- */
-static grn_rc
-grn_ts_expr_op_node_deref_args_for_equal(grn_ctx *ctx,
-                                         grn_ts_expr_op_node *node)
-{
-  grn_rc rc;
-  if (node->n_args != 2) {
-    GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid #args: %" GRN_FMT_SIZE,
-                      node->n_args);
-  }
-  if ((node->args[0]->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
-    return grn_ts_expr_node_deref(ctx, &node->args[1]);
-  }
-  if ((node->args[1]->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
-    return grn_ts_expr_node_deref(ctx, &node->args[0]);
-  }
-
-  /* FIXME: Arguments should be compared as references if possible. */
-  rc = grn_ts_expr_node_deref(ctx, &node->args[0]);
-  if (rc != GRN_SUCCESS) {
-    return rc;
-  }
-  rc = grn_ts_expr_node_deref(ctx, &node->args[1]);
-  if (rc != GRN_SUCCESS) {
-    return rc;
-  }
-  return GRN_SUCCESS;
-}
-
-/* grn_ts_expr_op_node_deref_args() resolves references if required. */
-static grn_rc
-grn_ts_expr_op_node_deref_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
-{
-  switch (node->op_type) {
-    case GRN_TS_OP_EQUAL:
-    case GRN_TS_OP_NOT_EQUAL: {
-      return grn_ts_expr_op_node_deref_args_for_equal(ctx, node);
-    }
-    /* TODO: Add a ternary operator. */
-    default: {
-      size_t i;
-      for (i = 0; i < node->n_args; i++) {
-        grn_rc rc = grn_ts_expr_node_deref(ctx, &node->args[i]);
-        if (rc != GRN_SUCCESS) {
-          return rc;
-        }
-      }
-      return GRN_SUCCESS;
-    }
-  }
-}
-
 /* grn_ts_expr_op_node_setup() sets up an operator node. */
 static grn_rc
 grn_ts_expr_op_node_setup(grn_ctx *ctx, grn_ts_expr_op_node *node)
@@ -3307,6 +3346,52 @@ grn_ts_op_negative_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
 #undef GRN_TS_OP_SIGN_EVALUATE
 #undef GRN_TS_OP_SIGN_EVALUATE_CASE
 
+/* grn_ts_op_float_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_float_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                         const grn_ts_record *in, size_t n_in, void *out)
+{
+  size_t i;
+  grn_ts_int *buf_ptr;
+  grn_ts_float *out_ptr = (grn_ts_float *)out;
+  grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+                                               &node->bufs[0]);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  buf_ptr = (grn_ts_int *)node->bufs[0].ptr;
+  for (i = 0; i < n_in; i++) {
+    rc = grn_ts_op_float(ctx, buf_ptr[i], &out_ptr[i]);
+    if (rc != GRN_SUCCESS) {
+      return rc;
+    }
+  }
+  return GRN_SUCCESS;
+}
+
+/* grn_ts_op_time_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_time_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                        const grn_ts_record *in, size_t n_in, void *out)
+{
+  size_t i;
+  grn_ts_text *buf_ptr;
+  grn_ts_time *out_ptr = (grn_ts_time *)out;
+  grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
+                                               &node->bufs[0]);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  buf_ptr = (grn_ts_text *)node->bufs[0].ptr;
+  for (i = 0; i < n_in; i++) {
+    rc = grn_ts_op_time(ctx, buf_ptr[i], &out_ptr[i]);
+    if (rc != GRN_SUCCESS) {
+      return rc;
+    }
+  }
+  return GRN_SUCCESS;
+}
+
 /* grn_ts_op_logical_and_evaluate() evaluates an operator. */
 static grn_rc
 grn_ts_op_logical_and_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
@@ -3969,6 +4054,12 @@ grn_ts_expr_op_node_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
     case GRN_TS_OP_NEGATIVE: {
       return grn_ts_op_negative_evaluate(ctx, node, in, n_in, out);
     }
+    case GRN_TS_OP_FLOAT: {
+      return grn_ts_op_float_evaluate(ctx, node, in, n_in, out);
+    }
+    case GRN_TS_OP_TIME: {
+      return grn_ts_op_time_evaluate(ctx, node, in, n_in, out);
+    }
     case GRN_TS_OP_LOGICAL_AND: {
       return grn_ts_op_logical_and_evaluate(ctx, node, in, n_in, out);
     }
@@ -4459,6 +4550,30 @@ grn_ts_op_negative_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
 }
 #undef GRN_TS_OP_SIGN_ADJUST
 
+/* grn_ts_op_float_adjust() updates scores. */
+static grn_rc
+grn_ts_op_float_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                       grn_ts_record *io, size_t n_io)
+{
+  size_t i;
+  grn_ts_int *buf_ptr;
+  grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], io, n_io,
+                                               &node->bufs[0]);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  buf_ptr = (grn_ts_int *)node->bufs[0].ptr;
+  for (i = 0; i < n_io; i++) {
+    grn_ts_float result;
+    rc = grn_ts_op_float(ctx, buf_ptr[i], &result);
+    io[i].score = (grn_ts_score)result;
+    if (!isfinite(io[i].score)) {
+      GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid score: %g", result);
+    }
+  }
+  return GRN_SUCCESS;
+}
+
 #define GRN_TS_OP_ARITH_ADJUST(type)\
   grn_rc rc;\
   size_t i, count = 0;\
@@ -4536,6 +4651,9 @@ grn_ts_expr_op_node_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
     case GRN_TS_OP_NEGATIVE: {
       return grn_ts_op_negative_adjust(ctx, node, io, n_io);
     }
+    case GRN_TS_OP_FLOAT: {
+      return grn_ts_op_float_adjust(ctx, node, io, n_io);
+    }
     case GRN_TS_OP_PLUS: {
       return grn_ts_op_plus_adjust(ctx, node, io, n_io);
     }

  Modified: lib/ts/ts_op.c (+7 -1)
===================================================================
--- lib/ts/ts_op.c    2015-11-17 15:44:44 +0900 (2591d5e)
+++ lib/ts/ts_op.c    2015-11-17 16:56:45 +0900 (4a91d19)
@@ -25,7 +25,9 @@ grn_ts_op_get_n_args(grn_ts_op_type op_type)
     case GRN_TS_OP_LOGICAL_NOT: /* !X */
     case GRN_TS_OP_BITWISE_NOT: /* ~X */
     case GRN_TS_OP_POSITIVE:    /* +X */
-    case GRN_TS_OP_NEGATIVE: {  /* -X */
+    case GRN_TS_OP_NEGATIVE:    /* -X */
+    case GRN_TS_OP_FLOAT:
+    case GRN_TS_OP_TIME: {
       return 1;
     }
     case GRN_TS_OP_LOGICAL_AND:            /* X && Y  */
@@ -67,6 +69,10 @@ grn_ts_op_get_precedence(grn_ts_op_type op_type)
     case GRN_TS_OP_NEGATIVE: {
       return 14;
     }
+    case GRN_TS_OP_FLOAT:
+    case GRN_TS_OP_TIME: {
+      return 15;
+    }
     case GRN_TS_OP_LOGICAL_AND: {
       return 5;
     }

  Modified: lib/ts/ts_op.h (+4 -0)
===================================================================
--- lib/ts/ts_op.h    2015-11-17 15:44:44 +0900 (9613527)
+++ lib/ts/ts_op.h    2015-11-17 16:56:45 +0900 (43fd737)
@@ -39,6 +39,10 @@ typedef enum {
   GRN_TS_OP_POSITIVE,    /* +X */
   GRN_TS_OP_NEGATIVE,    /* -X */
 
+  /* Typecast operators. */
+  GRN_TS_OP_FLOAT,
+  GRN_TS_OP_TIME,
+
   /* Binary operators. */
   GRN_TS_OP_LOGICAL_AND,            /* X && Y  */
   GRN_TS_OP_LOGICAL_OR,             /* X || Y  */
-------------- next part --------------
HTML����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る