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:
parent
9653c703dc
commit
2e5eccf197
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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>;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 << "}]";
|
||||
}
|
||||
|
@ -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 << "})";
|
||||
}
|
||||
|
@ -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; });
|
||||
}
|
||||
|
@ -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]));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user