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:
parent
db5f4469fe
commit
f9bcd6d760
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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};
|
||||
}
|
||||
|
@ -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"));
|
||||
|
Loading…
Reference in New Issue
Block a user