Replace Atoms with Symbols in Expand operator

Reviewers: florijan, mislav.bradac

Reviewed By: florijan

Differential Revision: https://phabricator.memgraph.io/D404
This commit is contained in:
Teon Banek 2017-05-30 10:39:17 +02:00
parent db5f4469fe
commit f9bcd6d760
5 changed files with 53 additions and 43 deletions

View File

@ -246,12 +246,14 @@ std::unique_ptr<Cursor> ScanAllByLabel::MakeCursor(GraphDbAccessor &db) {
output_symbol_, input_->MakeCursor(db), std::move(vertices));
}
Expand::Expand(const NodeAtom *node_atom, const EdgeAtom *edge_atom,
Expand::Expand(Symbol node_symbol, Symbol edge_symbol,
EdgeAtom::Direction direction,
const std::shared_ptr<LogicalOperator> &input,
Symbol input_symbol, bool existing_node, bool existing_edge,
GraphView graph_view)
: node_atom_(node_atom),
edge_atom_(edge_atom),
: node_symbol_(node_symbol),
edge_symbol_(edge_symbol),
direction_(direction),
input_(input ? input : std::make_shared<Once>()),
input_symbol_(input_symbol),
existing_node_(existing_node),
@ -285,8 +287,7 @@ bool Expand::ExpandCursor::Pull(Frame &frame, const SymbolTable &symbol_table) {
// when expanding in EdgeAtom::Direction::BOTH directions
// we should do only one expansion for cycles, and it was
// already done in the block above
if (self_.edge_atom_->direction_ == EdgeAtom::Direction::BOTH &&
edge.is_cycle())
if (self_.direction_ == EdgeAtom::Direction::BOTH && edge.is_cycle())
continue;
if (HandleExistingEdge(edge, frame, symbol_table) &&
PullNode(edge, EdgeAtom::Direction::RIGHT, frame, symbol_table))
@ -334,7 +335,7 @@ bool Expand::ExpandCursor::InitEdges(Frame &frame,
break;
}
auto direction = self_.edge_atom_->direction_;
auto direction = self_.direction_;
if (direction == EdgeAtom::Direction::LEFT ||
direction == EdgeAtom::Direction::BOTH) {
in_edges_ = std::make_unique<InEdgeT>(vertex.in());
@ -359,14 +360,13 @@ bool Expand::ExpandCursor::HandleExistingEdge(const EdgeAccessor &new_edge,
Frame &frame,
const SymbolTable &symbol_table) {
if (self_.existing_edge_) {
TypedValue &old_edge_value =
frame[symbol_table.at(*self_.edge_atom_->identifier_)];
TypedValue &old_edge_value = frame[self_.edge_symbol_];
// old_edge_value may be Null when using optional matching
return !old_edge_value.IsNull() &&
old_edge_value.Value<EdgeAccessor>() == new_edge;
} else {
// not matching existing, so put the new_edge into the frame and return true
frame[symbol_table.at(*self_.edge_atom_->identifier_)] = new_edge;
frame[self_.edge_symbol_] = new_edge;
return true;
}
}
@ -388,14 +388,13 @@ bool Expand::ExpandCursor::HandleExistingNode(const VertexAccessor new_node,
Frame &frame,
const SymbolTable &symbol_table) {
if (self_.existing_node_) {
TypedValue &old_node_value =
frame[symbol_table.at(*self_.node_atom_->identifier_)];
TypedValue &old_node_value = frame[self_.node_symbol_];
// old_node_value may be Null when using optional matching
return !old_node_value.IsNull() &&
old_node_value.Value<VertexAccessor>() == new_node;
} else {
// not matching existing, so put the new_edge into the frame and return true
frame[symbol_table.at(*self_.node_atom_->identifier_)] = new_node;
// not matching existing, so put the new_node into the frame and return true
frame[self_.node_symbol_] = new_node;
return true;
}
}

View File

@ -358,18 +358,21 @@ class Expand : public LogicalOperator {
* the expansion originates from. This is controlled with a
* constructor argument.
*
* @param node_atom Describes the node to be expanded. Only the
* identifier is used, labels and properties are ignored.
* @param edge_atom Describes the edge to be expanded. Identifier
* and direction are used, edge type and properties are ignored.
* @param node_symbol Symbol pointing to the node to be expanded. This is
* where the new node will be stored.
* @param edge_symbol Symbol for the edge to be expanded. This is where the
* edge value will be stored.
* @param direction EdgeAtom::Direction determining the direction of edge
* expansion. The direction is relative to the starting vertex (pointed by
* `input_symbol`).
* @param input Optional LogicalOperator that preceeds this one.
* @param input_symbol Symbol that points to a VertexAccessor
* in the Frame that expansion should emanate from.
* @param existing_node If or not the node to be expanded is already
* present in the Frame and should just be checked for equality.
* @param existing_edge Same like 'existing_node', but for edges.
* @param input_symbol Symbol that points to a VertexAccessor in the Frame
* that expansion should emanate from.
* @param existing_node If or not the node to be expanded is already present
* in the Frame and should just be checked for equality.
* @param existing_edge Same like `existing_node`, but for edges.
*/
Expand(const NodeAtom *node_atom, const EdgeAtom *edge_atom,
Expand(Symbol node_symbol, Symbol edge_symbol, EdgeAtom::Direction direction,
const std::shared_ptr<LogicalOperator> &input, Symbol input_symbol,
bool existing_node, bool existing_edge,
GraphView graph_view = GraphView::AS_IS);
@ -378,8 +381,9 @@ class Expand : public LogicalOperator {
private:
// info on what's getting expanded
const NodeAtom *node_atom_;
const EdgeAtom *edge_atom_;
const Symbol node_symbol_;
const Symbol edge_symbol_;
const EdgeAtom::Direction direction_;
// the input op and the symbol under which the op's result
// can be found in the frame

View File

@ -793,7 +793,7 @@ LogicalOperator *PlanMatching(const Matching &matching,
context.new_symbols.emplace_back(edge_symbol);
}
last_op =
new Expand(expansion.node2, expansion.edge,
new Expand(node_symbol, edge_symbol, expansion.edge->direction_,
std::shared_ptr<LogicalOperator>(last_op), node1_symbol,
existing_node, existing_edge, context.graph_view);
if (!existing_edge) {

View File

@ -139,8 +139,9 @@ ExpandTuple MakeExpand(AstTreeStorage &storage, SymbolTable &symbol_table,
auto node_sym = symbol_table.CreateSymbol(node_identifier, true);
symbol_table[*node->identifier_] = node_sym;
auto op = std::make_shared<Expand>(node, edge, input, input_symbol,
existing_node, existing_edge, graph_view);
auto op = std::make_shared<Expand>(node_sym, edge_sym, direction, input,
input_symbol, existing_node, existing_edge,
graph_view);
return ExpandTuple{edge, edge_sym, node, node_sym, op};
}

View File

@ -409,12 +409,14 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
auto with = MakeProduce(optional, n_ne);
// MATCH (m) -[r]-> (n)
auto m = MakeScanAll(storage, symbol_table, "m", with);
auto edge = EDGE("r", EdgeAtom::Direction::RIGHT);
symbol_table[*edge->identifier_] = symbol_table.CreateSymbol("r", true);
auto edge_direction = EdgeAtom::Direction::RIGHT;
auto edge = EDGE("r", edge_direction);
auto edge_sym = symbol_table.CreateSymbol("r", true);
symbol_table[*edge->identifier_] = edge_sym;
auto node = NODE("n");
symbol_table[*node->identifier_] = with_n_sym;
auto expand =
std::make_shared<plan::Expand>(node, edge, m.op_, m.sym_, true, false);
auto expand = std::make_shared<plan::Expand>(
with_n_sym, edge_sym, edge_direction, m.op_, m.sym_, true, false);
// RETURN m
auto m_ne = NEXPR("m", IDENT("m"));
symbol_table[*m_ne->expression_] = m.sym_;
@ -452,17 +454,19 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingEdge) {
// WITH r
auto r_ne = NEXPR("r", IDENT("r"));
symbol_table[*r_ne->expression_] = r_m.edge_sym_;
auto with_n_sym = symbol_table.CreateSymbol("r", true);
symbol_table[*r_ne] = with_n_sym;
auto with_r_sym = symbol_table.CreateSymbol("r", true);
symbol_table[*r_ne] = with_r_sym;
auto with = MakeProduce(optional, r_ne);
// MATCH (a) -[r]- (b)
auto a = MakeScanAll(storage, symbol_table, "a", with);
auto edge = EDGE("r", EdgeAtom::Direction::BOTH);
symbol_table[*edge->identifier_] = r_m.edge_sym_;
auto edge_direction = EdgeAtom::Direction::BOTH;
auto edge = EDGE("r", edge_direction);
symbol_table[*edge->identifier_] = with_r_sym;
auto node = NODE("n");
symbol_table[*node->identifier_] = symbol_table.CreateSymbol("b", true);
auto expand =
std::make_shared<plan::Expand>(node, edge, a.op_, a.sym_, false, true);
auto node_sym = symbol_table.CreateSymbol("b", true);
symbol_table[*node->identifier_] = node_sym;
auto expand = std::make_shared<plan::Expand>(
node_sym, with_r_sym, edge_direction, a.op_, a.sym_, false, true);
// RETURN a
auto a_ne = NEXPR("a", IDENT("a"));
symbol_table[*a_ne->expression_] = a.sym_;
@ -494,8 +498,9 @@ TEST(QueryPlan, ExpandExistingNode) {
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
EdgeAtom::Direction::RIGHT, false, "n", with_existing);
if (with_existing)
symbol_table[*r_n.node_->identifier_] =
symbol_table[*n.node_->identifier_];
r_n.op_ =
std::make_shared<Expand>(n.sym_, r_n.edge_sym_, r_n.edge_->direction_,
n.op_, n.sym_, with_existing, false);
// make a named expression and a produce
auto output = NEXPR("n", IDENT("n"));
@ -538,8 +543,9 @@ TEST(QueryPlan, ExpandExistingEdge) {
auto r_k = MakeExpand(storage, symbol_table, r_j.op_, r_j.node_sym_, "r",
EdgeAtom::Direction::BOTH, with_existing, "k", false);
if (with_existing)
symbol_table[*r_k.edge_->identifier_] =
symbol_table[*r_j.edge_->identifier_];
r_k.op_ = std::make_shared<Expand>(r_k.node_sym_, r_j.edge_sym_,
r_k.edge_->direction_, r_j.op_,
r_j.node_sym_, false, with_existing);
// make a named expression and a produce
auto output = NEXPR("r", IDENT("r"));