[Groonga-commit] groonga/grnxx at ecb9758 [master] Add logical operators.

Back to archive index

susumu.yata null+****@clear*****
Mon Jul 14 15:37:44 JST 2014


susumu.yata	2014-07-14 15:37:44 +0900 (Mon, 14 Jul 2014)

  New Revision: ecb97581b46cd8437fef7839b502a5c137d7f2ca
  https://github.com/groonga/grnxx/commit/ecb97581b46cd8437fef7839b502a5c137d7f2ca

  Message:
    Add logical operators.

  Modified files:
    include/grnxx/expression.hpp
    lib/grnxx/expression.cpp
    test/test_grnxx.cpp

  Modified: include/grnxx/expression.hpp (+7 -0)
===================================================================
--- include/grnxx/expression.hpp    2014-07-14 15:12:20 +0900 (4ed0b7b)
+++ include/grnxx/expression.hpp    2014-07-14 15:37:44 +0900 (1fb97cb)
@@ -12,6 +12,10 @@ enum OperatorType {
 
   // -- Binary operators --
 
+  // Logical operators.
+  LOGICAL_AND_OPERATOR,
+  LOGICAL_OR_OPERATOR,
+
   // Equality operators.
   EQUAL_OPERATOR,
   NOT_EQUAL_OPERATOR,
@@ -122,6 +126,9 @@ class ExpressionBuilder {
 
   explicit ExpressionBuilder(const Table *table);
 
+  // Push an operator && or ||.
+  template <typename T>
+  bool push_logical_operator(Error *error);
   // Push an operator == or !=.
   template <typename T>
   bool push_equality_operator(Error *error);

  Modified: lib/grnxx/expression.cpp (+56 -0)
===================================================================
--- lib/grnxx/expression.cpp    2014-07-14 15:12:20 +0900 (77cf135)
+++ lib/grnxx/expression.cpp    2014-07-14 15:37:44 +0900 (3d8ab70)
@@ -216,6 +216,28 @@ class ColumnNode : public Node<T> {
 
 // -- OperatorNode --
 
+struct LogicalAnd {
+  struct Functor {
+    using Arg1 = Bool;
+    using Arg2 = Bool;
+    using Result = Bool;
+    Bool operator()(Arg1 lhs, Arg2 rhs) const {
+      return lhs && rhs;
+    };
+  };
+};
+
+struct LogicalOr {
+  struct Functor {
+    using Arg1 = Bool;
+    using Arg2 = Bool;
+    using Result = Bool;
+    Bool operator()(Arg1 lhs, Arg2 rhs) const {
+      return lhs || rhs;
+    };
+  };
+};
+
 struct Equal {
   template <typename T>
   struct Functor {
@@ -452,6 +474,12 @@ bool ExpressionBuilder::push_column(Error *error, String name) {
 bool ExpressionBuilder::push_operator(Error *error,
                                       OperatorType operator_type) {
   switch (operator_type) {
+    case LOGICAL_AND_OPERATOR: {
+      return push_logical_operator<LogicalAnd>(error);
+    }
+    case LOGICAL_OR_OPERATOR: {
+      return push_logical_operator<LogicalOr>(error);
+    }
     case EQUAL_OPERATOR: {
       return push_equality_operator<Equal>(error);
     }
@@ -495,6 +523,34 @@ unique_ptr<Expression> ExpressionBuilder::release(Error *error) {
 ExpressionBuilder::ExpressionBuilder(const Table *table) : table_(table) {}
 
 template <typename T>
+bool ExpressionBuilder::push_logical_operator(Error *error) {
+  if (stack_.size() < 2) {
+    // TODO: Define a better error code.
+    GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Not enough operands");
+    return false;
+  }
+  auto &lhs = stack_[stack_.size() - 2];
+  auto &rhs = stack_[stack_.size() - 1];
+  if ((lhs->data_type() != BOOL_DATA) ||
+      (rhs->data_type() != BOOL_DATA)) {
+    // TODO: Define a better error code.
+    GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong type");
+    return false;
+  }
+  unique_ptr<ExpressionNode> node;
+  typename T::Functor functor;
+  node.reset(new (nothrow) BinaryNode<decltype(functor)>(
+      functor, std::move(lhs), std::move(rhs)));
+  if (!node) {
+    GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed");
+    return false;
+  }
+  stack_.pop_back();
+  stack_.back() = std::move(node);
+  return true;
+}
+
+template <typename T>
 bool ExpressionBuilder::push_equality_operator(Error *error) {
   if (stack_.size() < 2) {
     // TODO: Define a better error code.

  Modified: test/test_grnxx.cpp (+19 -0)
===================================================================
--- test/test_grnxx.cpp    2014-07-14 15:12:20 +0900 (a8bb175)
+++ test/test_grnxx.cpp    2014-07-14 15:37:44 +0900 (be38fa6)
@@ -416,6 +416,25 @@ void test_expression() {
   assert(expression->filter(&error, &record_set));
   assert(record_set.size() == 1);
   assert(record_set.get(0).row_id == 2);
+
+  record_set.clear();
+  cursor = table->create_cursor(&error, grnxx::CursorOptions());
+  assert(cursor);
+  assert(cursor->read(&error, 2, &record_set) == 2);
+
+  // 論理演算を試す.
+  assert(builder->push_column(&error, "IntColumn"));
+  assert(builder->push_datum(&error, grnxx::Int(300)));
+  assert(builder->push_operator(&error, grnxx::GREATER_OPERATOR));
+  assert(builder->push_column(&error, "BoolColumn"));
+  assert(builder->push_operator(&error, grnxx::LOGICAL_AND_OPERATOR));
+  expression = builder->release(&error);
+  assert(expression);
+
+  // フィルタとして使ったときの結果を確認する.
+  assert(expression->filter(&error, &record_set));
+  assert(record_set.size() == 1);
+  assert(record_set.get(0).row_id == 2);
 }
 
 }  // namespace
-------------- next part --------------
HTML����������������������������...
Descargar 



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