Support creating NodeFilter and CreateOp logical operators
Reviewers: mislav.bradac, buda, florijan Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D133
This commit is contained in:
parent
da0c9c03d6
commit
baa644e9b7
@ -353,6 +353,7 @@ set(memgraph_src_files
|
|||||||
${src_dir}/query/frontend/ast/cypher_main_visitor.cpp
|
${src_dir}/query/frontend/ast/cypher_main_visitor.cpp
|
||||||
${src_dir}/query/context.cpp
|
${src_dir}/query/context.cpp
|
||||||
${src_dir}/query/backend/cpp/typed_value.cpp
|
${src_dir}/query/backend/cpp/typed_value.cpp
|
||||||
|
${src_dir}/query/frontend/logical/planner.cpp
|
||||||
)
|
)
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class Engine {
|
|||||||
query.Accept(symbol_generator);
|
query.Accept(symbol_generator);
|
||||||
|
|
||||||
// high level tree -> logical plan
|
// high level tree -> logical plan
|
||||||
auto logical_plan = MakeLogicalPlan(query);
|
auto logical_plan = MakeLogicalPlan(query, symbol_table);
|
||||||
|
|
||||||
// generate frame based on symbol table max_position
|
// generate frame based on symbol table max_position
|
||||||
Frame frame(symbol_table.max_position());
|
Frame frame(symbol_table.max_position());
|
||||||
|
78
src/query/frontend/logical/planner.cpp
Normal file
78
src/query/frontend/logical/planner.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include "query/frontend/logical/planner.hpp"
|
||||||
|
|
||||||
|
#include "query/frontend/ast/ast.hpp"
|
||||||
|
#include "utils/exceptions/not_yet_implemented.hpp"
|
||||||
|
|
||||||
|
namespace query {
|
||||||
|
|
||||||
|
static LogicalOperator *GenCreate(
|
||||||
|
Create& create, std::shared_ptr<LogicalOperator> input_op)
|
||||||
|
{
|
||||||
|
if (input_op) {
|
||||||
|
throw NotYetImplemented();
|
||||||
|
}
|
||||||
|
if (create.patterns_.size() != 1) {
|
||||||
|
throw NotYetImplemented();
|
||||||
|
}
|
||||||
|
auto &pattern = create.patterns_[0];
|
||||||
|
if (pattern->atoms_.size() != 1) {
|
||||||
|
throw NotYetImplemented();
|
||||||
|
}
|
||||||
|
auto node_atom = std::dynamic_pointer_cast<NodeAtom>(pattern->atoms_[0]);
|
||||||
|
return new CreateOp(node_atom);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LogicalOperator *GenMatch(
|
||||||
|
Match& match,
|
||||||
|
std::shared_ptr<LogicalOperator> input_op,
|
||||||
|
const SymbolTable &symbol_table)
|
||||||
|
{
|
||||||
|
if (input_op) {
|
||||||
|
throw NotYetImplemented();
|
||||||
|
}
|
||||||
|
if (match.patterns_.size() != 1) {
|
||||||
|
throw NotYetImplemented();
|
||||||
|
}
|
||||||
|
auto &pattern = match.patterns_[0];
|
||||||
|
if (pattern->atoms_.size() != 1) {
|
||||||
|
throw NotYetImplemented();
|
||||||
|
}
|
||||||
|
auto node_atom = std::dynamic_pointer_cast<NodeAtom>(pattern->atoms_[0]);
|
||||||
|
auto *scan_all = new ScanAll(node_atom);
|
||||||
|
if (!node_atom->labels_.empty() || !node_atom->properties_.empty()) {
|
||||||
|
auto &input_symbol = symbol_table.at(*node_atom->identifier_);
|
||||||
|
return new NodeFilter(std::shared_ptr<LogicalOperator>(scan_all), input_symbol,
|
||||||
|
node_atom->labels_, node_atom->properties_);
|
||||||
|
}
|
||||||
|
return scan_all;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Produce *GenReturn(Return& ret, std::shared_ptr<LogicalOperator> input_op)
|
||||||
|
{
|
||||||
|
if (!input_op) {
|
||||||
|
throw NotYetImplemented();
|
||||||
|
}
|
||||||
|
return new Produce(input_op, ret.named_expressions_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<LogicalOperator> MakeLogicalPlan(
|
||||||
|
Query& query, const SymbolTable &symbol_table)
|
||||||
|
{
|
||||||
|
LogicalOperator *input_op = nullptr;
|
||||||
|
for (auto &clause : query.clauses_) {
|
||||||
|
auto *clause_ptr = clause.get();
|
||||||
|
if (auto *match = dynamic_cast<Match*>(clause_ptr)) {
|
||||||
|
input_op = GenMatch(*match, std::shared_ptr<LogicalOperator>(input_op),
|
||||||
|
symbol_table);
|
||||||
|
} else if (auto *ret = dynamic_cast<Return*>(clause_ptr)) {
|
||||||
|
input_op = GenReturn(*ret, std::shared_ptr<LogicalOperator>(input_op));
|
||||||
|
} else if (auto *create = dynamic_cast<Create*>(clause_ptr)) {
|
||||||
|
input_op = GenCreate(*create, std::shared_ptr<LogicalOperator>(input_op));
|
||||||
|
} else {
|
||||||
|
throw NotYetImplemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::unique_ptr<LogicalOperator>(input_op);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,74 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include "query/frontend/ast/ast.hpp"
|
|
||||||
#include "query/frontend/logical/operator.hpp"
|
#include "query/frontend/logical/operator.hpp"
|
||||||
|
|
||||||
namespace query {
|
namespace query {
|
||||||
|
|
||||||
std::shared_ptr<LogicalOperator> GenCreate(
|
class Query;
|
||||||
Create& match, std::shared_ptr<LogicalOperator> current_op)
|
class SymbolTable;
|
||||||
{
|
|
||||||
if (current_op) {
|
|
||||||
throw std::runtime_error("Not implemented");
|
|
||||||
}
|
|
||||||
if (match.patterns_.size() != 1) {
|
|
||||||
throw std::runtime_error("Not implemented");
|
|
||||||
}
|
|
||||||
auto& pattern = match.patterns_[0];
|
|
||||||
if (pattern->atoms_.size() != 1) {
|
|
||||||
throw std::runtime_error("Not implemented");
|
|
||||||
}
|
|
||||||
auto node_atom = std::dynamic_pointer_cast<NodeAtom>(pattern->atoms_[0]);
|
|
||||||
return std::make_shared<CreateOp>(node_atom);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<LogicalOperator> GenMatch(
|
// Returns the root of LogicalOperator tree. The tree is constructed by
|
||||||
Match& match, std::shared_ptr<LogicalOperator> current_op)
|
// traversing the given AST Query node. SymbolTable is used to determine inputs
|
||||||
{
|
// and outputs of certain operators.
|
||||||
if (current_op) {
|
std::unique_ptr<LogicalOperator> MakeLogicalPlan(
|
||||||
throw std::runtime_error("Not implemented");
|
Query& query, const SymbolTable &symbol_table);
|
||||||
}
|
|
||||||
if (match.patterns_.size() != 1) {
|
|
||||||
throw std::runtime_error("Not implemented");
|
|
||||||
}
|
|
||||||
auto& pattern = match.patterns_[0];
|
|
||||||
if (pattern->atoms_.size() != 1) {
|
|
||||||
throw std::runtime_error("Not implemented");
|
|
||||||
}
|
|
||||||
auto node_atom = std::dynamic_pointer_cast<NodeAtom>(pattern->atoms_[0]);
|
|
||||||
return std::make_shared<ScanAll>(node_atom);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<LogicalOperator> GenReturn(
|
|
||||||
Return& ret, std::shared_ptr<LogicalOperator> current_op)
|
|
||||||
{
|
|
||||||
if (!current_op) {
|
|
||||||
throw std::runtime_error("Not implemented");
|
|
||||||
}
|
|
||||||
return std::make_shared<Produce>(current_op, ret.named_expressions_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<LogicalOperator> MakeLogicalPlan(Query& query)
|
|
||||||
{
|
|
||||||
std::shared_ptr<LogicalOperator> current_op;
|
|
||||||
for (auto& clause : query.clauses_) {
|
|
||||||
auto* clause_ptr = clause.get();
|
|
||||||
auto* create = dynamic_cast<Create*>(clause_ptr);
|
|
||||||
auto* match = dynamic_cast<Match*>(clause_ptr);
|
|
||||||
auto* ret = dynamic_cast<Return*>(clause_ptr);
|
|
||||||
if (create) {
|
|
||||||
current_op = GenCreate(*create, current_op);
|
|
||||||
} else if (match) {
|
|
||||||
current_op = GenMatch(*match, current_op);
|
|
||||||
} else if (ret) {
|
|
||||||
return GenReturn(*ret, current_op);
|
|
||||||
} else {
|
|
||||||
throw std::runtime_error("Not implemented");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return current_op;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,10 @@ class SymbolTable {
|
|||||||
return Symbol(name, position);
|
return Symbol(name, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& operator[](const Tree& tree) { return table_[tree.uid()]; }
|
auto &operator[](const Tree& tree) { return table_[tree.uid()]; }
|
||||||
|
|
||||||
|
auto &at(const Tree& tree) { return table_.at(tree.uid()); }
|
||||||
|
const auto &at(const Tree& tree) const { return table_.at(tree.uid()); }
|
||||||
|
|
||||||
int max_position() const { return position_; }
|
int max_position() const { return position_; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user