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/context.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);
|
||||
|
||||
// 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
|
||||
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
|
||||
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/logical/operator.hpp"
|
||||
|
||||
namespace query {
|
||||
|
||||
std::shared_ptr<LogicalOperator> GenCreate(
|
||||
Create& match, std::shared_ptr<LogicalOperator> current_op)
|
||||
{
|
||||
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);
|
||||
}
|
||||
class Query;
|
||||
class SymbolTable;
|
||||
|
||||
std::shared_ptr<LogicalOperator> GenMatch(
|
||||
Match& match, std::shared_ptr<LogicalOperator> current_op)
|
||||
{
|
||||
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<ScanAll>(node_atom);
|
||||
}
|
||||
// Returns the root of LogicalOperator tree. The tree is constructed by
|
||||
// traversing the given AST Query node. SymbolTable is used to determine inputs
|
||||
// and outputs of certain operators.
|
||||
std::unique_ptr<LogicalOperator> MakeLogicalPlan(
|
||||
Query& query, const SymbolTable &symbol_table);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ class SymbolTable {
|
||||
|
||||
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_; }
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user