| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "sargs/SearchArgument.hh" |
| #include "wrap/gtest-wrapper.h" |
| |
| #include <unordered_set> |
| |
| namespace orc { |
| |
| TEST(TestSearchArgument, literalTest) { |
| Literal literal0(static_cast<int64_t>(1234)); |
| EXPECT_EQ(PredicateDataType::LONG, literal0.getType()); |
| EXPECT_TRUE("1234" == literal0.toString()); |
| |
| Literal literal1(0.1234); |
| EXPECT_EQ(PredicateDataType::FLOAT, literal1.getType()); |
| EXPECT_TRUE("0.1234" == literal1.toString()); |
| |
| Literal literal2(false); |
| EXPECT_EQ(PredicateDataType::BOOLEAN, literal2.getType()); |
| EXPECT_TRUE("false" == literal2.toString()); |
| |
| Literal literal3(static_cast<int64_t>(123456), 123456789); |
| EXPECT_EQ(PredicateDataType::TIMESTAMP, literal3.getType()); |
| EXPECT_TRUE("123456.123456789" == literal3.toString()); |
| EXPECT_EQ(123456123, literal3.getTimestamp().getMillis()); |
| |
| Literal literal4(Int128(54321), 6, 2); |
| EXPECT_EQ(PredicateDataType::DECIMAL, literal4.getType()); |
| EXPECT_TRUE("543.21" == literal4.toString()); |
| |
| Literal literal5("test", 4); |
| EXPECT_EQ(PredicateDataType::STRING, literal5.getType()); |
| EXPECT_TRUE("test" == literal5.toString()); |
| |
| Literal left(static_cast<int64_t>(123)), right(static_cast<int64_t>(123)); |
| EXPECT_TRUE(left == right); |
| EXPECT_FALSE(left != right); |
| Literal left2(static_cast<int64_t>(321)); |
| EXPECT_TRUE(left2 != right); |
| EXPECT_FALSE(left2 == right); |
| } |
| |
| TEST(TestSearchArgument, predicateLeafTest) { |
| PredicateLeaf leaf1( |
| PredicateLeaf::Operator::EQUALS, |
| PredicateDataType::LONG, |
| "id", |
| Literal(static_cast<int64_t>(1234))); |
| EXPECT_EQ(PredicateLeaf::Operator::EQUALS, leaf1.getOperator()); |
| EXPECT_EQ(PredicateDataType::LONG, leaf1.getType()); |
| EXPECT_EQ("id", leaf1.getColumnName()); |
| EXPECT_EQ("(id = 1234)", leaf1.toString()); |
| |
| const char * str1 = "aaa", * str2 = "zzz"; |
| PredicateLeaf leaf2( |
| PredicateLeaf::Operator::BETWEEN, |
| PredicateDataType::STRING, |
| "name", |
| { Literal(str1, 3), Literal(str2, 3)}); |
| EXPECT_EQ(PredicateLeaf::Operator::BETWEEN, leaf2.getOperator()); |
| EXPECT_EQ(PredicateDataType::STRING, leaf2.getType()); |
| EXPECT_EQ("name", leaf2.getColumnName()); |
| EXPECT_EQ("(name between [aaa, zzz])", leaf2.toString()); |
| |
| PredicateLeaf leaf3(leaf2); |
| EXPECT_TRUE(leaf2 == leaf3); |
| EXPECT_FALSE(leaf1 == leaf3); |
| |
| PredicateLeaf leaf4( |
| PredicateLeaf::Operator::LESS_THAN_EQUALS, |
| PredicateDataType::DECIMAL, |
| "sales", |
| { Literal(111222, 6, 3) }); |
| EXPECT_EQ(PredicateLeaf::Operator::LESS_THAN_EQUALS, leaf4.getOperator()); |
| EXPECT_EQ(PredicateDataType::DECIMAL, leaf4.getType()); |
| EXPECT_EQ("(sales <= 111.222)", leaf4.toString()); |
| } |
| |
| TEST(TestSearchArgument, truthValueTest) { |
| EXPECT_EQ(TruthValue::YES, TruthValue::YES && TruthValue::YES); |
| EXPECT_EQ(TruthValue::NO, TruthValue::YES && TruthValue::NO); |
| EXPECT_EQ(TruthValue::IS_NULL, TruthValue::YES && TruthValue::IS_NULL); |
| EXPECT_EQ(TruthValue::YES_NULL, TruthValue::YES && TruthValue::YES_NULL); |
| |
| EXPECT_EQ(TruthValue::NO, TruthValue::NO || TruthValue::NO); |
| EXPECT_EQ(TruthValue::YES, TruthValue::YES || TruthValue::NO); |
| |
| EXPECT_EQ(TruthValue::YES, !TruthValue::NO); |
| } |
| |
| static TreeNode _not(TreeNode arg) { |
| return std::make_shared<ExpressionTree>(ExpressionTree::Operator::NOT, |
| NodeList{arg}); |
| } |
| |
| static TreeNode _and(NodeList args) { |
| return std::make_shared<ExpressionTree>(ExpressionTree::Operator::AND, args); |
| } |
| |
| static TreeNode _and(TreeNode l, TreeNode r) { |
| return std::make_shared<ExpressionTree>( |
| ExpressionTree::Operator::AND, NodeList{l, r}); |
| } |
| |
| static TreeNode _or(NodeList args) { |
| return std::make_shared<ExpressionTree>(ExpressionTree::Operator::OR, args); |
| } |
| |
| static TreeNode _or(TreeNode l, TreeNode r) { |
| return std::make_shared<ExpressionTree>( |
| ExpressionTree::Operator::OR, NodeList{l, r}); |
| } |
| |
| static TreeNode _leaf(int leaf) { |
| return std::make_shared<ExpressionTree>(leaf); |
| } |
| |
| static TreeNode _constant(TruthValue val) { |
| return std::make_shared<ExpressionTree>(val); |
| } |
| |
| TEST(TestSearchArgument, testNotPushdown) { |
| EXPECT_EQ("leaf-1", |
| SearchArgumentBuilderImpl::pushDownNot(_leaf(1))->toString()); |
| EXPECT_EQ("(not leaf-1)", |
| SearchArgumentBuilderImpl::pushDownNot(_not(_leaf(1)))->toString()); |
| EXPECT_EQ("leaf-1", |
| SearchArgumentBuilderImpl::pushDownNot(_not(_not(_leaf(1)))) |
| ->toString()); |
| EXPECT_EQ("(not leaf-1)", |
| SearchArgumentBuilderImpl::pushDownNot(_not(_not(_not(_leaf(1)))))-> |
| toString()); |
| EXPECT_EQ("(or leaf-1 (not leaf-2))", |
| SearchArgumentBuilderImpl::pushDownNot(_not(_and(_not(_leaf(1)), |
| _leaf(2))))->toString()); |
| EXPECT_EQ("(and (not leaf-1) leaf-2)", |
| SearchArgumentBuilderImpl::pushDownNot(_not(_or(_leaf(1), |
| _not(_leaf(2)))))->toString()); |
| EXPECT_EQ("(or (or (not leaf-1) leaf-2) leaf-3)", |
| SearchArgumentBuilderImpl::pushDownNot(_or(_not(_and(_leaf(1), |
| _not(_leaf(2)))), |
| _not(_not(_leaf(3)))))->toString()); |
| EXPECT_EQ("NO", SearchArgumentBuilderImpl::pushDownNot( |
| _not(_constant(TruthValue::YES)))->toString()); |
| EXPECT_EQ("YES", SearchArgumentBuilderImpl::pushDownNot( |
| _not(_constant(TruthValue::NO)))->toString()); |
| EXPECT_EQ("IS_NULL", SearchArgumentBuilderImpl::pushDownNot( |
| _not(_constant(TruthValue::IS_NULL)))->toString()); |
| EXPECT_EQ("YES_NO", SearchArgumentBuilderImpl::pushDownNot( |
| _not(_constant(TruthValue::YES_NO)))->toString()); |
| EXPECT_EQ("YES_NULL", SearchArgumentBuilderImpl::pushDownNot( |
| _not(_constant(TruthValue::NO_NULL)))->toString()); |
| EXPECT_EQ("NO_NULL", SearchArgumentBuilderImpl::pushDownNot( |
| _not(_constant(TruthValue::YES_NULL)))->toString()); |
| EXPECT_EQ("YES_NO_NULL", SearchArgumentBuilderImpl::pushDownNot( |
| _not(_constant(TruthValue::YES_NO_NULL)))->toString()); |
| } |
| |
| TEST(TestSearchArgument, testFlatten) { |
| EXPECT_EQ("leaf-1", |
| SearchArgumentBuilderImpl::flatten(_leaf(1))->toString()); |
| EXPECT_EQ("NO", |
| SearchArgumentBuilderImpl::flatten(_constant(TruthValue::NO))->toString()); |
| EXPECT_EQ("(not (not leaf-1))", |
| SearchArgumentBuilderImpl::flatten(_not(_not(_leaf(1))))->toString()); |
| EXPECT_EQ("(and leaf-1 leaf-2)", |
| SearchArgumentBuilderImpl::flatten(_and(_leaf(1), _leaf(2)))->toString()); |
| EXPECT_EQ("(and (or leaf-1 leaf-2) leaf-3)", |
| SearchArgumentBuilderImpl::flatten(_and(_or(_leaf(1), _leaf(2)), _leaf(3)) |
| )->toString()); |
| EXPECT_EQ("(and leaf-1 leaf-2 leaf-3 leaf-4)", |
| SearchArgumentBuilderImpl::flatten(_and(_and(_leaf(1), _leaf(2)), |
| _and(_leaf(3), _leaf(4))))->toString()); |
| EXPECT_EQ("(or leaf-1 leaf-2 leaf-3 leaf-4)", |
| SearchArgumentBuilderImpl::flatten( |
| _or(_leaf(1), _or(_leaf(2), _or(_leaf(3), _leaf(4)))))->toString()); |
| EXPECT_EQ("(or leaf-1 leaf-2 leaf-3 leaf-4)", |
| SearchArgumentBuilderImpl::flatten( |
| _or(_or(_or(_leaf(1), _leaf(2)), _leaf(3)), _leaf(4)))->toString()); |
| EXPECT_EQ("(or leaf-1 leaf-2 leaf-3 leaf-4 leaf-5 leaf-6)", |
| SearchArgumentBuilderImpl::flatten( |
| _or(_or(_leaf(1), _or(_leaf(2), _leaf(3))), _or(_or(_leaf(4), _leaf(5)), _leaf(6))))->toString()); |
| EXPECT_EQ("(and (not leaf-1) leaf-2 (not leaf-3) leaf-4 (not leaf-5) leaf-6)", |
| SearchArgumentBuilderImpl::flatten(_and(_and(_not(_leaf(1)), |
| _and(_leaf(2), _not(_leaf(3)))), _and(_and(_leaf(4), _not(_leaf(5))), _leaf(6))) |
| )->toString()); |
| EXPECT_EQ("(not (and leaf-1 leaf-2 leaf-3))", |
| SearchArgumentBuilderImpl::flatten(_not(_and(_leaf(1), _and(_leaf(2), _leaf(3)))) |
| )->toString()); |
| } |
| |
| TEST(TestSearchArgument, testFoldMaybe) { |
| EXPECT_EQ("(and leaf-1)", |
| SearchArgumentBuilderImpl::foldMaybe( |
| _and(_leaf(1), _constant(TruthValue::YES_NO_NULL)))->toString()); |
| EXPECT_EQ("(and leaf-1 leaf-2)", |
| SearchArgumentBuilderImpl::foldMaybe( |
| _and(NodeList{_leaf(1), |
| _constant(TruthValue::YES_NO_NULL), |
| _leaf(2) |
| }))->toString()); |
| EXPECT_EQ("(and leaf-1 leaf-2)", |
| SearchArgumentBuilderImpl:: |
| foldMaybe(_and(NodeList {_constant(TruthValue::YES_NO_NULL), |
| _leaf(1), |
| _leaf(2), |
| _constant(TruthValue::YES_NO_NULL) |
| }))->toString()); |
| EXPECT_EQ("YES_NO_NULL", |
| SearchArgumentBuilderImpl:: |
| foldMaybe(_and(_constant(TruthValue::YES_NO_NULL), |
| _constant(TruthValue::YES_NO_NULL)))->toString()); |
| EXPECT_EQ("YES_NO_NULL", |
| SearchArgumentBuilderImpl:: |
| foldMaybe(_or(_leaf(1), |
| _constant(TruthValue::YES_NO_NULL)))->toString()); |
| EXPECT_EQ("(or leaf-1 (and leaf-2))", |
| SearchArgumentBuilderImpl::foldMaybe( |
| _or(_leaf(1), |
| _and(_leaf(2), |
| _constant(TruthValue::YES_NO_NULL))))->toString()); |
| EXPECT_EQ("(and leaf-1)",SearchArgumentBuilderImpl::foldMaybe( |
| _and(_or(_leaf(2), |
| _constant(TruthValue::YES_NO_NULL)), |
| _leaf(1)))->toString()); |
| EXPECT_EQ("(and leaf-100)", |
| SearchArgumentBuilderImpl::foldMaybe( |
| SearchArgumentBuilderImpl::convertToCNF(_and(_leaf(100), |
| _or(NodeList { _and(_leaf(0), _leaf(1)), |
| _and(_leaf(2), _leaf(3)), |
| _and(_leaf(4), _leaf(5)), |
| _and(_leaf(6), _leaf(7)), |
| _and(_leaf(8), _leaf(9)), |
| _and(_leaf(10), _leaf(11)), |
| _and(_leaf(12), _leaf(13)), |
| _and(_leaf(14), _leaf(15)), |
| _and(_leaf(16), _leaf(17))}))))->toString()); |
| } |
| |
| static void assertNoSharedNodes(TreeNode tree, |
| std::unordered_set<TreeNode>& seen) { |
| if (seen.find(tree) != seen.end() && |
| tree->getOperator() != ExpressionTree::Operator::LEAF) { |
| throw std::runtime_error( |
| "repeated node in expression " + tree->toString()); |
| } |
| seen.insert(tree); |
| for (auto& child : tree->getChildren()) { |
| assertNoSharedNodes(child, seen); |
| } |
| } |
| |
| TEST(TestSearchArgument, testCNF) { |
| EXPECT_EQ("leaf-1", |
| SearchArgumentBuilderImpl::convertToCNF(_leaf(1))->toString()); |
| EXPECT_EQ("NO",SearchArgumentBuilderImpl::convertToCNF( |
| _constant(TruthValue::NO))->toString()); |
| EXPECT_EQ("(not leaf-1)", SearchArgumentBuilderImpl::convertToCNF( |
| _not(_leaf(1)))->toString()); |
| EXPECT_EQ("(and leaf-1 leaf-2)", SearchArgumentBuilderImpl:: |
| convertToCNF(_and(_leaf(1), _leaf(2)))->toString()); |
| EXPECT_EQ("(or (not leaf-1) leaf-2)",SearchArgumentBuilderImpl:: |
| convertToCNF(_or(_not(_leaf(1)), _leaf(2)))->toString()); |
| EXPECT_EQ("(and (or leaf-1 leaf-2) (not leaf-3))", |
| SearchArgumentBuilderImpl::convertToCNF( |
| _and(_or(_leaf(1), _leaf(2)), _not(_leaf(3))))->toString()); |
| EXPECT_EQ("(and (or leaf-1 leaf-3) (or leaf-2 leaf-3)" |
| " (or leaf-1 leaf-4) (or leaf-2 leaf-4))", |
| SearchArgumentBuilderImpl::convertToCNF(_or( |
| _and(_leaf(1), _leaf(2)), |
| _and(_leaf(3), _leaf(4))))->toString()); |
| EXPECT_EQ("(and" |
| " (or leaf-1 leaf-5) (or leaf-2 leaf-5)" |
| " (or leaf-3 leaf-5) (or leaf-4 leaf-5)" |
| " (or leaf-1 leaf-6) (or leaf-2 leaf-6)" |
| " (or leaf-3 leaf-6) (or leaf-4 leaf-6))", |
| SearchArgumentBuilderImpl::convertToCNF( |
| _or(_and(NodeList{_leaf(1), _leaf(2), _leaf(3), _leaf(4)}), |
| _and(_leaf(5), _leaf(6))) |
| )->toString()); |
| EXPECT_EQ("(and" |
| " (or leaf-5 leaf-6 (not leaf-7) leaf-1 leaf-3)" |
| " (or leaf-5 leaf-6 (not leaf-7) leaf-2 leaf-3)" |
| " (or leaf-5 leaf-6 (not leaf-7) leaf-1 leaf-4)" |
| " (or leaf-5 leaf-6 (not leaf-7) leaf-2 leaf-4))", |
| SearchArgumentBuilderImpl::convertToCNF( |
| _or(NodeList{_and(_leaf(1), _leaf(2)), |
| _and(_leaf(3), _leaf(4)), |
| _or(_leaf(5), _leaf(6)), |
| _not(_leaf(7)) |
| }))->toString()); |
| EXPECT_EQ("(and" |
| " (or leaf-8 leaf-0 leaf-3 leaf-6)" |
| " (or leaf-8 leaf-1 leaf-3 leaf-6)" |
| " (or leaf-8 leaf-2 leaf-3 leaf-6)" |
| " (or leaf-8 leaf-0 leaf-4 leaf-6)" |
| " (or leaf-8 leaf-1 leaf-4 leaf-6)" |
| " (or leaf-8 leaf-2 leaf-4 leaf-6)" |
| " (or leaf-8 leaf-0 leaf-5 leaf-6)" |
| " (or leaf-8 leaf-1 leaf-5 leaf-6)" |
| " (or leaf-8 leaf-2 leaf-5 leaf-6)" |
| " (or leaf-8 leaf-0 leaf-3 leaf-7)" |
| " (or leaf-8 leaf-1 leaf-3 leaf-7)" |
| " (or leaf-8 leaf-2 leaf-3 leaf-7)" |
| " (or leaf-8 leaf-0 leaf-4 leaf-7)" |
| " (or leaf-8 leaf-1 leaf-4 leaf-7)" |
| " (or leaf-8 leaf-2 leaf-4 leaf-7)" |
| " (or leaf-8 leaf-0 leaf-5 leaf-7)" |
| " (or leaf-8 leaf-1 leaf-5 leaf-7)" |
| " (or leaf-8 leaf-2 leaf-5 leaf-7))", |
| SearchArgumentBuilderImpl::convertToCNF(_or(NodeList { |
| _and(NodeList {_leaf(0), _leaf(1), _leaf(2)}), |
| _and(NodeList {_leaf(3), _leaf(4), _leaf(5)}), |
| _and(_leaf(6), _leaf(7)), |
| _leaf(8)}) |
| )->toString()); |
| EXPECT_EQ("YES_NO_NULL", SearchArgumentBuilderImpl::convertToCNF( |
| _or(NodeList {_and(_leaf(0), _leaf(1)), |
| _and(_leaf(2), _leaf(3)), |
| _and(_leaf(4), _leaf(5)), |
| _and(_leaf(6), _leaf(7)), |
| _and(_leaf(8), _leaf(9)), |
| _and(_leaf(10), _leaf(11)), |
| _and(_leaf(12), _leaf(13)), |
| _and(_leaf(14), _leaf(15)), |
| _and(_leaf(16), _leaf(17))}))->toString()); |
| EXPECT_EQ("(and leaf-100 YES_NO_NULL)", |
| SearchArgumentBuilderImpl::convertToCNF( |
| _and(_leaf(100), |
| _or(NodeList { |
| _and(_leaf(0), _leaf(1)), |
| _and(_leaf(2), _leaf(3)), |
| _and(_leaf(4), _leaf(5)), |
| _and(_leaf(6), _leaf(7)), |
| _and(_leaf(8), _leaf(9)), |
| _and(_leaf(10), _leaf(11)), |
| _and(_leaf(12), _leaf(13)), |
| _and(_leaf(14), _leaf(15)), |
| _and(_leaf(16), _leaf(17))})))->toString()); |
| |
| std::unordered_set<TreeNode> seen; |
| EXPECT_NO_THROW(assertNoSharedNodes( |
| SearchArgumentBuilderImpl::convertToCNF( |
| _or(NodeList {_and(NodeList { _leaf(0), _leaf(1), _leaf(2) }), |
| _and(NodeList { _leaf(3), _leaf(4), _leaf(5) }), |
| _and(_leaf(6), _leaf(7)), |
| _leaf(8)})), seen)); |
| } |
| |
| TEST(TestSearchArgument, testBuilder) { |
| auto sarg = SearchArgumentFactory::newBuilder() |
| ->startAnd() |
| .lessThan("x", PredicateDataType::LONG, |
| Literal(static_cast<int64_t>(10))) |
| .lessThanEquals("y", PredicateDataType::STRING, Literal("hi", 2)) |
| .equals("z", PredicateDataType::FLOAT, Literal(1.1)) |
| .end() |
| .build(); |
| EXPECT_EQ("leaf-0 = (x < 10), " |
| "leaf-1 = (y <= hi), " |
| "leaf-2 = (z = 1.1), " |
| "expr = (and leaf-0 leaf-1 leaf-2)", sarg->toString()); |
| sarg = SearchArgumentFactory::newBuilder() |
| ->startNot() |
| .startOr() |
| .isNull("x", PredicateDataType::LONG) |
| .between("y", PredicateDataType::LONG, |
| Literal(static_cast<int64_t>(10)), Literal(static_cast<int64_t>(20))) |
| .in("z", PredicateDataType::LONG, |
| {Literal(static_cast<int64_t>(1)), |
| Literal(static_cast<int64_t>(2)), Literal(static_cast<int64_t>(3))}) |
| .nullSafeEquals( |
| "a", PredicateDataType::STRING, Literal("stinger", 7)) |
| .end() |
| .end() |
| .build(); |
| EXPECT_EQ( |
| "leaf-0 = (x is null), " |
| "leaf-1 = (y between [10, 20]), " |
| "leaf-2 = (z in [1, 2, 3]), " |
| "leaf-3 = (a null_safe_= stinger), " |
| "expr = (and (not leaf-0) (not leaf-1) (not leaf-2) (not leaf-3))", |
| sarg->toString()); |
| } |
| |
| TEST(TestSearchArgument, testBuilderComplexTypes) { |
| auto sarg = SearchArgumentFactory::newBuilder() |
| ->startAnd() |
| .lessThan("x", PredicateDataType::DATE, // 1970-01-11 |
| Literal(PredicateDataType::DATE, 123456L)) |
| .lessThanEquals("y", PredicateDataType::STRING, |
| Literal("hi ", 10)) |
| .equals("z", PredicateDataType::DECIMAL, Literal(10, 2, 1)) |
| .end() |
| .build(); |
| EXPECT_EQ("leaf-0 = (x < 123456), " |
| "leaf-1 = (y <= hi ), " |
| "leaf-2 = (z = 1.0), " |
| "expr = (and leaf-0 leaf-1 leaf-2)", sarg->toString()); |
| |
| sarg = SearchArgumentFactory::newBuilder() |
| ->startNot() |
| .startOr() |
| .isNull("x", PredicateDataType::LONG) |
| .between("y", PredicateDataType::DECIMAL, |
| Literal(10, 3, 0), Literal(200, 3, 1)) |
| .in("z", PredicateDataType::LONG, |
| { Literal(static_cast<int64_t>(1)), |
| Literal(static_cast<int64_t>(2)), |
| Literal(static_cast<int64_t>(3)) }) |
| .nullSafeEquals("a", PredicateDataType::STRING, |
| Literal("stinger", 7)) |
| .end() |
| .end() |
| .build(); |
| EXPECT_EQ("leaf-0 = (x is null), " |
| "leaf-1 = (y between [10, 20.0]), " |
| "leaf-2 = (z in [1, 2, 3]), " |
| "leaf-3 = (a null_safe_= stinger), " |
| "expr = (and (not leaf-0) (not leaf-1) (not leaf-2) (not leaf-3))", |
| sarg->toString()); |
| } |
| |
| TEST(TestSearchArgument, testBuilderComplexTypes2) { |
| auto sarg = |
| SearchArgumentFactory::newBuilder() |
| ->startAnd() |
| .lessThan("x", PredicateDataType::DATE, |
| Literal(PredicateDataType::DATE, 11111L)) // "2005-3-12" |
| .lessThanEquals("y", PredicateDataType::STRING, |
| Literal("hi ", 10)) |
| .equals("z", PredicateDataType::DECIMAL, |
| Literal(10, 2, 1)) |
| .end() |
| .build(); |
| EXPECT_EQ("leaf-0 = (x < 11111), " |
| "leaf-1 = (y <= hi ), " |
| "leaf-2 = (z = 1.0), " |
| "expr = (and leaf-0 leaf-1 leaf-2)", sarg->toString()); |
| |
| sarg = SearchArgumentFactory::newBuilder() |
| ->startNot() |
| .startOr() |
| .isNull("x", PredicateDataType::LONG) |
| .between("y", PredicateDataType::DECIMAL, |
| Literal(10, 2, 0), Literal(200, 3, 1)) |
| .in("z", PredicateDataType::LONG, |
| { Literal(static_cast<int64_t>(1)), |
| Literal(static_cast<int64_t>(2)), |
| Literal(static_cast<int64_t>(3)) }) |
| .nullSafeEquals("a", PredicateDataType::STRING, |
| Literal("stinger", 7)) |
| .end() |
| .end() |
| .build(); |
| EXPECT_EQ("leaf-0 = (x is null), " |
| "leaf-1 = (y between [10, 20.0]), " |
| "leaf-2 = (z in [1, 2, 3]), " |
| "leaf-3 = (a null_safe_= stinger), " |
| "expr = (and (not leaf-0) (not leaf-1) (not leaf-2) (not leaf-3))", |
| sarg->toString()); |
| } |
| |
| TEST(TestSearchArgument, testBuilderFloat) { |
| auto sarg = SearchArgumentFactory::newBuilder() |
| ->startAnd() |
| .lessThan("x", PredicateDataType::LONG, |
| Literal(static_cast<int64_t>(22))) |
| .lessThan("x1", PredicateDataType::LONG, |
| Literal(static_cast<int64_t>(22))) |
| .lessThanEquals("y", PredicateDataType::STRING, |
| Literal("hi ", 10)) |
| .equals("z", PredicateDataType::FLOAT, Literal(0.22)) |
| .equals("z1", PredicateDataType::FLOAT, Literal(0.22)) |
| .end() |
| .build(); |
| EXPECT_EQ("leaf-0 = (x < 22), " |
| "leaf-1 = (x1 < 22), " |
| "leaf-2 = (y <= hi ), " |
| "leaf-3 = (z = 0.22), " |
| "leaf-4 = (z1 = 0.22), " |
| "expr = (and leaf-0 leaf-1 leaf-2 leaf-3 leaf-4)", |
| sarg->toString()); |
| } |
| |
| TEST(TestSearchArgument, testBadLiteral) { |
| EXPECT_THROW( |
| SearchArgumentFactory::newBuilder() |
| ->startAnd() |
| .lessThan("x", PredicateDataType::LONG, Literal("hi", 2)) |
| .end() |
| .build(), |
| std::invalid_argument); |
| } |
| |
| TEST(TestSearchArgument, testBadLiteralList) { |
| EXPECT_THROW( |
| SearchArgumentFactory::newBuilder() |
| ->startAnd() |
| .in("x", PredicateDataType::STRING, |
| {Literal("hi ", 23)}) |
| .end() |
| .build(), |
| std::invalid_argument); |
| } |
| |
| } // namespace orc |