#pragma once #include #include #include #include "query/common.hpp" #include "query/context.hpp" #include "query/frontend/semantic/symbol_table.hpp" #include "query/interpret/frame.hpp" #include "query/plan/operator.hpp" #include "query_common.hpp" using namespace query; using namespace query::plan; using Bound = ScanAllByLabelPropertyRange::Bound; /** Helper function that collects all the results from the given Produce. */ std::vector> CollectProduce( Produce *produce, SymbolTable &symbol_table, database::GraphDbAccessor &db_accessor) { Frame frame(symbol_table.max_position()); // top level node in the operator tree is a produce (return) // so stream out results // collect the symbols from the return clause std::vector symbols; for (auto named_expression : produce->named_expressions()) symbols.emplace_back(symbol_table[*named_expression]); Context context(db_accessor); context.symbol_table_ = symbol_table; // stream out results auto cursor = produce->MakeCursor(db_accessor); std::vector> results; while (cursor->Pull(frame, context)) { std::vector values; for (auto &symbol : symbols) values.emplace_back(frame[symbol]); results.emplace_back(values); } return results; } int PullAll(std::shared_ptr logical_op, database::GraphDbAccessor &db, SymbolTable &symbol_table) { Frame frame(symbol_table.max_position()); auto cursor = logical_op->MakeCursor(db); int count = 0; Context context(db); context.symbol_table_ = symbol_table; while (cursor->Pull(frame, context)) count++; return count; } template auto MakeProduce(std::shared_ptr input, TNamedExpressions... named_expressions) { return std::make_shared( input, std::vector{named_expressions...}); } struct ScanAllTuple { NodeAtom *node_; std::shared_ptr op_; Symbol sym_; }; /** * Creates and returns a tuple of stuff for a scan-all starting * from the node with the given name. * * Returns ScanAllTuple(node_atom, scan_all_logical_op, symbol). */ ScanAllTuple MakeScanAll(AstStorage &storage, SymbolTable &symbol_table, const std::string &identifier, std::shared_ptr input = {nullptr}, GraphView graph_view = GraphView::OLD) { auto node = NODE(identifier); auto symbol = symbol_table.CreateSymbol(identifier, true); symbol_table[*node->identifier_] = symbol; auto logical_op = std::make_shared(input, symbol, graph_view); return ScanAllTuple{node, logical_op, symbol}; } /** * Creates and returns a tuple of stuff for a scan-all starting * from the node with the given name and label. * * Returns ScanAllTuple(node_atom, scan_all_logical_op, symbol). */ ScanAllTuple MakeScanAllByLabel( AstStorage &storage, SymbolTable &symbol_table, const std::string &identifier, storage::Label label, std::shared_ptr input = {nullptr}, GraphView graph_view = GraphView::OLD) { auto node = NODE(identifier); auto symbol = symbol_table.CreateSymbol(identifier, true); symbol_table[*node->identifier_] = symbol; auto logical_op = std::make_shared(input, symbol, label, graph_view); return ScanAllTuple{node, logical_op, symbol}; } /** * Creates and returns a tuple of stuff for a scan-all starting from the node * with the given name and label whose property values are in range. * * Returns ScanAllTuple(node_atom, scan_all_logical_op, symbol). */ ScanAllTuple MakeScanAllByLabelPropertyRange( AstStorage &storage, SymbolTable &symbol_table, std::string identifier, storage::Label label, storage::Property property, std::experimental::optional lower_bound, std::experimental::optional upper_bound, std::shared_ptr input = {nullptr}, GraphView graph_view = GraphView::OLD) { auto node = NODE(identifier); auto symbol = symbol_table.CreateSymbol(identifier, true); symbol_table[*node->identifier_] = symbol; auto logical_op = std::make_shared( input, symbol, label, property, lower_bound, upper_bound, graph_view); return ScanAllTuple{node, logical_op, symbol}; } /** * Creates and returns a tuple of stuff for a scan-all starting from the node * with the given name and label whose property value is equal to given value. * * Returns ScanAllTuple(node_atom, scan_all_logical_op, symbol). */ ScanAllTuple MakeScanAllByLabelPropertyValue( AstStorage &storage, SymbolTable &symbol_table, std::string identifier, storage::Label label, storage::Property property, Expression *value, std::shared_ptr input = {nullptr}, GraphView graph_view = GraphView::OLD) { auto node = NODE(identifier); auto symbol = symbol_table.CreateSymbol(identifier, true); symbol_table[*node->identifier_] = symbol; auto logical_op = std::make_shared( input, symbol, label, property, value, graph_view); return ScanAllTuple{node, logical_op, symbol}; } struct ExpandTuple { EdgeAtom *edge_; Symbol edge_sym_; NodeAtom *node_; Symbol node_sym_; std::shared_ptr op_; }; ExpandTuple MakeExpand(AstStorage &storage, SymbolTable &symbol_table, std::shared_ptr input, Symbol input_symbol, const std::string &edge_identifier, EdgeAtom::Direction direction, const std::vector &edge_types, const std::string &node_identifier, bool existing_node, GraphView graph_view) { auto edge = EDGE(edge_identifier, direction); auto edge_sym = symbol_table.CreateSymbol(edge_identifier, true); symbol_table[*edge->identifier_] = edge_sym; auto node = NODE(node_identifier); auto node_sym = symbol_table.CreateSymbol(node_identifier, true); symbol_table[*node->identifier_] = node_sym; auto op = std::make_shared(node_sym, edge_sym, direction, edge_types, input, input_symbol, existing_node, graph_view); return ExpandTuple{edge, edge_sym, node, node_sym, op}; } template auto CountIterable(TIterable iterable) { return std::distance(iterable.begin(), iterable.end()); }