Basic interpreter implementation.

This commit is contained in:
Marko Budiselic 2017-03-11 21:02:03 +01:00
parent 9030454132
commit 0eeb1fc5b4
6 changed files with 155 additions and 51 deletions

View File

@ -1,14 +1,52 @@
#pragma once
#include "antlr4-runtime.h"
#include "database/graph_db_accessor.hpp"
#include "query/frontend/ast/cypher_main_visitor.hpp"
class TypedcheckedTree {};
class LogicalPlan {};
class Context;
class LogicalPlanGenerator {
public:
std::vector<LogicalPlan> Generate(TypedcheckedTree&, Context&) {
return {LogicalPlan()};
}
};
struct Config {
LogicalPlanGenerator logical_plan_generator;
};
class Context {
public:
int uid_counter;
Context(Config config, GraphDbAccessor& db_accessor)
: config(config), db_accessor(db_accessor) {}
Config config;
GraphDbAccessor& db_accessor;
};
class LogicalPlanner {
public:
LogicalPlanner(Context ctx) : ctx_(ctx) {}
LogicalPlan Apply(TypedcheckedTree typedchecked_tree) {
return ctx_.config.logical_plan_generator.Generate(typedchecked_tree,
ctx_)[0];
}
private:
Context ctx_;
};
class HighLevelAstConversion {
void Apply(const Context &ctx, antlr4::tree::ParseTree *tree) {
public:
void Apply(const Context& ctx, antlr4::tree::ParseTree* tree) {
query::frontend::CypherMainVisitor visitor(ctx);
visitor.visit(tree);
}

View File

@ -2,21 +2,44 @@
#include "database/graph_db_accessor.hpp"
#include "query/frontend/opencypher/parser.hpp"
#include "query/context.hpp"
namespace query {
template <typename Stream>
class Engine {
public:
Engine() {}
Engine() {
}
auto Execute(const std::string &query, GraphDbAccessor &db_accessor,
Stream &stream) {
frontend::opencypher::Parser parser(query);
Config config;
Context ctx(config, db_accessor);
::frontend::opencypher::Parser parser(query);
auto low_level_tree = parser.tree();
// high level tree
// typechecked tree
// logical tree
auto high_level_tree = low2high_tree.Apply(ctx, low_level_tree);
TypedcheckedTree typechecked_tree;
auto logical_plan = LogicalPlanner(ctx).Apply(typechecked_tree);
// interpret & stream results
// generate frame based on symbol table max_position
Frame frame(size);
auto cursor = logical_plan.MakeCursor(frame);
logical_plan.WriteHeader(stream);
auto symbols = logical_plan.OutputSymbols(symbol_table);
while (cursor.pull(frame, context)) {
std::vector<TypedValue> values(symbols.size());
for (auto symbol : symbols) {
values.emplace_back(frame[symbol]);
}
stream.Result(values);
}
stream.Summary({"type": "r"});
}
private:
Context ctx;
HighLevelAstConversion low2high_tree;
};
}

View File

@ -7,4 +7,7 @@ TypedValue Ident::Evaluate(Frame& frame, SymbolTable& symbol_table) {
return frame[symbol_table[*this].position_];
}
void NamedExpr::Evaluate(Frame& frame, SymbolTable& symbol_table) {
frame[symbol_table[*ident_].position_] = expr_->Evaluate(frame, symbol_table);
}
}

View File

@ -50,24 +50,24 @@ class TreeVisitorBase {
};
class Tree {
public:
public:
Tree(const int uid) : uid_(uid) {}
int uid() const { return uid_; }
virtual void Accept(TreeVisitorBase& visitor) = 0;
private:
private:
const int uid_;
};
class Expr : public Tree {
public:
virtual TypedValue Evaluate(Frame &, SymbolTable &) = 0;
public:
virtual TypedValue Evaluate(Frame&, SymbolTable&) = 0;
};
class Ident : public Expr {
public:
public:
std::string identifier_;
TypedValue Evaluate(Frame &frame, SymbolTable &symbol_table) override;
TypedValue Evaluate(Frame& frame, SymbolTable& symbol_table) override;
void Accept(TreeVisitorBase& visitor) override {
visitor.PreVisit(*this);
visitor.Visit(*this);
@ -77,8 +77,15 @@ public:
class Part : public Tree {};
class NamedExpr : public Tree {
public:
std::shared_ptr<Ident> ident_;
std::shared_ptr<Expr> expr_;
void Evaluate(Frame& frame, SymbolTable& symbol_table);
};
class NodePart : public Part {
public:
public:
Ident identifier_;
// TODO: Mislav call GraphDb::label(label_name) to populate labels_!
std::vector<GraphDb::Label> labels_;
@ -92,7 +99,7 @@ public:
};
class EdgePart : public Part {
public:
public:
Ident identifier_;
// TODO: finish this: properties, types...
void Accept(TreeVisitorBase& visitor) override {
@ -106,7 +113,7 @@ public:
class Clause : public Tree {};
class Pattern : public Tree {
public:
public:
std::vector<std::shared_ptr<NodePart>> node_parts_;
void Accept(TreeVisitorBase& visitor) override {
visitor.PreVisit(*this);
@ -119,7 +126,7 @@ public:
};
class Query : public Tree {
public:
public:
std::vector<std::unique_ptr<Clause>> clauses_;
void Accept(TreeVisitorBase& visitor) override {
visitor.PreVisit(*this);
@ -132,7 +139,7 @@ public:
};
class Match : public Clause {
public:
public:
std::vector<std::unique_ptr<Pattern>> patterns_;
void Accept(TreeVisitorBase& visitor) override {
visitor.PreVisit(*this);
@ -145,7 +152,7 @@ public:
};
class Return : public Clause {
public:
public:
std::vector<std::shared_ptr<Expr>> exprs_;
void Accept(TreeVisitorBase& visitor) override {
visitor.PreVisit(*this);

View File

@ -9,6 +9,24 @@
#include "query/frontend/typecheck/symbol_table.hpp"
namespace query {
class ConsoleResultStream : public Loggable {
public:
ConsoleResultStream() : Loggable("ConsoleResultStream") {}
void Header(const std::vector<std::string>&) { logger.info("header"); }
void Result(std::vector<TypedValue>& values) {
for (auto value : values) {
logger.info(" result");
}
}
void Summary(const std::map<std::string, TypedValue>&) {
logger.info("summary");
}
};
class Cursor {
public:
virtual bool pull(Frame&, SymbolTable&) = 0;
@ -19,6 +37,10 @@ class LogicalOperator {
public:
auto children() { return children_; };
virtual std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor db) = 0;
virtual void WriteHeader(ConsoleResultStream&) {}
virtual std::vector<Symbol> OutputSymbols(SymbolTable& symbol_table) {
return {};
}
virtual ~LogicalOperator() {}
protected:
@ -32,8 +54,10 @@ class ScanAll : public LogicalOperator {
private:
class ScanAllCursor : public Cursor {
public:
ScanAllCursor(ScanAll& parent, GraphDbAccessor db)
: parent_(parent), db_(db), vertices_(db.vertices()),
ScanAllCursor(ScanAll& self, GraphDbAccessor db)
: self_(self),
db_(db),
vertices_(db.vertices()),
vertices_it_(vertices_.begin()) {}
bool pull(Frame& frame, SymbolTable& symbol_table) override {
@ -47,14 +71,14 @@ class ScanAll : public LogicalOperator {
}
private:
ScanAll& parent_;
ScanAll& self_;
GraphDbAccessor db_;
decltype(db_.vertices()) vertices_;
decltype(vertices_.begin()) vertices_it_;
bool evaluate(Frame& frame, SymbolTable& symbol_table,
VertexAccessor& vertex) {
auto node_part = parent_.node_part_;
auto node_part = self_.node_part_;
for (auto label : node_part->labels_) {
if (!vertex.has_label(label)) return false;
}
@ -65,8 +89,7 @@ class ScanAll : public LogicalOperator {
public:
std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor db) override {
Cursor* cursor = new ScanAllCursor(*this, db);
return std::unique_ptr<Cursor>(cursor);
return std::make_unique<Cursor>(ScanAllCursor(*this, db));
}
private:
@ -76,29 +99,56 @@ class ScanAll : public LogicalOperator {
class Produce : public LogicalOperator {
public:
Produce(std::shared_ptr<LogicalOperator> op, std::vector<std::shared_ptr<Expr>> exprs)
: exprs_(exprs) {
children_.emplace_back(op);
Produce(std::shared_ptr<LogicalOperator> input,
std::vector<std::shared_ptr<NamedExpr>> exprs)
: input_(input), exprs_(exprs) {
children_.emplace_back(input);
}
void WriteHeader(ConsoleResultStream& stream) override {
// TODO: write real result
stream.Header({"n"});
}
std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor db) override {
return std::make_unique<Cursor>(ProduceCursor(*this, db));
}
std::vector<Symbol> OutputSymbols(SymbolTable& symbol_table) override {
std::vector<Symbol> result(exprs_.size());
for (auto named_expr : exprs_) {
result.emplace_back(symbol_table[*named_expr->ident_]);
}
return result;
}
private:
class ProduceCursor : public Cursor {
public:
ProduceCursor(Produce& parent) : parent_(parent) {}
bool pull(Frame &frame, SymbolTable& symbol_table) override {
for (auto expr : parent_.exprs_) {
frame[symbol_table[*expr].position_] = expr->Evaluate(frame, symbol_table);
ProduceCursor(Produce& self, GraphDbAccessor db)
: self_(self), self_cursor_(self_.MakeCursor(db)) {}
bool pull(Frame& frame, SymbolTable& symbol_table) override {
if (self_cursor_->pull(frame, symbol_table)) {
for (auto expr : self_.exprs_) {
expr->Evaluate(frame, symbol_table);
}
return true;
}
return true;
return false;
}
private:
Produce& parent_;
Produce& self_;
std::unique_ptr<Cursor> self_cursor_;
};
public:
std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor) override {
return std::unique_ptr<Cursor>(new ProduceCursor(*this));
}
private:
std::vector<std::shared_ptr<Expr>> exprs_;
std::shared_ptr<LogicalOperator> input_;
std::vector<std::shared_ptr<NamedExpr>> exprs_;
};
}

View File

@ -10,23 +10,6 @@ using std::cout;
using std::cin;
using std::endl;
class ConsoleResultStream : public Loggable {
public:
ConsoleResultStream() : Loggable("ConsoleResultStream") {}
void Header(const std::vector<std::string>&) { logger.info("header"); }
void Result(std::vector<TypedValue>& values) {
for (auto value : values) {
logger.info(" result");
}
}
void Summary(const std::map<std::string, TypedValue>&) {
logger.info("summary");
}
};
int main(int argc, char* argv[]) {
// init arguments
REGISTER_ARGS(argc, argv);