// // Copyright 2017 Memgraph // Created by Mislav Bradac on 27.03.17. // #include #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "query/frontend/ast/ast.hpp" #include "query/frontend/opencypher/parser.hpp" #include "query/interpret/awesome_memgraph_functions.hpp" #include "query/interpret/eval.hpp" using namespace query; struct NoContextExpressionEvaluator { NoContextExpressionEvaluator() {} Frame frame{0}; SymbolTable symbol_table; ExpressionEvaluator eval{frame, symbol_table}; }; TEST(ExpressionEvaluator, OrOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(true), storage.Create(false)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(true), storage.Create(true)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); } TEST(ExpressionEvaluator, XorOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(true), storage.Create(false)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(true), storage.Create(true)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); } TEST(ExpressionEvaluator, AndOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(true), storage.Create(true)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(false), storage.Create(true)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); } TEST(ExpressionEvaluator, AdditionOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(2), storage.Create(3)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), 5); } TEST(ExpressionEvaluator, SubtractionOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(2), storage.Create(3)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), -1); } TEST(ExpressionEvaluator, MultiplicationOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(2), storage.Create(3)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), 6); } TEST(ExpressionEvaluator, DivisionOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(50), storage.Create(10)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), 5); } TEST(ExpressionEvaluator, ModOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(65), storage.Create(10)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), 5); } TEST(ExpressionEvaluator, EqualOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(10), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); op = storage.Create(storage.Create(15), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(20), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); } TEST(ExpressionEvaluator, NotEqualOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(10), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(15), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); op = storage.Create(storage.Create(20), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); } TEST(ExpressionEvaluator, LessOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(10), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(15), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); op = storage.Create(storage.Create(20), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); } TEST(ExpressionEvaluator, GreaterOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(10), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); op = storage.Create(storage.Create(15), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); op = storage.Create(storage.Create(20), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); } TEST(ExpressionEvaluator, LessEqualOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(10), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(15), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(20), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); } TEST(ExpressionEvaluator, GreaterEqualOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(10), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); op = storage.Create(storage.Create(15), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); op = storage.Create(storage.Create(20), storage.Create(15)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); } TEST(ExpressionEvaluator, NotOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(false)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); } TEST(ExpressionEvaluator, UnaryPlusOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(5)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), 5); } TEST(ExpressionEvaluator, UnaryMinusOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(5)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), -5); } TEST(ExpressionEvaluator, IsNullOperator) { AstTreeStorage storage; NoContextExpressionEvaluator eval; auto *op = storage.Create(storage.Create(1)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), false); op = storage.Create(storage.Create(TypedValue::Null)); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); } TEST(ExpressionEvaluator, Function) { AstTreeStorage storage; NoContextExpressionEvaluator eval; { std::vector arguments = { storage.Create(TypedValue::Null)}; auto *op = storage.Create(NameToFunction("ABS"), arguments); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().type(), TypedValue::Type::Null); } { std::vector arguments = {storage.Create(-2)}; auto *op = storage.Create(NameToFunction("ABS"), arguments); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), 2); } { std::vector arguments = {storage.Create(-2.5)}; auto *op = storage.Create(NameToFunction("ABS"), arguments); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), 2.5); } { std::vector arguments = {storage.Create(true)}; auto *op = storage.Create(NameToFunction("ABS"), arguments); op->Accept(eval.eval); ASSERT_EQ(eval.eval.PopBack().Value(), true); } { std::vector arguments = { storage.Create(std::vector(5))}; auto *op = storage.Create(NameToFunction("ABS"), arguments); ASSERT_THROW(op->Accept(eval.eval), QueryRuntimeException); } } TEST(ExpressionEvaluator, Aggregation) { AstTreeStorage storage; auto aggr = storage.Create(storage.Create(42), Aggregation::Op::COUNT); SymbolTable symbol_table; auto aggr_sym = symbol_table.CreateSymbol("aggr"); symbol_table[*aggr] = aggr_sym; Frame frame{symbol_table.max_position()}; frame[aggr_sym] = TypedValue(1); ExpressionEvaluator eval{frame, symbol_table}; aggr->Accept(eval); EXPECT_EQ(eval.PopBack().Value(), 1); }