538 lines
24 KiB
C++
538 lines
24 KiB
C++
// Copyright 2023 Memgraph Ltd.
|
|
//
|
|
// Use of this software is governed by the Business Source License
|
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
|
// License, and you may not use this file except in compliance with the Business Source License.
|
|
//
|
|
// As of the Change Date specified in that file, in accordance with
|
|
// the Business Source License, use of this software will be governed
|
|
// by the Apache License, Version 2.0, included in the file
|
|
// licenses/APL.txt.
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "disk_test_utils.hpp"
|
|
#include "query/frontend/semantic/symbol_table.hpp"
|
|
#include "query/plan/operator.hpp"
|
|
#include "query/plan/preprocess.hpp"
|
|
#include "query/plan/pretty_print.hpp"
|
|
|
|
#include "query_common.hpp"
|
|
#include "storage/v2/disk/storage.hpp"
|
|
#include "storage/v2/inmemory/storage.hpp"
|
|
|
|
using namespace memgraph::query;
|
|
using namespace memgraph::query::plan;
|
|
|
|
// The JSON formatted plan is consumed (or will be) by Memgraph Lab, and
|
|
// therefore should not be changed before synchronizing with whoever is
|
|
// maintaining Memgraph Lab. Hopefully, one day integration tests will exist and
|
|
// there will be no need to be super careful.
|
|
|
|
template <typename StorageType>
|
|
class OperatorToStringTest : public ::testing::Test {
|
|
protected:
|
|
const std::string testSuite = "plan_operator_to_string";
|
|
|
|
OperatorToStringTest()
|
|
: config(disk_test_utils::GenerateOnDiskConfig(testSuite)),
|
|
db(new StorageType(config)),
|
|
dba_storage(db->Access()),
|
|
dba(dba_storage.get()) {}
|
|
|
|
~OperatorToStringTest() override {
|
|
if (std::is_same<StorageType, memgraph::storage::DiskStorage>::value) {
|
|
disk_test_utils::RemoveRocksDbDirs(testSuite);
|
|
}
|
|
}
|
|
|
|
AstStorage storage;
|
|
SymbolTable symbol_table;
|
|
|
|
memgraph::storage::Config config;
|
|
std::unique_ptr<memgraph::storage::Storage> db;
|
|
std::unique_ptr<memgraph::storage::Storage::Accessor> dba_storage;
|
|
memgraph::query::DbAccessor dba;
|
|
|
|
Symbol GetSymbol(std::string name) { return symbol_table.CreateSymbol(name, true); }
|
|
};
|
|
|
|
using StorageTypes = ::testing::Types<memgraph::storage::InMemoryStorage, memgraph::storage::DiskStorage>;
|
|
TYPED_TEST_CASE(OperatorToStringTest, StorageTypes);
|
|
|
|
TYPED_TEST(OperatorToStringTest, Once) {
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<Once>();
|
|
|
|
std::string expected_string{"Once"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, CreateNode) {
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<CreateNode>(
|
|
nullptr, NodeCreationInfo{this->GetSymbol("node"),
|
|
{this->dba.NameToLabel("Label1"), this->dba.NameToLabel("Label2")},
|
|
{{this->dba.NameToProperty("prop1"), LITERAL(5)},
|
|
{this->dba.NameToProperty("prop2"), LITERAL("some cool stuff")}}});
|
|
|
|
std::string expected_string{"CreateNode"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, CreateExpand) {
|
|
Symbol node1_sym = this->GetSymbol("node1");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, this->GetSymbol("node1"));
|
|
last_op = std::make_shared<CreateExpand>(
|
|
NodeCreationInfo{this->GetSymbol("node2"),
|
|
{this->dba.NameToLabel("Label1"), this->dba.NameToLabel("Label2")},
|
|
{{this->dba.NameToProperty("prop1"), LITERAL(5)},
|
|
{this->dba.NameToProperty("prop2"), LITERAL("some cool stuff")}}},
|
|
EdgeCreationInfo{this->GetSymbol("edge"),
|
|
{{this->dba.NameToProperty("weight"), LITERAL(5.32)}},
|
|
this->dba.NameToEdgeType("edge_type"),
|
|
EdgeAtom::Direction::OUT},
|
|
last_op, node1_sym, false);
|
|
last_op->dba_ = &this->dba;
|
|
|
|
std::string expected_string{"CreateExpand (node1)-[edge:edge_type]->(node2)"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, ScanAll) {
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<ScanAll>(nullptr, this->GetSymbol("node"));
|
|
|
|
std::string expected_string{"ScanAll (node)"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, ScanAllByLabel) {
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<ScanAllByLabel>(nullptr, this->GetSymbol("node"), this->dba.NameToLabel("Label"));
|
|
last_op->dba_ = &this->dba;
|
|
|
|
std::string expected_string{"ScanAllByLabel (node :Label)"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, ScanAllByLabelPropertyRange) {
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<ScanAllByLabelPropertyRange>(
|
|
nullptr, this->GetSymbol("node"), this->dba.NameToLabel("Label"), this->dba.NameToProperty("prop"), "prop",
|
|
memgraph::utils::MakeBoundInclusive<Expression *>(LITERAL(1)),
|
|
memgraph::utils::MakeBoundExclusive<Expression *>(LITERAL(20)));
|
|
last_op->dba_ = &this->dba;
|
|
|
|
std::string expected_string{"ScanAllByLabelPropertyRange (node :Label {prop})"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, ScanAllByLabelPropertyValue) {
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<ScanAllByLabelPropertyValue>(
|
|
nullptr, this->GetSymbol("node"), this->dba.NameToLabel("Label"), this->dba.NameToProperty("prop"), "prop",
|
|
ADD(LITERAL(21), LITERAL(21)));
|
|
last_op->dba_ = &this->dba;
|
|
|
|
std::string expected_string{"ScanAllByLabelPropertyValue (node :Label {prop})"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, ScanAllByLabelProperty) {
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<ScanAllByLabelProperty>(nullptr, this->GetSymbol("node"), this->dba.NameToLabel("Label"),
|
|
this->dba.NameToProperty("prop"), "prop");
|
|
last_op->dba_ = &this->dba;
|
|
|
|
std::string expected_string{"ScanAllByLabelProperty (node :Label {prop})"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, ScanAllById) {
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<ScanAllById>(nullptr, this->GetSymbol("node"), ADD(LITERAL(21), LITERAL(21)));
|
|
last_op->dba_ = &this->dba;
|
|
|
|
std::string expected_string{"ScanAllById (node)"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Expand) {
|
|
auto node1_sym = this->GetSymbol("node1");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node1_sym);
|
|
last_op = std::make_shared<Expand>(last_op, node1_sym, this->GetSymbol("node2"), this->GetSymbol("edge"),
|
|
EdgeAtom::Direction::BOTH,
|
|
std::vector<memgraph::storage::EdgeTypeId>{this->dba.NameToEdgeType("EdgeType1"),
|
|
this->dba.NameToEdgeType("EdgeType2")},
|
|
false, memgraph::storage::View::OLD);
|
|
last_op->dba_ = &this->dba;
|
|
|
|
std::string expected_string{"Expand (node1)-[edge:EdgeType1|:EdgeType2]-(node2)"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, ExpandVariable) {
|
|
auto node1_sym = this->GetSymbol("node1");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node1_sym);
|
|
last_op = std::make_shared<ExpandVariable>(
|
|
last_op, node1_sym, this->GetSymbol("node2"), this->GetSymbol("edge"), EdgeAtom::Type::BREADTH_FIRST,
|
|
EdgeAtom::Direction::OUT,
|
|
std::vector<memgraph::storage::EdgeTypeId>{this->dba.NameToEdgeType("EdgeType1"),
|
|
this->dba.NameToEdgeType("EdgeType2")},
|
|
false, LITERAL(2), LITERAL(5), false,
|
|
ExpansionLambda{this->GetSymbol("inner_node"), this->GetSymbol("inner_edge"),
|
|
PROPERTY_LOOKUP(this->dba, "inner_node", this->dba.NameToProperty("unblocked"))},
|
|
std::nullopt, std::nullopt);
|
|
last_op->dba_ = &this->dba;
|
|
|
|
std::string expected_string{"BFSExpand (node1)-[edge:EdgeType1|:EdgeType2]->(node2)"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, ConstructNamedPath) {
|
|
auto node1_sym = this->GetSymbol("node1");
|
|
auto edge1_sym = this->GetSymbol("edge1");
|
|
auto node2_sym = this->GetSymbol("node2");
|
|
auto edge2_sym = this->GetSymbol("edge2");
|
|
auto node3_sym = this->GetSymbol("node3");
|
|
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node1_sym);
|
|
last_op = std::make_shared<Expand>(last_op, node1_sym, node2_sym, edge1_sym, EdgeAtom::Direction::OUT,
|
|
std::vector<memgraph::storage::EdgeTypeId>{}, false, memgraph::storage::View::OLD);
|
|
last_op = std::make_shared<Expand>(last_op, node2_sym, node3_sym, edge2_sym, EdgeAtom::Direction::OUT,
|
|
std::vector<memgraph::storage::EdgeTypeId>{}, false, memgraph::storage::View::OLD);
|
|
last_op = std::make_shared<ConstructNamedPath>(
|
|
last_op, this->GetSymbol("path"), std::vector<Symbol>{node1_sym, edge1_sym, node2_sym, edge2_sym, node3_sym});
|
|
|
|
std::string expected_string{"ConstructNamedPath"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Filter) {
|
|
auto node = this->GetSymbol("person");
|
|
auto node_ident = IDENT("person");
|
|
auto property = this->dba.NameToProperty("name");
|
|
auto property_ix = this->storage.GetPropertyIx("name");
|
|
|
|
FilterInfo generic_filter_info = {.type = FilterInfo::Type::Generic, .used_symbols = {node}};
|
|
|
|
auto id_filter = IdFilter(this->symbol_table, node, LITERAL(42));
|
|
FilterInfo id_filter_info = {.type = FilterInfo::Type::Id, .id_filter = id_filter};
|
|
|
|
std::vector<LabelIx> labels{this->storage.GetLabelIx("Customer"), this->storage.GetLabelIx("Visitor")};
|
|
auto labels_test = LABELS_TEST(node_ident, labels);
|
|
FilterInfo label_filter_info = {.type = FilterInfo::Type::Label, .expression = labels_test};
|
|
|
|
auto labels_test_2 = LABELS_TEST(PROPERTY_LOOKUP(this->dba, "person", property), labels);
|
|
FilterInfo label_filter_2_info = {.type = FilterInfo::Type::Label, .expression = labels_test_2};
|
|
|
|
auto property_filter = PropertyFilter(node, property_ix, PropertyFilter::Type::EQUAL);
|
|
FilterInfo property_filter_info = {.type = FilterInfo::Type::Property, .property_filter = property_filter};
|
|
|
|
FilterInfo pattern_filter_info = {.type = FilterInfo::Type::Pattern};
|
|
|
|
Filters filters;
|
|
filters.SetFilters({generic_filter_info, id_filter_info, label_filter_info, label_filter_2_info, property_filter_info,
|
|
pattern_filter_info});
|
|
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node);
|
|
last_op = std::make_shared<Filter>(last_op, std::vector<std::shared_ptr<LogicalOperator>>{},
|
|
EQ(PROPERTY_LOOKUP(this->dba, "person", property), LITERAL(5)), filters);
|
|
|
|
std::string expected_string{
|
|
"Filter (:Customer:Visitor), (person :Customer:Visitor), Generic {person}, Pattern, id(person), {person.name}"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Produce) {
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<Produce>(
|
|
nullptr, std::vector<NamedExpression *>{NEXPR("pet", LITERAL(5)), NEXPR("string", LITERAL("string"))});
|
|
|
|
std::string expected_string{"Produce {pet, string}"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Delete) {
|
|
auto node_sym = this->GetSymbol("node1");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node_sym);
|
|
last_op = std::make_shared<Expand>(last_op, node_sym, this->GetSymbol("node2"), this->GetSymbol("edge"),
|
|
EdgeAtom::Direction::BOTH, std::vector<memgraph::storage::EdgeTypeId>{}, false,
|
|
memgraph::storage::View::OLD);
|
|
last_op = std::make_shared<plan::Delete>(last_op, std::vector<Expression *>{IDENT("node2")}, true);
|
|
|
|
std::string expected_string{"Delete"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, SetProperty) {
|
|
memgraph::storage::PropertyId prop = this->dba.NameToProperty("prop");
|
|
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, this->GetSymbol("node"));
|
|
last_op = std::make_shared<plan::SetProperty>(last_op, prop, PROPERTY_LOOKUP(this->dba, "node", prop),
|
|
ADD(PROPERTY_LOOKUP(this->dba, "node", prop), LITERAL(1)));
|
|
|
|
std::string expected_string{"SetProperty"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, SetProperties) {
|
|
auto node_sym = this->GetSymbol("node");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node_sym);
|
|
last_op = std::make_shared<plan::SetProperties>(last_op, node_sym,
|
|
MAP({{this->storage.GetPropertyIx("prop1"), LITERAL(1)},
|
|
{this->storage.GetPropertyIx("prop2"), LITERAL("propko")}}),
|
|
plan::SetProperties::Op::REPLACE);
|
|
|
|
std::string expected_string{"SetProperties"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, SetLabels) {
|
|
auto node_sym = this->GetSymbol("node");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node_sym);
|
|
last_op = std::make_shared<plan::SetLabels>(
|
|
last_op, node_sym,
|
|
std::vector<memgraph::storage::LabelId>{this->dba.NameToLabel("label1"), this->dba.NameToLabel("label2")});
|
|
|
|
std::string expected_string{"SetLabels"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, RemoveProperty) {
|
|
auto node_sym = this->GetSymbol("node");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node_sym);
|
|
last_op = std::make_shared<plan::RemoveProperty>(
|
|
last_op, this->dba.NameToProperty("prop"), PROPERTY_LOOKUP(this->dba, "node", this->dba.NameToProperty("prop")));
|
|
|
|
std::string expected_string{"RemoveProperty"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, RemoveLabels) {
|
|
auto node_sym = this->GetSymbol("node");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node_sym);
|
|
last_op = std::make_shared<plan::RemoveLabels>(
|
|
last_op, node_sym,
|
|
std::vector<memgraph::storage::LabelId>{this->dba.NameToLabel("label1"), this->dba.NameToLabel("label2")});
|
|
|
|
std::string expected_string{"RemoveLabels"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, EdgeUniquenessFilter) {
|
|
auto node1_sym = this->GetSymbol("node1");
|
|
auto node2_sym = this->GetSymbol("node2");
|
|
auto node3_sym = this->GetSymbol("node3");
|
|
auto node4_sym = this->GetSymbol("node4");
|
|
|
|
auto edge1_sym = this->GetSymbol("edge1");
|
|
auto edge2_sym = this->GetSymbol("edge2");
|
|
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node1_sym);
|
|
last_op = std::make_shared<Expand>(last_op, node1_sym, node2_sym, edge1_sym, EdgeAtom::Direction::IN,
|
|
std::vector<memgraph::storage::EdgeTypeId>{}, false, memgraph::storage::View::OLD);
|
|
last_op = std::make_shared<ScanAll>(last_op, node3_sym);
|
|
last_op = std::make_shared<Expand>(last_op, node3_sym, node4_sym, edge2_sym, EdgeAtom::Direction::OUT,
|
|
std::vector<memgraph::storage::EdgeTypeId>{}, false, memgraph::storage::View::OLD);
|
|
last_op = std::make_shared<EdgeUniquenessFilter>(last_op, edge2_sym, std::vector<Symbol>{edge1_sym});
|
|
|
|
std::string expected_string{"EdgeUniquenessFilter {edge1 : edge2}"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Accumulate) {
|
|
memgraph::storage::PropertyId prop = this->dba.NameToProperty("prop");
|
|
auto node_sym = this->GetSymbol("node");
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node_sym);
|
|
last_op = std::make_shared<plan::SetProperty>(last_op, prop, PROPERTY_LOOKUP(this->dba, "node", prop),
|
|
ADD(PROPERTY_LOOKUP(this->dba, "node", prop), LITERAL(1)));
|
|
last_op = std::make_shared<plan::Accumulate>(last_op, std::vector<Symbol>{node_sym}, true);
|
|
|
|
std::string expected_string{"Accumulate"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Aggregate) {
|
|
memgraph::storage::PropertyId value = this->dba.NameToProperty("value");
|
|
memgraph::storage::PropertyId color = this->dba.NameToProperty("color");
|
|
memgraph::storage::PropertyId type = this->dba.NameToProperty("type");
|
|
auto node_sym = this->GetSymbol("node");
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<plan::Aggregate>(
|
|
nullptr,
|
|
std::vector<Aggregate::Element>{
|
|
{PROPERTY_LOOKUP(this->dba, "node", value), nullptr, Aggregation::Op::SUM, this->GetSymbol("sum")},
|
|
{PROPERTY_LOOKUP(this->dba, "node", value), PROPERTY_LOOKUP(this->dba, "node", color),
|
|
Aggregation::Op::COLLECT_MAP, this->GetSymbol("map")},
|
|
{nullptr, nullptr, Aggregation::Op::COUNT, this->GetSymbol("count")}},
|
|
std::vector<Expression *>{PROPERTY_LOOKUP(this->dba, "node", type)}, std::vector<Symbol>{node_sym});
|
|
|
|
std::string expected_string{"Aggregate {sum, map, count} {node}"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Skip) {
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, this->GetSymbol("node"));
|
|
last_op = std::make_shared<Skip>(last_op, LITERAL(42));
|
|
|
|
std::string expected_string{"Skip"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Limit) {
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, this->GetSymbol("node"));
|
|
last_op = std::make_shared<Limit>(last_op, LITERAL(42));
|
|
|
|
std::string expected_string{"Limit"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, OrderBy) {
|
|
Symbol person_sym = this->GetSymbol("person");
|
|
Symbol pet_sym = this->GetSymbol("pet");
|
|
memgraph::storage::PropertyId name = this->dba.NameToProperty("name");
|
|
memgraph::storage::PropertyId age = this->dba.NameToProperty("age");
|
|
std::shared_ptr<LogicalOperator> last_op;
|
|
last_op = std::make_shared<OrderBy>(nullptr,
|
|
std::vector<SortItem>{{Ordering::ASC, PROPERTY_LOOKUP(this->dba, "person", name)},
|
|
{Ordering::DESC, PROPERTY_LOOKUP(this->dba, "pet", age)}},
|
|
std::vector<Symbol>{person_sym, pet_sym});
|
|
|
|
std::string expected_string{"OrderBy {person, pet}"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Merge) {
|
|
Symbol node_sym = this->GetSymbol("node");
|
|
memgraph::storage::LabelId label = this->dba.NameToLabel("label");
|
|
|
|
std::shared_ptr<LogicalOperator> match = std::make_shared<ScanAllByLabel>(nullptr, node_sym, label);
|
|
|
|
std::shared_ptr<LogicalOperator> create =
|
|
std::make_shared<CreateNode>(nullptr, NodeCreationInfo{node_sym, {label}, {}});
|
|
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<plan::Merge>(nullptr, match, create);
|
|
|
|
std::string expected_string{"Merge"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Optional) {
|
|
Symbol node1_sym = this->GetSymbol("node1");
|
|
Symbol node2_sym = this->GetSymbol("node2");
|
|
Symbol edge_sym = this->GetSymbol("edge");
|
|
|
|
std::shared_ptr<LogicalOperator> input = std::make_shared<ScanAll>(nullptr, node1_sym);
|
|
|
|
std::shared_ptr<LogicalOperator> expand =
|
|
std::make_shared<Expand>(nullptr, node1_sym, node2_sym, edge_sym, EdgeAtom::Direction::OUT,
|
|
std::vector<memgraph::storage::EdgeTypeId>{}, false, memgraph::storage::View::OLD);
|
|
|
|
std::shared_ptr<LogicalOperator> last_op =
|
|
std::make_shared<Optional>(input, expand, std::vector<Symbol>{node2_sym, edge_sym});
|
|
|
|
std::string expected_string{"Optional"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Unwind) {
|
|
std::shared_ptr<LogicalOperator> last_op =
|
|
std::make_shared<plan::Unwind>(nullptr, LIST(LITERAL(1), LITERAL(2), LITERAL(3)), this->GetSymbol("x"));
|
|
|
|
std::string expected_string{"Unwind"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Distinct) {
|
|
Symbol x = this->GetSymbol("x");
|
|
std::shared_ptr<LogicalOperator> last_op =
|
|
std::make_shared<plan::Unwind>(nullptr, LIST(LITERAL(2), LITERAL(3), LITERAL(2)), x);
|
|
last_op = std::make_shared<Distinct>(last_op, std::vector<Symbol>{x});
|
|
|
|
std::string expected_string{"Distinct"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Union) {
|
|
Symbol x = this->GetSymbol("x");
|
|
std::shared_ptr<LogicalOperator> lhs =
|
|
std::make_shared<plan::Unwind>(nullptr, LIST(LITERAL(2), LITERAL(3), LITERAL(2)), x);
|
|
|
|
Symbol node = this->GetSymbol("x");
|
|
std::shared_ptr<LogicalOperator> rhs = std::make_shared<ScanAll>(nullptr, node);
|
|
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<Union>(
|
|
lhs, rhs, std::vector<Symbol>{this->GetSymbol("x")}, std::vector<Symbol>{x}, std::vector<Symbol>{node});
|
|
|
|
std::string expected_string{"Union {x : x}"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, CallProcedure) {
|
|
memgraph::query::plan::CallProcedure call_op;
|
|
call_op.input_ = std::make_shared<Once>();
|
|
call_op.procedure_name_ = "mg.procedures";
|
|
call_op.arguments_ = {};
|
|
call_op.result_fields_ = {"is_editable", "is_write", "name", "path", "signature"};
|
|
call_op.result_symbols_ = {this->GetSymbol("is_editable"), this->GetSymbol("is_write"), this->GetSymbol("name"),
|
|
this->GetSymbol("path"), this->GetSymbol("signature")};
|
|
|
|
std::string expected_string{"CallProcedure<mg.procedures> {is_editable, is_write, name, path, signature}"};
|
|
EXPECT_EQ(call_op.ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, LoadCsv) {
|
|
memgraph::query::plan::LoadCsv last_op;
|
|
last_op.input_ = std::make_shared<Once>();
|
|
last_op.row_var_ = this->GetSymbol("transaction");
|
|
|
|
std::string expected_string{"LoadCsv {transaction}"};
|
|
EXPECT_EQ(last_op.ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Foreach) {
|
|
Symbol x = this->GetSymbol("x");
|
|
std::shared_ptr<LogicalOperator> create = std::make_shared<CreateNode>(
|
|
nullptr, NodeCreationInfo{this->GetSymbol("node"), {this->dba.NameToLabel("Label1")}, {}});
|
|
std::shared_ptr<LogicalOperator> foreach =
|
|
std::make_shared<plan::Foreach>(nullptr, std::move(create), LIST(LITERAL(1)), x);
|
|
|
|
std::string expected_string{"Foreach"};
|
|
EXPECT_EQ(foreach->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, EmptyResult) {
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<EmptyResult>(nullptr);
|
|
|
|
std::string expected_string{"EmptyResult"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, EvaluatePatternFilter) {
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<EvaluatePatternFilter>(nullptr, this->GetSymbol("node"));
|
|
|
|
std::string expected_string{"EvaluatePatternFilter"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, Apply) {
|
|
memgraph::query::plan::Apply last_op(nullptr, nullptr, false);
|
|
|
|
std::string expected_string{"Apply"};
|
|
EXPECT_EQ(last_op.ToString(), expected_string);
|
|
}
|
|
|
|
TYPED_TEST(OperatorToStringTest, HashJoin) {
|
|
Symbol lhs_sym = this->GetSymbol("node1");
|
|
Symbol rhs_sym = this->GetSymbol("node2");
|
|
|
|
std::shared_ptr<LogicalOperator> lhs_match = std::make_shared<ScanAll>(nullptr, lhs_sym);
|
|
std::shared_ptr<LogicalOperator> rhs_match = std::make_shared<ScanAll>(nullptr, rhs_sym);
|
|
std::shared_ptr<LogicalOperator> last_op = std::make_shared<HashJoin>(
|
|
lhs_match, std::vector<Symbol>{lhs_sym}, rhs_match, std::vector<Symbol>{rhs_sym}, nullptr);
|
|
|
|
std::string expected_string{"HashJoin {node1 : node2}"};
|
|
EXPECT_EQ(last_op->ToString(), expected_string);
|
|
}
|