Query::AST::Literal refactor. Repl and TypedValue mods.

Summary:
- Query::AST::Literal refactor (LiteralBase introduced, ListLiteral added)
- Repl now prints out list TypedValues properly
- TypedValue to string conversion refactors

Reviewers: teon.banek, mislav.bradac, buda

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D327
This commit is contained in:
florijan 2017-04-28 12:06:18 +02:00
parent 9653c703dc
commit 2e5eccf197
14 changed files with 292 additions and 176 deletions

View File

@ -8,6 +8,7 @@
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
#include "query/exceptions.hpp"
#include "query/interpreter.hpp"
@ -55,16 +56,7 @@ std::string ReadLine(const char *prompt) {
*/
std::string TypedValueToString(const query::TypedValue &value) {
std::stringstream ss;
switch (value.type()) {
case query::TypedValue::Type::List:
break;
case query::TypedValue::Type::Map:
break;
case query::TypedValue::Type::Path:
break;
default:
ss << value;
}
ss << value;
return ss.str();
}
@ -121,9 +113,10 @@ void PrintResults(ResultStreamFaker results) {
// output the summary
std::cout << "Query summary: {";
PrintIterable(std::cout, results.GetSummary(), ", ", [&](const auto kv) {
return kv.first + ": " + TypedValueToString(kv.second);
});
PrintIterable(std::cout, results.GetSummary(), ", ",
[&](auto &stream, const auto &kv) {
stream << kv.first << ": " << kv.second;
});
std::cout << "}" << std::endl;
}

View File

@ -361,7 +361,14 @@ class IsNullOperator : public UnaryOperator {
using UnaryOperator::UnaryOperator;
};
class Literal : public Expression {
class BaseLiteral : public Expression {
friend class AstTreeStorage;
protected:
BaseLiteral(int uid) : Expression(uid) {}
};
class PrimitiveLiteral : public BaseLiteral {
friend class AstTreeStorage;
public:
@ -369,9 +376,29 @@ class Literal : public Expression {
DEFVISITABLE(TreeVisitorBase);
protected:
Literal(int uid) : Expression(uid) {}
PrimitiveLiteral(int uid) : BaseLiteral(uid) {}
template <typename T>
Literal(int uid, T value) : Expression(uid), value_(value) {}
PrimitiveLiteral(int uid, T value) : BaseLiteral(uid), value_(value) {}
};
class ListLiteral : public BaseLiteral {
friend class AstTreeStorage;
public:
const std::vector<Expression *> elements_;
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
for (auto expr_ptr : elements_)
expr_ptr->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
ListLiteral(int uid) : BaseLiteral(uid) {}
ListLiteral(int uid, const std::vector<Expression *> &elements)
: BaseLiteral(uid), elements_(elements) {}
};
class Identifier : public Expression {

View File

@ -18,7 +18,8 @@ class With;
class Pattern;
class NodeAtom;
class EdgeAtom;
class Literal;
class PrimitiveLiteral;
class ListLiteral;
class OrOperator;
class XorOperator;
class AndOperator;
@ -51,8 +52,8 @@ using TreeVisitorBase = ::utils::Visitor<
AdditionOperator, SubtractionOperator, MultiplicationOperator,
DivisionOperator, ModOperator, NotEqualOperator, EqualOperator,
LessOperator, GreaterOperator, LessEqualOperator, GreaterEqualOperator,
UnaryPlusOperator, UnaryMinusOperator, IsNullOperator, Identifier, Literal,
PropertyLookup, Aggregation, Function, Create, Match, Return, With, Pattern,
NodeAtom, EdgeAtom, Delete, Where, SetProperty, SetProperties, SetLabels,
RemoveProperty, RemoveLabels, Merge>;
UnaryPlusOperator, UnaryMinusOperator, IsNullOperator, Identifier,
PrimitiveLiteral, ListLiteral, PropertyLookup, Aggregation, Function,
Create, Match, Return, With, Pattern, NodeAtom, EdgeAtom, Delete, Where,
SetProperty, SetProperties, SetLabels, RemoveProperty, RemoveLabels, Merge>;
}

View File

@ -273,6 +273,14 @@ antlrcpp::Any CypherMainVisitor::visitMapLiteral(
return map;
}
antlrcpp::Any CypherMainVisitor::visitListLiteral(
CypherParser::ListLiteralContext *ctx) {
std::vector<Expression *> expressions;
for (auto expr_ctx_ptr : ctx->expression())
expressions.push_back(expr_ctx_ptr->accept(this));
return expressions;
}
antlrcpp::Any CypherMainVisitor::visitPropertyKeyName(
CypherParser::PropertyKeyNameContext *ctx) {
return ctx_.db_accessor_.property(visitChildren(ctx));
@ -606,7 +614,8 @@ antlrcpp::Any CypherMainVisitor::visitExpression2(
antlrcpp::Any CypherMainVisitor::visitAtom(CypherParser::AtomContext *ctx) {
if (ctx->literal()) {
return static_cast<Expression *>(visitChildren(ctx).as<Literal *>());
return static_cast<Expression *>(
ctx->literal()->accept(this).as<BaseLiteral *>());
} else if (ctx->parameter()) {
// TODO: implement other clauses.
throw utils::NotYetImplemented();
@ -628,18 +637,22 @@ antlrcpp::Any CypherMainVisitor::visitAtom(CypherParser::AtomContext *ctx) {
antlrcpp::Any CypherMainVisitor::visitLiteral(
CypherParser::LiteralContext *ctx) {
if (ctx->CYPHERNULL()) {
return storage_.Create<Literal>(TypedValue::Null);
return static_cast<BaseLiteral *>(
storage_.Create<PrimitiveLiteral>(TypedValue::Null));
} else if (ctx->StringLiteral()) {
return storage_.Create<Literal>(
visitStringLiteral(ctx->StringLiteral()->getText()).as<std::string>());
return static_cast<BaseLiteral *>(storage_.Create<PrimitiveLiteral>(
visitStringLiteral(ctx->StringLiteral()->getText()).as<std::string>()));
} else if (ctx->booleanLiteral()) {
return storage_.Create<Literal>(
ctx->booleanLiteral()->accept(this).as<bool>());
return static_cast<BaseLiteral *>(storage_.Create<PrimitiveLiteral>(
ctx->booleanLiteral()->accept(this).as<bool>()));
} else if (ctx->numberLiteral()) {
return storage_.Create<Literal>(
ctx->numberLiteral()->accept(this).as<TypedValue>());
return static_cast<BaseLiteral *>(storage_.Create<PrimitiveLiteral>(
ctx->numberLiteral()->accept(this).as<TypedValue>()));
} else if (ctx->listLiteral()) {
return static_cast<BaseLiteral *>(storage_.Create<ListLiteral>(
ctx->listLiteral()->accept(this).as<std::vector<Expression *>>()));
} else {
// TODO: Implement map and list literals.
// TODO: Implement map literal.
throw utils::NotYetImplemented();
}
return visitChildren(ctx);

View File

@ -205,6 +205,11 @@ class CypherMainVisitor : public antlropencypher::CypherBaseVisitor {
*/
antlrcpp::Any visitMapLiteral(CypherParser::MapLiteralContext *ctx) override;
/**
* @return vector<Expression*>
*/
antlrcpp::Any visitListLiteral(CypherParser::ListLiteralContext *ctx) override;
/**
* @return GraphDbTypes::Property
*/
@ -393,7 +398,7 @@ class CypherMainVisitor : public antlropencypher::CypherBaseVisitor {
CypherParser::FunctionNameContext *ctx) override;
/**
* @return Literal*
* @return BaseLiteral*
*/
antlrcpp::Any visitLiteral(CypherParser::LiteralContext *ctx) override;

View File

@ -2,6 +2,7 @@
#include <map>
#include <vector>
#include <algorithm>
#include "database/graph_db_accessor.hpp"
#include "query/common.hpp"
@ -117,12 +118,21 @@ class ExpressionEvaluator : public TreeVisitorBase {
}
}
void Visit(Literal &literal) override {
void Visit(PrimitiveLiteral &literal) override {
// TODO: no need to evaluate constants, we can write it to frame in one
// of the previous phases.
result_stack_.push_back(literal.value_);
}
void PostVisit(ListLiteral &literal) override {
std::vector<TypedValue> result;
result.reserve(literal.elements_.size());
for (size_t i = 0 ; i < literal.elements_.size() ; i++)
result.emplace_back(PopBack());
std::reverse(result.begin(), result.end());
result_stack_.emplace_back(std::move(result));
}
bool PreVisit(Aggregation &aggregation) override {
auto value = frame_[symbol_table_.at(aggregation)];
// Aggregation is probably always simple type, but let's switch accessor

View File

@ -256,7 +256,9 @@ class ReturnBodyContext : public TreeVisitorBase {
using TreeVisitorBase::Visit;
using TreeVisitorBase::PostVisit;
void Visit(Literal &) override { has_aggregation_.emplace_back(false); }
void Visit(PrimitiveLiteral &) override { has_aggregation_.emplace_back(false); }
void Visit(ListLiteral &) override { has_aggregation_.emplace_back(false); }
void Visit(Identifier &ident) override {
const auto &symbol = symbol_table_.at(ident);

View File

@ -5,6 +5,7 @@
#include <iostream>
#include <memory>
#include "utils/algorithm.hpp"
#include "utils/assert.hpp"
#include "utils/exceptions.hpp"
#include "utils/hashing/fnv.hpp"
@ -295,15 +296,14 @@ std::ostream &operator<<(std::ostream &os, const TypedValue &value) {
return os << value.Value<std::string>();
case TypedValue::Type::List:
os << "[";
for (const auto &x : value.Value<std::vector<TypedValue>>()) {
os << x << ",";
}
PrintIterable(os, value.Value<std::vector<TypedValue>>());
return os << "]";
case TypedValue::Type::Map:
os << "{";
for (const auto &x : value.Value<std::map<std::string, TypedValue>>()) {
os << x.first << ": " << x.second << ",";
}
PrintIterable(os, value.Value<std::map<std::string, TypedValue>>(), ", ",
[](auto &stream, const auto &pair) {
stream << pair.first << ": " << pair.second;
});
return os << "}";
case TypedValue::Type::Vertex:
return os << value.Value<VertexAccessor>();
@ -707,8 +707,7 @@ TypedValue operator&&(const TypedValue &a, const TypedValue &b) {
// if either operand is false, the result is false
if (a.type() == TypedValue::Type::Bool && !a.Value<bool>()) return false;
if (b.type() == TypedValue::Type::Bool && !b.Value<bool>()) return false;
if (a.IsNull() || b.IsNull())
return TypedValue::Null;
if (a.IsNull() || b.IsNull()) return TypedValue::Null;
// neither is false, neither is null, thus both are true
return true;
}
@ -719,21 +718,18 @@ TypedValue operator||(const TypedValue &a, const TypedValue &b) {
// if either operand is true, the result is true
if (a.type() == TypedValue::Type::Bool && a.Value<bool>()) return true;
if (b.type() == TypedValue::Type::Bool && b.Value<bool>()) return true;
if (a.IsNull() || b.IsNull())
return TypedValue::Null;
if (a.IsNull() || b.IsNull()) return TypedValue::Null;
// neither is true, neither is null, thus both are false
return false;
}
TypedValue operator^(const TypedValue &a, const TypedValue &b) {
EnsureLogicallyOk(a,b, "logical XOR");
EnsureLogicallyOk(a, b, "logical XOR");
// at this point we only have null and bool
if (a.IsNull() ||
b.IsNull())
return TypedValue::Null;
else
return static_cast<bool>(a.Value<bool>() ^ b.Value<bool>());
if (a.IsNull() || b.IsNull())
return TypedValue::Null;
else
return static_cast<bool>(a.Value<bool>() ^ b.Value<bool>());
}
bool TypedValue::BoolEqual::operator()(const TypedValue &lhs,

View File

@ -22,11 +22,8 @@ bool EdgeAccessor::is_cycle() const {
std::ostream &operator<<(std::ostream &os, const EdgeAccessor &ea) {
os << "E[" << ea.db_accessor().edge_type_name(ea.edge_type());
os << " {";
auto prop_to_string = [&](const auto kv) {
std::stringstream ss;
ss << ea.db_accessor().property_name(kv.first) << ": " << kv.second;
return ss.str();
};
PrintIterable(os, ea.Properties(), ", ", prop_to_string);
PrintIterable(os, ea.Properties(), ", ", [&](auto &stream, const auto &pair) {
stream << ea.db_accessor().property_name(pair.first) << ": " << pair.second;
});
return os << "}]";
}

View File

@ -43,14 +43,12 @@ const std::vector<GraphDbTypes::Label> &VertexAccessor::labels() const {
std::ostream &operator<<(std::ostream &os, const VertexAccessor &va) {
os << "V(";
PrintIterable(os, va.labels(), ":",
[&](auto label) { return va.db_accessor().label_name(label); });
PrintIterable(os, va.labels(), ":", [&](auto &stream, auto label) {
stream << va.db_accessor().label_name(label);
});
os << " {";
auto prop_to_string = [&](const auto kv) {
std::stringstream ss;
ss << va.db_accessor().property_name(kv.first) << ": " << kv.second;
return ss.str();
};
PrintIterable(os, va.Properties(), ", ", prop_to_string);
PrintIterable(os, va.Properties(), ", ", [&](auto &stream, const auto &pair) {
stream << va.db_accessor().property_name(pair.first) << ": " << pair.second;
});
return os << "})";
}

View File

@ -31,19 +31,33 @@ ForwardIt action_remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p,
* @param stream Destination stream.
* @param iterable An iterable collection of items.
* @param delim Delimiter that is put between items.
* @param converter Function which converts an item to a type which supports
* @c operator<<.
* @param streamer Function which accepts a TStream and an item and
* streams the item to the stream.
*/
template <typename TStream, typename TIterable, typename TConverter>
template <typename TStream, typename TIterable, typename TStreamer>
void PrintIterable(TStream &stream, const TIterable &iterable,
const std::string &delim = ", ", TConverter converter = {}) {
const std::string &delim = ", ", TStreamer streamer = {}) {
bool first = true;
for (const auto &item : iterable) {
if (first)
first = false;
else
stream << delim;
stream << converter(item);
streamer(stream, item);
}
}
/**
* Outputs a collection of items to the given stream, separating them with the
* given delimiter.
*
* @param stream Destination stream.
* @param iterable An iterable collection of items.
* @param delim Delimiter that is put between items.
*/
template <typename TStream, typename TIterable>
void PrintIterable(TStream &stream, const TIterable &iterable,
const std::string &delim = ", ") {
PrintIterable(stream, iterable, delim,
[](auto &stream, const auto &item) { stream << item; });
}

View File

@ -94,7 +94,7 @@ TEST(CypherMainVisitor, ReturnLimit) {
ASSERT_EQ(query->clauses_.size(), 1U);
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
ASSERT_TRUE(return_clause->body_.limit);
auto *literal = dynamic_cast<Literal *>(return_clause->body_.limit);
auto *literal = dynamic_cast<PrimitiveLiteral *>(return_clause->body_.limit);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<int64_t>(), 5);
}
@ -105,7 +105,7 @@ TEST(CypherMainVisitor, ReturnSkip) {
ASSERT_EQ(query->clauses_.size(), 1U);
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
ASSERT_TRUE(return_clause->body_.skip);
auto *literal = dynamic_cast<Literal *>(return_clause->body_.skip);
auto *literal = dynamic_cast<PrimitiveLiteral *>(return_clause->body_.skip);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<int64_t>(), 5);
}
@ -140,7 +140,7 @@ TEST(CypherMainVisitorTest, IntegerLiteral) {
AstGenerator ast_generator("RETURN 42");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<int64_t>(), 42);
@ -155,7 +155,7 @@ TEST(CypherMainVisitorTest, BooleanLiteralTrue) {
AstGenerator ast_generator("RETURN TrUe");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<bool>(), true);
@ -165,7 +165,7 @@ TEST(CypherMainVisitorTest, BooleanLiteralFalse) {
AstGenerator ast_generator("RETURN faLSE");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<bool>(), false);
@ -175,7 +175,7 @@ TEST(CypherMainVisitorTest, NullLiteral) {
AstGenerator ast_generator("RETURN nULl");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.type(), TypedValue::Type::Null);
@ -185,7 +185,7 @@ TEST(CypherMainVisitorTest, ParenthesizedExpression) {
AstGenerator ast_generator("RETURN (2)");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<int64_t>(), 2);
@ -201,10 +201,10 @@ TEST(CypherMainVisitorTest, OrOperator) {
ASSERT_TRUE(or_operator2);
auto *or_operator1 = dynamic_cast<OrOperator *>(or_operator2->expression1_);
ASSERT_TRUE(or_operator1);
auto *operand1 = dynamic_cast<Literal *>(or_operator1->expression1_);
auto *operand1 = dynamic_cast<PrimitiveLiteral *>(or_operator1->expression1_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<bool>(), true);
auto *operand2 = dynamic_cast<Literal *>(or_operator1->expression2_);
auto *operand2 = dynamic_cast<PrimitiveLiteral *>(or_operator1->expression2_);
ASSERT_TRUE(operand2);
ASSERT_EQ(operand2->value_.Value<bool>(), false);
auto *operand3 = dynamic_cast<Identifier *>(or_operator2->expression2_);
@ -218,10 +218,10 @@ TEST(CypherMainVisitorTest, XorOperator) {
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *xor_operator = dynamic_cast<XorOperator *>(
return_clause->body_.named_expressions[0]->expression_);
auto *operand1 = dynamic_cast<Literal *>(xor_operator->expression1_);
auto *operand1 = dynamic_cast<PrimitiveLiteral *>(xor_operator->expression1_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<bool>(), true);
auto *operand2 = dynamic_cast<Literal *>(xor_operator->expression2_);
auto *operand2 = dynamic_cast<PrimitiveLiteral *>(xor_operator->expression2_);
ASSERT_TRUE(operand2);
ASSERT_EQ(operand2->value_.Value<bool>(), false);
}
@ -232,10 +232,10 @@ TEST(CypherMainVisitorTest, AndOperator) {
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *and_operator = dynamic_cast<AndOperator *>(
return_clause->body_.named_expressions[0]->expression_);
auto *operand1 = dynamic_cast<Literal *>(and_operator->expression1_);
auto *operand1 = dynamic_cast<PrimitiveLiteral *>(and_operator->expression1_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<bool>(), true);
auto *operand2 = dynamic_cast<Literal *>(and_operator->expression2_);
auto *operand2 = dynamic_cast<PrimitiveLiteral *>(and_operator->expression2_);
ASSERT_TRUE(operand2);
ASSERT_EQ(operand2->value_.Value<bool>(), false);
}
@ -250,13 +250,16 @@ TEST(CypherMainVisitorTest, AdditionSubtractionOperators) {
auto *subtraction_operator =
dynamic_cast<SubtractionOperator *>(addition_operator->expression1_);
ASSERT_TRUE(subtraction_operator);
auto *operand1 = dynamic_cast<Literal *>(subtraction_operator->expression1_);
auto *operand1 =
dynamic_cast<PrimitiveLiteral *>(subtraction_operator->expression1_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<int64_t>(), 1);
auto *operand2 = dynamic_cast<Literal *>(subtraction_operator->expression2_);
auto *operand2 =
dynamic_cast<PrimitiveLiteral *>(subtraction_operator->expression2_);
ASSERT_TRUE(operand2);
ASSERT_EQ(operand2->value_.Value<int64_t>(), 2);
auto *operand3 = dynamic_cast<Literal *>(addition_operator->expression2_);
auto *operand3 =
dynamic_cast<PrimitiveLiteral *>(addition_operator->expression2_);
ASSERT_TRUE(operand3);
ASSERT_EQ(operand3->value_.Value<int64_t>(), 3);
}
@ -267,10 +270,12 @@ TEST(CypherMainVisitorTest, MulitplicationOperator) {
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *mult_operator = dynamic_cast<MultiplicationOperator *>(
return_clause->body_.named_expressions[0]->expression_);
auto *operand1 = dynamic_cast<Literal *>(mult_operator->expression1_);
auto *operand1 =
dynamic_cast<PrimitiveLiteral *>(mult_operator->expression1_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<int64_t>(), 2);
auto *operand2 = dynamic_cast<Literal *>(mult_operator->expression2_);
auto *operand2 =
dynamic_cast<PrimitiveLiteral *>(mult_operator->expression2_);
ASSERT_TRUE(operand2);
ASSERT_EQ(operand2->value_.Value<int64_t>(), 3);
}
@ -281,10 +286,10 @@ TEST(CypherMainVisitorTest, DivisionOperator) {
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *div_operator = dynamic_cast<DivisionOperator *>(
return_clause->body_.named_expressions[0]->expression_);
auto *operand1 = dynamic_cast<Literal *>(div_operator->expression1_);
auto *operand1 = dynamic_cast<PrimitiveLiteral *>(div_operator->expression1_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<int64_t>(), 2);
auto *operand2 = dynamic_cast<Literal *>(div_operator->expression2_);
auto *operand2 = dynamic_cast<PrimitiveLiteral *>(div_operator->expression2_);
ASSERT_TRUE(operand2);
ASSERT_EQ(operand2->value_.Value<int64_t>(), 3);
}
@ -295,10 +300,10 @@ TEST(CypherMainVisitorTest, ModOperator) {
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *mod_operator = dynamic_cast<ModOperator *>(
return_clause->body_.named_expressions[0]->expression_);
auto *operand1 = dynamic_cast<Literal *>(mod_operator->expression1_);
auto *operand1 = dynamic_cast<PrimitiveLiteral *>(mod_operator->expression1_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<int64_t>(), 2);
auto *operand2 = dynamic_cast<Literal *>(mod_operator->expression2_);
auto *operand2 = dynamic_cast<PrimitiveLiteral *>(mod_operator->expression2_);
ASSERT_TRUE(operand2);
ASSERT_EQ(operand2->value_.Value<int64_t>(), 3);
}
@ -310,9 +315,11 @@ TEST(CypherMainVisitorTest, ModOperator) {
_operator = and_operator->expression1_; \
auto *cmp_operator = dynamic_cast<TYPE *>(and_operator->expression2_); \
ASSERT_TRUE(cmp_operator); \
auto *operand1 = dynamic_cast<Literal *>(cmp_operator->expression1_); \
auto *operand1 = \
dynamic_cast<PrimitiveLiteral *>(cmp_operator->expression1_); \
ASSERT_EQ(operand1->value_.Value<int64_t>(), VALUE1); \
auto *operand2 = dynamic_cast<Literal *>(cmp_operator->expression2_); \
auto *operand2 = \
dynamic_cast<PrimitiveLiteral *>(cmp_operator->expression2_); \
ASSERT_EQ(operand2->value_.Value<int64_t>(), VALUE2); \
} while (0)
@ -330,9 +337,9 @@ TEST(CypherMainVisitorTest, ComparisonOperators) {
CHECK_COMPARISON(NotEqualOperator, 3, 4);
auto *cmp_operator = dynamic_cast<EqualOperator *>(_operator);
ASSERT_TRUE(cmp_operator);
auto *operand1 = dynamic_cast<Literal *>(cmp_operator->expression1_);
auto *operand1 = dynamic_cast<PrimitiveLiteral *>(cmp_operator->expression1_);
ASSERT_EQ(operand1->value_.Value<int64_t>(), 2);
auto *operand2 = dynamic_cast<Literal *>(cmp_operator->expression2_);
auto *operand2 = dynamic_cast<PrimitiveLiteral *>(cmp_operator->expression2_);
ASSERT_EQ(operand2->value_.Value<int64_t>(), 3);
}
@ -344,7 +351,8 @@ TEST(CypherMainVisitorTest, IsNull) {
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *is_type_operator = dynamic_cast<IsNullOperator *>(
return_clause->body_.named_expressions[0]->expression_);
auto *operand1 = dynamic_cast<Literal *>(is_type_operator->expression_);
auto *operand1 =
dynamic_cast<PrimitiveLiteral *>(is_type_operator->expression_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<int64_t>(), 2);
}
@ -357,7 +365,8 @@ TEST(CypherMainVisitorTest, IsNotNull) {
return_clause->body_.named_expressions[0]->expression_);
auto *is_type_operator =
dynamic_cast<IsNullOperator *>(not_operator->expression_);
auto *operand1 = dynamic_cast<Literal *>(is_type_operator->expression_);
auto *operand1 =
dynamic_cast<PrimitiveLiteral *>(is_type_operator->expression_);
ASSERT_TRUE(operand1);
ASSERT_EQ(operand1->value_.Value<int64_t>(), 2);
}
@ -368,7 +377,7 @@ TEST(CypherMainVisitorTest, NotOperator) {
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *not_operator = dynamic_cast<NotOperator *>(
return_clause->body_.named_expressions[0]->expression_);
auto *operand = dynamic_cast<Literal *>(not_operator->expression_);
auto *operand = dynamic_cast<PrimitiveLiteral *>(not_operator->expression_);
ASSERT_TRUE(operand);
ASSERT_EQ(operand->value_.Value<bool>(), true);
}
@ -383,7 +392,8 @@ TEST(CypherMainVisitorTest, UnaryMinusPlusOperators) {
auto *unary_plus_operator =
dynamic_cast<UnaryPlusOperator *>(unary_minus_operator->expression_);
ASSERT_TRUE(unary_plus_operator);
auto *operand = dynamic_cast<Literal *>(unary_plus_operator->expression_);
auto *operand =
dynamic_cast<PrimitiveLiteral *>(unary_plus_operator->expression_);
ASSERT_TRUE(operand);
ASSERT_EQ(operand->value_.Value<int64_t>(), 5);
}
@ -430,7 +440,7 @@ TEST(CypherMainVisitorTest, StringLiteralDoubleQuotes) {
AstGenerator ast_generator("RETURN \"mi'rko\"");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<std::string>(), "mi'rko");
@ -440,7 +450,7 @@ TEST(CypherMainVisitorTest, StringLiteralSingleQuotes) {
AstGenerator ast_generator("RETURN 'mi\"rko'");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<std::string>(), "mi\"rko");
@ -451,7 +461,7 @@ TEST(CypherMainVisitorTest, StringLiteralEscapedChars) {
"RETURN '\\\\\\'\\\"\\b\\B\\f\\F\\n\\N\\r\\R\\t\\T'");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<std::string>(), "\\'\"\b\b\f\f\n\n\r\r\t\t");
@ -461,7 +471,7 @@ TEST(CypherMainVisitorTest, StringLiteralEscapedUtf16) {
AstGenerator ast_generator("RETURN '\\u221daaa\\U221daaa'");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<std::string>(), u8"\u221daaa\u221daaa");
@ -471,7 +481,7 @@ TEST(CypherMainVisitorTest, StringLiteralEscapedUtf32) {
AstGenerator ast_generator("RETURN '\\u0001F600aaaa\\U0001F600aaaaaaaa'");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<std::string>(),
@ -482,7 +492,7 @@ TEST(CypherMainVisitorTest, DoubleLiteral) {
AstGenerator ast_generator("RETURN 3.5");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<double>(), 3.5);
@ -492,12 +502,31 @@ TEST(CypherMainVisitorTest, DoubleLiteralExponent) {
AstGenerator ast_generator("RETURN 5e-1");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *literal = dynamic_cast<Literal *>(
auto *literal = dynamic_cast<PrimitiveLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(literal);
ASSERT_EQ(literal->value_.Value<double>(), 0.5);
}
TEST(CypherMainVisitorTest, ListLiteral) {
AstGenerator ast_generator("RETURN [3, [], 'johhny']");
auto *query = ast_generator.query_;
auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]);
auto *list_literal = dynamic_cast<ListLiteral *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(list_literal);
ASSERT_EQ(3, list_literal->elements_.size());
auto *elem_0 = dynamic_cast<PrimitiveLiteral *>(list_literal->elements_[0]);
ASSERT_TRUE(elem_0);
EXPECT_EQ(elem_0->value_.type(), TypedValue::Type::Int);
auto *elem_1 = dynamic_cast<ListLiteral *>(list_literal->elements_[1]);
ASSERT_TRUE(elem_1);
EXPECT_EQ(0, elem_1->elements_.size());
auto *elem_2 = dynamic_cast<PrimitiveLiteral *>(list_literal->elements_[2]);
ASSERT_TRUE(elem_2);
EXPECT_EQ(elem_2->value_.type(), TypedValue::Type::String);
}
TEST(CypherMainVisitorTest, NodePattern) {
AstGenerator ast_generator(
"MATCH (:label1:label2:label3 {a : 5, b : 10}) RETURN 1");
@ -521,7 +550,7 @@ TEST(CypherMainVisitorTest, NodePattern) {
ast_generator.db_accessor_->label("label3")));
std::unordered_map<GraphDbTypes::Property, int64_t> properties;
for (auto x : node->properties_) {
auto *literal = dynamic_cast<Literal *>(x.second);
auto *literal = dynamic_cast<PrimitiveLiteral *>(x.second);
ASSERT_TRUE(literal);
ASSERT_TRUE(literal->value_.type() == TypedValue::Type::Int);
properties[x.first] = literal->value_.Value<int64_t>();
@ -608,7 +637,7 @@ TEST(CypherMainVisitorTest, RelationshipPatternDetails) {
ast_generator.db_accessor_->edge_type("type2")));
std::unordered_map<GraphDbTypes::Property, int64_t> properties;
for (auto x : edge->properties_) {
auto *literal = dynamic_cast<Literal *>(x.second);
auto *literal = dynamic_cast<PrimitiveLiteral *>(x.second);
ASSERT_TRUE(literal);
ASSERT_TRUE(literal->value_.type() == TypedValue::Type::Int);
properties[x.first] = literal->value_.Value<int64_t>();
@ -976,5 +1005,4 @@ TEST(CypherMainVisitorTest, Merge) {
ASSERT_EQ(merge->on_create_.size(), 1U);
EXPECT_TRUE(dynamic_cast<SetLabels *>(merge->on_create_[0]));
}
}

View File

@ -356,7 +356,7 @@ auto GetMerge(AstTreeStorage &storage, Pattern *pattern, OnMatch on_match,
query::test_common::GetWithPatterns(storage.Create<query::Create>(), \
{__VA_ARGS__})
#define IDENT(name) storage.Create<query::Identifier>((name))
#define LITERAL(val) storage.Create<query::Literal>((val))
#define LITERAL(val) storage.Create<query::PrimitiveLiteral>((val))
#define PROPERTY_LOOKUP(...) \
query::test_common::GetPropertyLookup(storage, __VA_ARGS__)
#define NEXPR(name, expr) storage.Create<query::NamedExpression>((name), (expr))

View File

@ -37,7 +37,7 @@ TypedValue EvaluateFunction(const std::string &function_name,
std::vector<Expression *> expressions;
for (const auto &arg : args) {
expressions.push_back(storage.Create<Literal>(arg));
expressions.push_back(storage.Create<PrimitiveLiteral>(arg));
}
auto *op =
storage.Create<Function>(NameToFunction(function_name), expressions);
@ -48,12 +48,13 @@ TypedValue EvaluateFunction(const std::string &function_name,
TEST(ExpressionEvaluator, OrOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<OrOperator>(storage.Create<Literal>(true),
storage.Create<Literal>(false));
auto *op =
storage.Create<OrOperator>(storage.Create<PrimitiveLiteral>(true),
storage.Create<PrimitiveLiteral>(false));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<OrOperator>(storage.Create<Literal>(true),
storage.Create<Literal>(true));
op = storage.Create<OrOperator>(storage.Create<PrimitiveLiteral>(true),
storage.Create<PrimitiveLiteral>(true));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
@ -61,12 +62,13 @@ TEST(ExpressionEvaluator, OrOperator) {
TEST(ExpressionEvaluator, XorOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<XorOperator>(storage.Create<Literal>(true),
storage.Create<Literal>(false));
auto *op =
storage.Create<XorOperator>(storage.Create<PrimitiveLiteral>(true),
storage.Create<PrimitiveLiteral>(false));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<XorOperator>(storage.Create<Literal>(true),
storage.Create<Literal>(true));
op = storage.Create<XorOperator>(storage.Create<PrimitiveLiteral>(true),
storage.Create<PrimitiveLiteral>(true));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
}
@ -74,12 +76,13 @@ TEST(ExpressionEvaluator, XorOperator) {
TEST(ExpressionEvaluator, AndOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<AndOperator>(storage.Create<Literal>(true),
storage.Create<Literal>(true));
auto *op =
storage.Create<AndOperator>(storage.Create<PrimitiveLiteral>(true),
storage.Create<PrimitiveLiteral>(true));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<AndOperator>(storage.Create<Literal>(false),
storage.Create<Literal>(true));
op = storage.Create<AndOperator>(storage.Create<PrimitiveLiteral>(false),
storage.Create<PrimitiveLiteral>(true));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
}
@ -87,8 +90,8 @@ TEST(ExpressionEvaluator, AndOperator) {
TEST(ExpressionEvaluator, AdditionOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<AdditionOperator>(storage.Create<Literal>(2),
storage.Create<Literal>(3));
auto *op = storage.Create<AdditionOperator>(
storage.Create<PrimitiveLiteral>(2), storage.Create<PrimitiveLiteral>(3));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), 5);
}
@ -96,8 +99,8 @@ TEST(ExpressionEvaluator, AdditionOperator) {
TEST(ExpressionEvaluator, SubtractionOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<SubtractionOperator>(storage.Create<Literal>(2),
storage.Create<Literal>(3));
auto *op = storage.Create<SubtractionOperator>(
storage.Create<PrimitiveLiteral>(2), storage.Create<PrimitiveLiteral>(3));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), -1);
}
@ -105,8 +108,8 @@ TEST(ExpressionEvaluator, SubtractionOperator) {
TEST(ExpressionEvaluator, MultiplicationOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<MultiplicationOperator>(storage.Create<Literal>(2),
storage.Create<Literal>(3));
auto *op = storage.Create<MultiplicationOperator>(
storage.Create<PrimitiveLiteral>(2), storage.Create<PrimitiveLiteral>(3));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), 6);
}
@ -114,8 +117,9 @@ TEST(ExpressionEvaluator, MultiplicationOperator) {
TEST(ExpressionEvaluator, DivisionOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<DivisionOperator>(storage.Create<Literal>(50),
storage.Create<Literal>(10));
auto *op =
storage.Create<DivisionOperator>(storage.Create<PrimitiveLiteral>(50),
storage.Create<PrimitiveLiteral>(10));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), 5);
}
@ -123,8 +127,8 @@ TEST(ExpressionEvaluator, DivisionOperator) {
TEST(ExpressionEvaluator, ModOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<ModOperator>(storage.Create<Literal>(65),
storage.Create<Literal>(10));
auto *op = storage.Create<ModOperator>(storage.Create<PrimitiveLiteral>(65),
storage.Create<PrimitiveLiteral>(10));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), 5);
}
@ -132,16 +136,17 @@ TEST(ExpressionEvaluator, ModOperator) {
TEST(ExpressionEvaluator, EqualOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<EqualOperator>(storage.Create<Literal>(10),
storage.Create<Literal>(15));
auto *op =
storage.Create<EqualOperator>(storage.Create<PrimitiveLiteral>(10),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
op = storage.Create<EqualOperator>(storage.Create<Literal>(15),
storage.Create<Literal>(15));
op = storage.Create<EqualOperator>(storage.Create<PrimitiveLiteral>(15),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<EqualOperator>(storage.Create<Literal>(20),
storage.Create<Literal>(15));
op = storage.Create<EqualOperator>(storage.Create<PrimitiveLiteral>(20),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
}
@ -149,16 +154,17 @@ TEST(ExpressionEvaluator, EqualOperator) {
TEST(ExpressionEvaluator, NotEqualOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<NotEqualOperator>(storage.Create<Literal>(10),
storage.Create<Literal>(15));
auto *op =
storage.Create<NotEqualOperator>(storage.Create<PrimitiveLiteral>(10),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<NotEqualOperator>(storage.Create<Literal>(15),
storage.Create<Literal>(15));
op = storage.Create<NotEqualOperator>(storage.Create<PrimitiveLiteral>(15),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
op = storage.Create<NotEqualOperator>(storage.Create<Literal>(20),
storage.Create<Literal>(15));
op = storage.Create<NotEqualOperator>(storage.Create<PrimitiveLiteral>(20),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
@ -166,16 +172,16 @@ TEST(ExpressionEvaluator, NotEqualOperator) {
TEST(ExpressionEvaluator, LessOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<LessOperator>(storage.Create<Literal>(10),
storage.Create<Literal>(15));
auto *op = storage.Create<LessOperator>(storage.Create<PrimitiveLiteral>(10),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<LessOperator>(storage.Create<Literal>(15),
storage.Create<Literal>(15));
op = storage.Create<LessOperator>(storage.Create<PrimitiveLiteral>(15),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
op = storage.Create<LessOperator>(storage.Create<Literal>(20),
storage.Create<Literal>(15));
op = storage.Create<LessOperator>(storage.Create<PrimitiveLiteral>(20),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
}
@ -183,16 +189,17 @@ TEST(ExpressionEvaluator, LessOperator) {
TEST(ExpressionEvaluator, GreaterOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<GreaterOperator>(storage.Create<Literal>(10),
storage.Create<Literal>(15));
auto *op =
storage.Create<GreaterOperator>(storage.Create<PrimitiveLiteral>(10),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
op = storage.Create<GreaterOperator>(storage.Create<Literal>(15),
storage.Create<Literal>(15));
op = storage.Create<GreaterOperator>(storage.Create<PrimitiveLiteral>(15),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
op = storage.Create<GreaterOperator>(storage.Create<Literal>(20),
storage.Create<Literal>(15));
op = storage.Create<GreaterOperator>(storage.Create<PrimitiveLiteral>(20),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
@ -200,16 +207,17 @@ TEST(ExpressionEvaluator, GreaterOperator) {
TEST(ExpressionEvaluator, LessEqualOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<LessEqualOperator>(storage.Create<Literal>(10),
storage.Create<Literal>(15));
auto *op =
storage.Create<LessEqualOperator>(storage.Create<PrimitiveLiteral>(10),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<LessEqualOperator>(storage.Create<Literal>(15),
storage.Create<Literal>(15));
op = storage.Create<LessEqualOperator>(storage.Create<PrimitiveLiteral>(15),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<LessEqualOperator>(storage.Create<Literal>(20),
storage.Create<Literal>(15));
op = storage.Create<LessEqualOperator>(storage.Create<PrimitiveLiteral>(20),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
}
@ -217,16 +225,19 @@ TEST(ExpressionEvaluator, LessEqualOperator) {
TEST(ExpressionEvaluator, GreaterEqualOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<GreaterEqualOperator>(storage.Create<Literal>(10),
storage.Create<Literal>(15));
auto *op = storage.Create<GreaterEqualOperator>(
storage.Create<PrimitiveLiteral>(10),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
op = storage.Create<GreaterEqualOperator>(storage.Create<Literal>(15),
storage.Create<Literal>(15));
op = storage.Create<GreaterEqualOperator>(
storage.Create<PrimitiveLiteral>(15),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
op = storage.Create<GreaterEqualOperator>(storage.Create<Literal>(20),
storage.Create<Literal>(15));
op = storage.Create<GreaterEqualOperator>(
storage.Create<PrimitiveLiteral>(20),
storage.Create<PrimitiveLiteral>(15));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
@ -234,7 +245,8 @@ TEST(ExpressionEvaluator, GreaterEqualOperator) {
TEST(ExpressionEvaluator, NotOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<NotOperator>(storage.Create<Literal>(false));
auto *op =
storage.Create<NotOperator>(storage.Create<PrimitiveLiteral>(false));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
@ -242,7 +254,8 @@ TEST(ExpressionEvaluator, NotOperator) {
TEST(ExpressionEvaluator, UnaryPlusOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<UnaryPlusOperator>(storage.Create<Literal>(5));
auto *op =
storage.Create<UnaryPlusOperator>(storage.Create<PrimitiveLiteral>(5));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), 5);
}
@ -250,7 +263,8 @@ TEST(ExpressionEvaluator, UnaryPlusOperator) {
TEST(ExpressionEvaluator, UnaryMinusOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<UnaryMinusOperator>(storage.Create<Literal>(5));
auto *op =
storage.Create<UnaryMinusOperator>(storage.Create<PrimitiveLiteral>(5));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), -5);
}
@ -258,18 +272,19 @@ TEST(ExpressionEvaluator, UnaryMinusOperator) {
TEST(ExpressionEvaluator, IsNullOperator) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *op = storage.Create<IsNullOperator>(storage.Create<Literal>(1));
auto *op =
storage.Create<IsNullOperator>(storage.Create<PrimitiveLiteral>(1));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), false);
op =
storage.Create<IsNullOperator>(storage.Create<Literal>(TypedValue::Null));
op = storage.Create<IsNullOperator>(
storage.Create<PrimitiveLiteral>(TypedValue::Null));
op->Accept(eval.eval);
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
TEST(ExpressionEvaluator, Aggregation) {
AstTreeStorage storage;
auto aggr = storage.Create<Aggregation>(storage.Create<Literal>(42),
auto aggr = storage.Create<Aggregation>(storage.Create<PrimitiveLiteral>(42),
Aggregation::Op::COUNT);
SymbolTable symbol_table;
auto aggr_sym = symbol_table.CreateSymbol("aggr");
@ -283,6 +298,23 @@ TEST(ExpressionEvaluator, Aggregation) {
EXPECT_EQ(eval.PopBack().Value<int64_t>(), 1);
}
TEST(ExpressionEvaluator, ListLiteral) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
auto *list_literal = storage.Create<ListLiteral>(
std::vector<Expression *>{storage.Create<PrimitiveLiteral>(1),
storage.Create<PrimitiveLiteral>("bla"),
storage.Create<PrimitiveLiteral>(true)});
list_literal->Accept(eval.eval);
TypedValue result = eval.eval.PopBack();
ASSERT_EQ(result.type(), TypedValue::Type::List);
auto &result_elems = result.Value<std::vector<TypedValue>>();
ASSERT_EQ(3, result_elems.size());
EXPECT_EQ(result_elems[0].type(), TypedValue::Type::Int);
EXPECT_EQ(result_elems[1].type(), TypedValue::Type::String);
EXPECT_EQ(result_elems[2].type(), TypedValue::Type::Bool);
}
TEST(ExpressionEvaluator, FunctionCoalesce) {
ASSERT_THROW(EvaluateFunction("COALESCE", {}), QueryRuntimeException);
ASSERT_EQ(