susumu.yata
null+****@clear*****
Mon Jul 14 14:49:07 JST 2014
susumu.yata 2014-07-14 14:49:07 +0900 (Mon, 14 Jul 2014) New Revision: 1e884055ff237d12e11d14de9a90847badfad2d9 https://github.com/groonga/grnxx/commit/1e884055ff237d12e11d14de9a90847badfad2d9 Message: Implement NotEqual operator. Modified files: include/grnxx/expression.hpp lib/grnxx/expression.cpp test/test_grnxx.cpp Modified: include/grnxx/expression.hpp (+3 -0) =================================================================== --- include/grnxx/expression.hpp 2014-07-14 14:07:30 +0900 (0ae4ffd) +++ include/grnxx/expression.hpp 2014-07-14 14:49:07 +0900 (50b7744) @@ -114,6 +114,9 @@ class ExpressionBuilder { std::vector<unique_ptr<ExpressionNode>> stack_; explicit ExpressionBuilder(const Table *table); + + template <typename T> + bool push_equality_operator(Error *error); }; } // namespace grnxx Modified: lib/grnxx/expression.cpp (+65 -48) =================================================================== --- lib/grnxx/expression.cpp 2014-07-14 14:07:30 +0900 (dd654ea) +++ lib/grnxx/expression.cpp 2014-07-14 14:49:07 +0900 (265f4e1) @@ -216,13 +216,27 @@ class ColumnNode : public Node<T> { // -- OperatorNode -- -template <typename T, typename U> struct Equal { - using Arg1 = T; - using Arg2 = U; - using ResultType = Bool; - Bool operator()(Arg1 lhs, Arg2 rhs) const { - return lhs == rhs; + template <typename T> + struct Functor { + using Arg1 = T; + using Arg2 = T; + using Result = Bool; + Bool operator()(Arg1 lhs, Arg2 rhs) const { + return lhs == rhs; + }; + }; +}; + +struct NotEqual { + template <typename T> + struct Functor { + using Arg1 = T; + using Arg2 = T; + using Result = Bool; + Bool operator()(Arg1 lhs, Arg2 rhs) const { + return lhs != rhs; + }; }; }; @@ -235,7 +249,7 @@ class BinaryNode : public Node<Bool> { BinaryNode(Op op, unique_ptr<ExpressionNode> &&lhs, unique_ptr<ExpressionNode> &&rhs) - : Node<typename Op::ResultType>(), + : Node<typename Op::Result>(), operator_(op), lhs_(static_cast<Node<Arg1> *>(lhs.release())), rhs_(static_cast<Node<Arg2> *>(rhs.release())) {} @@ -389,51 +403,12 @@ bool ExpressionBuilder::push_column(Error *error, String name) { bool ExpressionBuilder::push_operator(Error *error, OperatorType operator_type) { - unique_ptr<ExpressionNode> node; switch (operator_type) { case EQUAL_OPERATOR: { - 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() != rhs->data_type()) { - // TODO: Define a better error code. - GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Type conflict"); - return false; - } - switch (lhs->data_type()) { - case BOOL_DATA: { - Equal<Bool, Bool> equal; - node.reset(new (nothrow) BinaryNode<decltype(equal)>( - equal, std::move(lhs), std::move(rhs))); - break; - } - case INT_DATA: { - Equal<Int, Int> equal; - node.reset(new (nothrow) BinaryNode<decltype(equal)>( - equal, std::move(lhs), std::move(rhs))); - break; - } - default: { - GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); - return false; - } - } - if (!node) { - GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); - return false; - } - stack_.resize(stack_.size() - 2); - stack_.push_back(std::move(node)); - return true; + return push_equality_operator<Equal>(error); } case NOT_EQUAL_OPERATOR: { - // TODO: Not supported yet. - GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); - return false; + return push_equality_operator<NotEqual>(error); } default: { // TODO: Not supported yet. @@ -459,4 +434,46 @@ unique_ptr<Expression> ExpressionBuilder::release(Error *error) { ExpressionBuilder::ExpressionBuilder(const Table *table) : table_(table) {} +template <typename T> +bool ExpressionBuilder::push_equality_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() != rhs->data_type()) { + // TODO: Define a better error code. + GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Type conflict"); + return false; + } + unique_ptr<ExpressionNode> node; + switch (lhs->data_type()) { + case BOOL_DATA: { + typename T::template Functor<Bool> equal; + node.reset(new (nothrow) BinaryNode<decltype(equal)>( + equal, std::move(lhs), std::move(rhs))); + break; + } + case INT_DATA: { + typename T::template Functor<Int> equal; + node.reset(new (nothrow) BinaryNode<decltype(equal)>( + equal, std::move(lhs), std::move(rhs))); + break; + } + default: { + GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); + return false; + } + } + if (!node) { + GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); + return false; + } + stack_.pop_back(); + stack_.back() = std::move(node); + return true; +} + } // namespace grnxx Modified: test/test_grnxx.cpp (+17 -1) =================================================================== --- test/test_grnxx.cpp 2014-07-14 14:07:30 +0900 (b7ac8e5) +++ test/test_grnxx.cpp 2014-07-14 14:49:07 +0900 (8ebcd2d) @@ -309,9 +309,9 @@ void test_expression() { assert(expression->filter(&error, &record_set)); assert(record_set.size() == 1); + record_set.clear(); cursor = table->create_cursor(&error, grnxx::CursorOptions()); assert(cursor); - record_set.clear(); assert(cursor->read(&error, 2, &record_set) == 2); assert(builder->push_column(&error, "IntColumn")); @@ -322,6 +322,22 @@ void test_expression() { assert(expression->filter(&error, &record_set)); assert(record_set.size() == 1); + assert(record_set.get(0).row_id == 1); + + 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(123))); + assert(builder->push_operator(&error, grnxx::NOT_EQUAL_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����������������������������...Download