2017-04-11 21:11:48 +08:00
|
|
|
//
|
|
|
|
// Copyright 2017 Memgraph
|
|
|
|
// Created by Florijan Stamenkovic on 14.03.17.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include <iterator>
|
|
|
|
#include <memory>
|
|
|
|
#include <vector>
|
|
|
|
|
2017-04-25 21:38:46 +08:00
|
|
|
#include "communication/result_stream_faker.hpp"
|
|
|
|
#include "query/common.hpp"
|
2017-04-11 21:11:48 +08:00
|
|
|
#include "query/frontend/semantic/symbol_table.hpp"
|
2017-04-13 16:01:16 +08:00
|
|
|
#include "query/interpret/frame.hpp"
|
2017-04-25 21:38:46 +08:00
|
|
|
#include "query/plan/operator.hpp"
|
2017-04-11 21:11:48 +08:00
|
|
|
|
|
|
|
#include "query_common.hpp"
|
|
|
|
|
|
|
|
using namespace query;
|
|
|
|
using namespace query::plan;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper function that collects all the results from the given
|
|
|
|
* Produce into a ResultStreamFaker and returns that object.
|
|
|
|
*
|
|
|
|
* @param produce
|
|
|
|
* @param symbol_table
|
|
|
|
* @param db_accessor
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
auto CollectProduce(std::shared_ptr<Produce> produce, SymbolTable &symbol_table,
|
|
|
|
GraphDbAccessor &db_accessor) {
|
|
|
|
ResultStreamFaker stream;
|
|
|
|
Frame frame(symbol_table.max_position());
|
|
|
|
|
|
|
|
// top level node in the operator tree is a produce (return)
|
|
|
|
// so stream out results
|
|
|
|
|
|
|
|
// generate header
|
|
|
|
std::vector<std::string> header;
|
|
|
|
for (auto named_expression : produce->named_expressions())
|
|
|
|
header.push_back(named_expression->name_);
|
|
|
|
stream.Header(header);
|
|
|
|
|
|
|
|
// collect the symbols from the return clause
|
|
|
|
std::vector<Symbol> symbols;
|
|
|
|
for (auto named_expression : produce->named_expressions())
|
|
|
|
symbols.emplace_back(symbol_table[*named_expression]);
|
|
|
|
|
|
|
|
// stream out results
|
|
|
|
auto cursor = produce->MakeCursor(db_accessor);
|
|
|
|
while (cursor->Pull(frame, symbol_table)) {
|
|
|
|
std::vector<TypedValue> values;
|
|
|
|
for (auto &symbol : symbols) values.emplace_back(frame[symbol]);
|
|
|
|
stream.Result(values);
|
|
|
|
}
|
|
|
|
|
|
|
|
stream.Summary({{std::string("type"), TypedValue("r")}});
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
int PullAll(std::shared_ptr<LogicalOperator> logical_op, GraphDbAccessor &db,
|
2017-04-18 21:19:42 +08:00
|
|
|
SymbolTable &symbol_table) {
|
2017-04-11 21:11:48 +08:00
|
|
|
Frame frame(symbol_table.max_position());
|
|
|
|
auto cursor = logical_op->MakeCursor(db);
|
|
|
|
int count = 0;
|
|
|
|
while (cursor->Pull(frame, symbol_table)) count++;
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename... TNamedExpressions>
|
|
|
|
auto MakeProduce(std::shared_ptr<LogicalOperator> input,
|
|
|
|
TNamedExpressions... named_expressions) {
|
|
|
|
return std::make_shared<Produce>(
|
|
|
|
input, std::vector<NamedExpression *>{named_expressions...});
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ScanAllTuple {
|
|
|
|
NodeAtom *node_;
|
|
|
|
std::shared_ptr<LogicalOperator> op_;
|
|
|
|
Symbol sym_;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates and returns a tuple of stuff for a scan-all starting
|
|
|
|
* from the node with the given name.
|
|
|
|
*
|
|
|
|
* Returns (node_atom, scan_all_logical_op, symbol).
|
|
|
|
*/
|
|
|
|
ScanAllTuple MakeScanAll(AstTreeStorage &storage, SymbolTable &symbol_table,
|
|
|
|
const std::string &identifier,
|
2017-04-25 21:38:46 +08:00
|
|
|
std::shared_ptr<LogicalOperator> input = {nullptr},
|
|
|
|
GraphView graph_view = GraphView::OLD) {
|
2017-04-11 21:11:48 +08:00
|
|
|
auto node = NODE(identifier);
|
2017-04-25 21:38:46 +08:00
|
|
|
auto logical_op = std::make_shared<ScanAll>(node, input, graph_view);
|
2017-05-12 17:37:22 +08:00
|
|
|
auto symbol = symbol_table.CreateSymbol(identifier, true);
|
2017-04-11 21:11:48 +08:00
|
|
|
symbol_table[*node->identifier_] = symbol;
|
|
|
|
// return std::make_tuple(node, logical_op, symbol);
|
|
|
|
return ScanAllTuple{node, logical_op, symbol};
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ExpandTuple {
|
|
|
|
EdgeAtom *edge_;
|
|
|
|
Symbol edge_sym_;
|
|
|
|
NodeAtom *node_;
|
|
|
|
Symbol node_sym_;
|
|
|
|
std::shared_ptr<LogicalOperator> op_;
|
|
|
|
};
|
|
|
|
|
|
|
|
ExpandTuple MakeExpand(AstTreeStorage &storage, SymbolTable &symbol_table,
|
|
|
|
std::shared_ptr<LogicalOperator> input,
|
|
|
|
Symbol input_symbol, const std::string &edge_identifier,
|
2017-04-25 21:38:46 +08:00
|
|
|
EdgeAtom::Direction direction, bool existing_edge,
|
|
|
|
const std::string &node_identifier, bool existing_node,
|
|
|
|
GraphView graph_view = GraphView::AS_IS) {
|
2017-04-11 21:11:48 +08:00
|
|
|
auto edge = EDGE(edge_identifier, direction);
|
2017-05-12 17:37:22 +08:00
|
|
|
auto edge_sym = symbol_table.CreateSymbol(edge_identifier, true);
|
2017-04-11 21:11:48 +08:00
|
|
|
symbol_table[*edge->identifier_] = edge_sym;
|
|
|
|
|
|
|
|
auto node = NODE(node_identifier);
|
2017-05-12 17:37:22 +08:00
|
|
|
auto node_sym = symbol_table.CreateSymbol(node_identifier, true);
|
2017-04-11 21:11:48 +08:00
|
|
|
symbol_table[*node->identifier_] = node_sym;
|
|
|
|
|
|
|
|
auto op = std::make_shared<Expand>(node, edge, input, input_symbol,
|
2017-04-25 21:38:46 +08:00
|
|
|
existing_node, existing_edge, graph_view);
|
2017-04-11 21:11:48 +08:00
|
|
|
|
|
|
|
return ExpandTuple{edge, edge_sym, node, node_sym, op};
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TIterable>
|
|
|
|
auto CountIterable(TIterable iterable) {
|
|
|
|
return std::distance(iterable.begin(), iterable.end());
|
|
|
|
}
|