Remove AS_IS from GraphView
Summary: Removing `AS_IS` from GraphView because it doesn't seem like it is necessary for query execution and it also has weird semantics (you might get a mix of old and new records). `Unwind`, `OrderBy` and `PullRemoteOrderBy` now use `OLD` graph view. Remove AS_IS from GraphView Fix query_cost_estimator tests Fix query_expression_evaluator tests Fix query_plan_match_filter_return tests Fix query_plan_create_set_remove_delete tests Fix query_plan_accumulate_aggregate tests Reviewers: teon.banek, buda Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1390
This commit is contained in:
parent
909e42d414
commit
0a6b8cdf4f
@ -21,12 +21,8 @@ std::string ParseParameter(const std::string &s);
|
||||
* see the OLD graph state (the latest state before the
|
||||
* current transaction+command), or NEW (state as
|
||||
* changed by the current transaction+command).
|
||||
*
|
||||
* Also some part of query execution could leave
|
||||
* the graph state AS_IS, that is as it was left
|
||||
* by some previous part of execution.
|
||||
*/
|
||||
enum class GraphView { AS_IS, OLD, NEW };
|
||||
enum class GraphView { OLD, NEW };
|
||||
|
||||
/**
|
||||
* Helper function for recursively reconstructing all the accessors in the
|
||||
@ -68,4 +64,4 @@ class TypedValueVectorCompare {
|
||||
// - (list, map, path, vertex, edge) can't compare to anything
|
||||
bool TypedValueCompare(const TypedValue &a, const TypedValue &b) const;
|
||||
};
|
||||
}
|
||||
} // namespace query
|
||||
|
@ -22,7 +22,7 @@ class ExpressionEvaluator : public TreeVisitor<TypedValue> {
|
||||
ExpressionEvaluator(Frame &frame, const Parameters ¶meters,
|
||||
const SymbolTable &symbol_table,
|
||||
database::GraphDbAccessor &db_accessor,
|
||||
GraphView graph_view = GraphView::AS_IS)
|
||||
GraphView graph_view)
|
||||
: frame_(frame),
|
||||
parameters_(parameters),
|
||||
symbol_table_(symbol_table),
|
||||
@ -444,7 +444,6 @@ class ExpressionEvaluator : public TreeVisitor<TypedValue> {
|
||||
// If the given TypedValue contains accessors, switch them to New or Old,
|
||||
// depending on use_new_ flag.
|
||||
void SwitchAccessors(TypedValue &value) {
|
||||
if (graph_view_ == GraphView::AS_IS) return;
|
||||
switch (value.type()) {
|
||||
case TypedValue::Type::Vertex: {
|
||||
auto &vertex = value.Value<VertexAccessor>();
|
||||
|
@ -353,10 +353,7 @@ ScanAll::ScanAll(const std::shared_ptr<LogicalOperator> &input,
|
||||
Symbol output_symbol, GraphView graph_view)
|
||||
: input_(input ? input : std::make_shared<Once>()),
|
||||
output_symbol_(output_symbol),
|
||||
graph_view_(graph_view) {
|
||||
CHECK(graph_view != GraphView::AS_IS)
|
||||
<< "ScanAll must have explicitly defined GraphView";
|
||||
}
|
||||
graph_view_(graph_view) {}
|
||||
|
||||
ACCEPT_WITH_INPUT(ScanAll)
|
||||
|
||||
@ -414,32 +411,32 @@ std::unique_ptr<Cursor> ScanAllByLabelPropertyRange::MakeCursor(
|
||||
-> std::experimental::optional<decltype(
|
||||
db.Vertices(label_, property_, std::experimental::nullopt,
|
||||
std::experimental::nullopt, false))> {
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db, graph_view_);
|
||||
auto convert = [&evaluator](const auto &bound)
|
||||
-> std::experimental::optional<utils::Bound<PropertyValue>> {
|
||||
if (!bound) return std::experimental::nullopt;
|
||||
auto value = bound->value()->Accept(evaluator);
|
||||
try {
|
||||
return std::experimental::make_optional(
|
||||
utils::Bound<PropertyValue>(value, bound->type()));
|
||||
} catch (const TypedValueException &) {
|
||||
throw QueryRuntimeException(
|
||||
"'{}' cannot be used as a property value.", value.type());
|
||||
}
|
||||
};
|
||||
auto maybe_lower = convert(lower_bound());
|
||||
auto maybe_upper = convert(upper_bound());
|
||||
// If any bound is null, then the comparison would result in nulls. This
|
||||
// is treated as not satisfying the filter, so return no vertices.
|
||||
if (maybe_lower && maybe_lower->value().IsNull())
|
||||
return std::experimental::nullopt;
|
||||
if (maybe_upper && maybe_upper->value().IsNull())
|
||||
return std::experimental::nullopt;
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db, graph_view_);
|
||||
auto convert = [&evaluator](const auto &bound)
|
||||
-> std::experimental::optional<utils::Bound<PropertyValue>> {
|
||||
if (!bound) return std::experimental::nullopt;
|
||||
auto value = bound->value()->Accept(evaluator);
|
||||
try {
|
||||
return std::experimental::make_optional(
|
||||
db.Vertices(label_, property_, maybe_lower, maybe_upper,
|
||||
graph_view_ == GraphView::NEW));
|
||||
};
|
||||
utils::Bound<PropertyValue>(value, bound->type()));
|
||||
} catch (const TypedValueException &) {
|
||||
throw QueryRuntimeException("'{}' cannot be used as a property value.",
|
||||
value.type());
|
||||
}
|
||||
};
|
||||
auto maybe_lower = convert(lower_bound());
|
||||
auto maybe_upper = convert(upper_bound());
|
||||
// If any bound is null, then the comparison would result in nulls. This
|
||||
// is treated as not satisfying the filter, so return no vertices.
|
||||
if (maybe_lower && maybe_lower->value().IsNull())
|
||||
return std::experimental::nullopt;
|
||||
if (maybe_upper && maybe_upper->value().IsNull())
|
||||
return std::experimental::nullopt;
|
||||
return std::experimental::make_optional(
|
||||
db.Vertices(label_, property_, maybe_lower, maybe_upper,
|
||||
graph_view_ == GraphView::NEW));
|
||||
};
|
||||
return std::make_unique<ScanAllCursor<decltype(vertices)>>(
|
||||
output_symbol_, input_->MakeCursor(db), std::move(vertices), db);
|
||||
}
|
||||
@ -462,18 +459,18 @@ std::unique_ptr<Cursor> ScanAllByLabelPropertyValue::MakeCursor(
|
||||
auto vertices = [this, &db](Frame &frame, Context &context)
|
||||
-> std::experimental::optional<decltype(
|
||||
db.Vertices(label_, property_, TypedValue::Null, false))> {
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db, graph_view_);
|
||||
auto value = expression_->Accept(evaluator);
|
||||
if (value.IsNull()) return std::experimental::nullopt;
|
||||
try {
|
||||
return std::experimental::make_optional(db.Vertices(
|
||||
label_, property_, value, graph_view_ == GraphView::NEW));
|
||||
} catch (const TypedValueException &) {
|
||||
throw QueryRuntimeException(
|
||||
"'{}' cannot be used as a property value.", value.type());
|
||||
}
|
||||
};
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db, graph_view_);
|
||||
auto value = expression_->Accept(evaluator);
|
||||
if (value.IsNull()) return std::experimental::nullopt;
|
||||
try {
|
||||
return std::experimental::make_optional(
|
||||
db.Vertices(label_, property_, value, graph_view_ == GraphView::NEW));
|
||||
} catch (const TypedValueException &) {
|
||||
throw QueryRuntimeException("'{}' cannot be used as a property value.",
|
||||
value.type());
|
||||
}
|
||||
};
|
||||
return std::make_unique<ScanAllCursor<decltype(vertices)>>(
|
||||
output_symbol_, input_->MakeCursor(db), std::move(vertices), db);
|
||||
}
|
||||
@ -666,8 +663,6 @@ void SwitchAccessor(TAccessor &accessor, GraphView graph_view) {
|
||||
case GraphView::OLD:
|
||||
accessor.SwitchOld();
|
||||
break;
|
||||
case GraphView::AS_IS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@ -907,7 +902,8 @@ class ExpandVariableCursor : public Cursor {
|
||||
|
||||
// Evaluate the upper and lower bounds.
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db_);
|
||||
context.symbol_table_, db_,
|
||||
self_.graph_view_);
|
||||
auto calc_bound = [&evaluator](auto &bound) {
|
||||
auto value = EvaluateInt(evaluator, bound, "Variable expansion bound");
|
||||
if (value < 0)
|
||||
@ -1055,7 +1051,7 @@ class ExpandBreadthFirstCursor : public query::plan::Cursor {
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool Pull(Frame &frame, Context &context) override {
|
||||
// evaulator for the filtering condition
|
||||
// evaluator for the filtering condition
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db_,
|
||||
self_.graph_view_);
|
||||
@ -1224,7 +1220,8 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor {
|
||||
// For the given (edge, vertex, weight, depth) tuple checks if they
|
||||
// satisfy the "where" condition. if so, places them in the priority queue.
|
||||
auto expand_pair = [this, &evaluator, &frame, &create_state](
|
||||
EdgeAccessor edge, VertexAccessor vertex, double weight, int depth) {
|
||||
EdgeAccessor edge, VertexAccessor vertex,
|
||||
double weight, int depth) {
|
||||
SwitchAccessor(edge, self_.graph_view_);
|
||||
SwitchAccessor(vertex, self_.graph_view_);
|
||||
|
||||
@ -2433,10 +2430,11 @@ Skip::SkipCursor::SkipCursor(const Skip &self, database::GraphDbAccessor &db)
|
||||
bool Skip::SkipCursor::Pull(Frame &frame, Context &context) {
|
||||
while (input_cursor_->Pull(frame, context)) {
|
||||
if (to_skip_ == -1) {
|
||||
// first successful pull from the input
|
||||
// evaluate the skip expression
|
||||
// First successful pull from the input, evaluate the skip expression. The
|
||||
// skip expression doesn't contain identifiers so graph view parameter is
|
||||
// not important.
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db_);
|
||||
context.symbol_table_, db_, GraphView::OLD);
|
||||
TypedValue to_skip = self_.expression_->Accept(evaluator);
|
||||
if (to_skip.type() != TypedValue::Type::Int)
|
||||
throw QueryRuntimeException("Result of SKIP expression must be an int");
|
||||
@ -2484,13 +2482,15 @@ Limit::LimitCursor::LimitCursor(const Limit &self,
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool Limit::LimitCursor::Pull(Frame &frame, Context &context) {
|
||||
// we need to evaluate the limit expression before the first input Pull
|
||||
// because it might be 0 and thereby we shouldn't Pull from input at all
|
||||
// we can do this before Pulling from the input because the limit
|
||||
// expression is not allowed to contain any identifiers
|
||||
// We need to evaluate the limit expression before the first input Pull
|
||||
// because it might be 0 and thereby we shouldn't Pull from input at all.
|
||||
// We can do this before Pulling from the input because the limit expression
|
||||
// is not allowed to contain any identifiers.
|
||||
if (limit_ == -1) {
|
||||
// Limit expression doesn't contain identifiers so graph view is not
|
||||
// important.
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db_);
|
||||
context.symbol_table_, db_, GraphView::OLD);
|
||||
TypedValue limit = self_.expression_->Accept(evaluator);
|
||||
if (limit.type() != TypedValue::Type::Int)
|
||||
throw QueryRuntimeException("Result of LIMIT expression must be an int");
|
||||
@ -2552,7 +2552,7 @@ OrderBy::OrderByCursor::OrderByCursor(const OrderBy &self,
|
||||
bool OrderBy::OrderByCursor::Pull(Frame &frame, Context &context) {
|
||||
if (!did_pull_all_) {
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db_);
|
||||
context.symbol_table_, db_, GraphView::OLD);
|
||||
while (input_cursor_->Pull(frame, context)) {
|
||||
// collect the order_by elements
|
||||
std::vector<TypedValue> order_by;
|
||||
@ -2782,7 +2782,7 @@ bool Unwind::UnwindCursor::Pull(Frame &frame, Context &context) {
|
||||
|
||||
// successful pull from input, initialize value and iterator
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, db_);
|
||||
context.symbol_table_, db_, GraphView::OLD);
|
||||
TypedValue input_value = self_.input_expression_->Accept(evaluator);
|
||||
if (input_value.type() != TypedValue::Type::List)
|
||||
throw QueryRuntimeException("UNWIND only accepts list values, got '{}'",
|
||||
@ -3501,7 +3501,8 @@ class PullRemoteOrderByCursor : public Cursor {
|
||||
bool Pull(Frame &frame, Context &context) {
|
||||
if (context.db_accessor_.should_abort()) throw HintedAbortError();
|
||||
ExpressionEvaluator evaluator(frame, context.parameters_,
|
||||
context.symbol_table_, context.db_accessor_);
|
||||
context.symbol_table_, context.db_accessor_,
|
||||
GraphView::OLD);
|
||||
|
||||
auto evaluate_result = [this, &evaluator]() {
|
||||
std::vector<TypedValue> order_by;
|
||||
|
@ -645,7 +645,7 @@ expansion")
|
||||
const std::vector<storage::EdgeType> &edge_types,
|
||||
const std::shared_ptr<LogicalOperator> &input,
|
||||
Symbol input_symbol, bool existing_node,
|
||||
GraphView graph_view = GraphView::AS_IS);
|
||||
GraphView graph_view);
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
@ -808,7 +808,7 @@ pulled.")
|
||||
Symbol input_symbol, bool existing_node, Lambda filter_lambda,
|
||||
std::experimental::optional<Lambda> weight_lambda,
|
||||
std::experimental::optional<Symbol> total_weight,
|
||||
GraphView graph_view = GraphView::AS_IS);
|
||||
GraphView graph_view);
|
||||
|
||||
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
||||
std::unique_ptr<Cursor> MakeCursor(
|
||||
|
@ -163,7 +163,7 @@ TEST_F(QueryCostEstimator, ScanAllByLabelPropertyRangeConstExpr) {
|
||||
TEST_F(QueryCostEstimator, Expand) {
|
||||
MakeOp<Expand>(NextSymbol(), NextSymbol(), EdgeAtom::Direction::IN,
|
||||
std::vector<storage::EdgeType>{}, last_op_, NextSymbol(),
|
||||
false);
|
||||
false, GraphView::OLD);
|
||||
EXPECT_COST(CardParam::kExpand * CostParam::kExpand);
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ TEST_F(QueryCostEstimator, ExpandVariable) {
|
||||
EdgeAtom::Direction::IN, std::vector<storage::EdgeType>{}, false, nullptr,
|
||||
nullptr, last_op_, NextSymbol(), false,
|
||||
ExpandVariable::Lambda{NextSymbol(), NextSymbol(), nullptr},
|
||||
std::experimental::nullopt, std::experimental::nullopt);
|
||||
std::experimental::nullopt, std::experimental::nullopt, GraphView::OLD);
|
||||
EXPECT_COST(CardParam::kExpandVariable * CostParam::kExpandVariable);
|
||||
}
|
||||
|
||||
@ -199,11 +199,12 @@ TEST_F(QueryCostEstimator, ExpandUniquenessFilter) {
|
||||
}
|
||||
|
||||
TEST_F(QueryCostEstimator, UnwindLiteral) {
|
||||
TEST_OP(MakeOp<query::plan::Unwind>(
|
||||
last_op_, storage_.Create<ListLiteral>(
|
||||
std::vector<Expression *>(7, nullptr)),
|
||||
NextSymbol()),
|
||||
CostParam::kUnwind, 7);
|
||||
TEST_OP(
|
||||
MakeOp<query::plan::Unwind>(
|
||||
last_op_,
|
||||
storage_.Create<ListLiteral>(std::vector<Expression *>(7, nullptr)),
|
||||
NextSymbol()),
|
||||
CostParam::kUnwind, 7);
|
||||
}
|
||||
|
||||
TEST_F(QueryCostEstimator, UnwindNoLiteral) {
|
||||
|
@ -33,7 +33,8 @@ struct NoContextExpressionEvaluator {
|
||||
database::SingleNode db;
|
||||
database::GraphDbAccessor dba{db};
|
||||
Parameters parameters;
|
||||
ExpressionEvaluator eval{frame, parameters, symbol_table, dba};
|
||||
ExpressionEvaluator eval{frame, parameters, symbol_table, dba,
|
||||
GraphView::OLD};
|
||||
};
|
||||
|
||||
TypedValue EvaluateFunction(const std::string &function_name,
|
||||
@ -44,7 +45,8 @@ TypedValue EvaluateFunction(const std::string &function_name,
|
||||
database::GraphDbAccessor dba(db);
|
||||
Frame frame{128};
|
||||
Parameters parameters;
|
||||
ExpressionEvaluator eval{frame, parameters, symbol_table, dba};
|
||||
ExpressionEvaluator eval{frame, parameters, symbol_table, dba,
|
||||
GraphView::OLD};
|
||||
|
||||
std::vector<Expression *> expressions;
|
||||
for (const auto &arg : args) {
|
||||
@ -719,7 +721,8 @@ TEST(ExpressionEvaluator, Aggregation) {
|
||||
database::SingleNode db;
|
||||
database::GraphDbAccessor dba(db);
|
||||
Parameters parameters;
|
||||
ExpressionEvaluator eval{frame, parameters, symbol_table, dba};
|
||||
ExpressionEvaluator eval{frame, parameters, symbol_table, dba,
|
||||
GraphView::OLD};
|
||||
auto value = aggr->Accept(eval);
|
||||
EXPECT_EQ(value.Value<int64_t>(), 1);
|
||||
}
|
||||
|
@ -42,8 +42,9 @@ TEST(QueryPlan, Accumulate) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
|
||||
auto one = LITERAL(1);
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
|
@ -176,7 +176,7 @@ ExpandTuple MakeExpand(AstTreeStorage &storage, SymbolTable &symbol_table,
|
||||
EdgeAtom::Direction direction,
|
||||
const std::vector<storage::EdgeType> &edge_types,
|
||||
const std::string &node_identifier, bool existing_node,
|
||||
GraphView graph_view = GraphView::AS_IS) {
|
||||
GraphView graph_view) {
|
||||
auto edge = EDGE(edge_identifier, direction);
|
||||
auto edge_sym = symbol_table.CreateSymbol(edge_identifier, true);
|
||||
symbol_table[*edge->identifier_] = edge_sym;
|
||||
|
@ -295,8 +295,9 @@ TEST(QueryPlan, Delete) {
|
||||
// delete all remaining edges
|
||||
{
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::NEW);
|
||||
auto r_get = storage.Create<Identifier>("r");
|
||||
symbol_table[*r_get] = r_m.edge_sym_;
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
@ -348,8 +349,9 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
|
||||
// getter expressions for deletion
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
@ -471,8 +473,9 @@ TEST(QueryPlan, SetProperty) {
|
||||
|
||||
// scan (n)-[r]->(m)
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::OLD);
|
||||
|
||||
// set prop1 to 42 on n and r
|
||||
auto prop1 = dba.Property("prop1");
|
||||
@ -522,8 +525,9 @@ TEST(QueryPlan, SetProperties) {
|
||||
|
||||
// scan (n)-[r]->(m)
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::OLD);
|
||||
|
||||
auto op = update ? plan::SetProperties::Op::UPDATE
|
||||
: plan::SetProperties::Op::REPLACE;
|
||||
@ -625,8 +629,9 @@ TEST(QueryPlan, RemoveProperty) {
|
||||
|
||||
// scan (n)-[r]->(m)
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::OLD);
|
||||
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop1);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
@ -702,8 +707,9 @@ TEST(QueryPlan, NodeFilterSet) {
|
||||
// MATCH (n {prop: 42}) -[r]- (m)
|
||||
auto scan_all = MakeScanAll(storage, symbol_table, "n");
|
||||
scan_all.node_->properties_[prop] = LITERAL(42);
|
||||
auto expand = MakeExpand(storage, symbol_table, scan_all.op_, scan_all.sym_,
|
||||
"r", EdgeAtom::Direction::BOTH, {}, "m", false);
|
||||
auto expand =
|
||||
MakeExpand(storage, symbol_table, scan_all.op_, scan_all.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
auto *filter_expr =
|
||||
EQ(storage.Create<PropertyLookup>(scan_all.node_->identifier_, prop),
|
||||
LITERAL(42));
|
||||
@ -741,8 +747,9 @@ TEST(QueryPlan, FilterRemove) {
|
||||
// MATCH (n) -[r]- (m) WHERE n.prop < 43
|
||||
auto scan_all = MakeScanAll(storage, symbol_table, "n");
|
||||
scan_all.node_->properties_[prop] = LITERAL(42);
|
||||
auto expand = MakeExpand(storage, symbol_table, scan_all.op_, scan_all.sym_,
|
||||
"r", EdgeAtom::Direction::BOTH, {}, "m", false);
|
||||
auto expand =
|
||||
MakeExpand(storage, symbol_table, scan_all.op_, scan_all.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
auto filter_prop = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*filter_prop->expression_] = scan_all.sym_;
|
||||
auto filter =
|
||||
@ -803,8 +810,9 @@ TEST(QueryPlan, Merge) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
|
||||
// merge_match branch
|
||||
auto r_m = MakeExpand(storage, symbol_table, std::make_shared<Once>(), n.sym_,
|
||||
"r", EdgeAtom::Direction::BOTH, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, std::make_shared<Once>(), n.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
auto m_p = PROPERTY_LOOKUP("m", prop);
|
||||
symbol_table[*m_p->expression_] = r_m.node_sym_;
|
||||
auto m_set = std::make_shared<plan::SetProperty>(r_m.op_, m_p, LITERAL(1));
|
||||
|
@ -418,10 +418,10 @@ TEST_F(ExpandFixture, Expand) {
|
||||
return PullAll(produce, dba_, symbol_table);
|
||||
};
|
||||
|
||||
EXPECT_EQ(2, test_expand(EdgeAtom::Direction::OUT, GraphView::AS_IS));
|
||||
EXPECT_EQ(2, test_expand(EdgeAtom::Direction::IN, GraphView::AS_IS));
|
||||
EXPECT_EQ(4, test_expand(EdgeAtom::Direction::BOTH, GraphView::AS_IS));
|
||||
//
|
||||
EXPECT_EQ(2, test_expand(EdgeAtom::Direction::OUT, GraphView::OLD));
|
||||
EXPECT_EQ(2, test_expand(EdgeAtom::Direction::IN, GraphView::OLD));
|
||||
EXPECT_EQ(4, test_expand(EdgeAtom::Direction::BOTH, GraphView::OLD));
|
||||
|
||||
// test that expand works well for both old and new graph state
|
||||
v1.Reconstruct();
|
||||
v2.Reconstruct();
|
||||
@ -442,8 +442,9 @@ TEST_F(ExpandFixture, Expand) {
|
||||
|
||||
TEST_F(ExpandFixture, ExpandPath) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::OLD);
|
||||
Symbol path_sym = symbol_table.CreateSymbol("path", true);
|
||||
auto path = std::make_shared<ConstructNamedPath>(
|
||||
r_m.op_, path_sym,
|
||||
@ -540,7 +541,7 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
const std::vector<storage::EdgeType> &edge_types,
|
||||
std::experimental::optional<size_t> lower,
|
||||
std::experimental::optional<size_t> upper, Symbol edge_sym,
|
||||
const std::string &node_to, GraphView graph_view = GraphView::AS_IS,
|
||||
const std::string &node_to, GraphView graph_view,
|
||||
bool is_reverse = false) {
|
||||
auto n_from = MakeScanAll(storage, symbol_table, node_from, input_op);
|
||||
auto filter_op = std::make_shared<Filter>(
|
||||
@ -628,7 +629,7 @@ TEST_F(QueryPlanExpandVariable, OneVariableExpansion) {
|
||||
auto e = Edge("r", direction);
|
||||
return GetEdgeListSizes(
|
||||
AddMatch<ExpandVariable>(nullptr, "n", layer, direction, {}, lower,
|
||||
upper, e, "m", GraphView::AS_IS, reverse),
|
||||
upper, e, "m", GraphView::OLD, reverse),
|
||||
e);
|
||||
};
|
||||
|
||||
@ -691,18 +692,19 @@ TEST_F(QueryPlanExpandVariable, EdgeUniquenessSingleAndVariableExpansion) {
|
||||
if (single_expansion_before) {
|
||||
symbols.push_back(Edge("r0", direction));
|
||||
last_op = AddMatch<Expand>(last_op, "n0", layer, direction, {}, lower,
|
||||
upper, symbols.back(), "m0");
|
||||
upper, symbols.back(), "m0", GraphView::OLD);
|
||||
}
|
||||
|
||||
auto var_length_sym = Edge("r1", direction);
|
||||
symbols.push_back(var_length_sym);
|
||||
last_op = AddMatch<ExpandVariable>(last_op, "n1", layer, direction, {},
|
||||
lower, upper, var_length_sym, "m1");
|
||||
last_op =
|
||||
AddMatch<ExpandVariable>(last_op, "n1", layer, direction, {}, lower,
|
||||
upper, var_length_sym, "m1", GraphView::OLD);
|
||||
|
||||
if (!single_expansion_before) {
|
||||
symbols.push_back(Edge("r2", direction));
|
||||
last_op = AddMatch<Expand>(last_op, "n2", layer, direction, {}, lower,
|
||||
upper, symbols.back(), "m2");
|
||||
upper, symbols.back(), "m2", GraphView::OLD);
|
||||
}
|
||||
|
||||
if (add_uniqueness_check) {
|
||||
@ -731,11 +733,13 @@ TEST_F(QueryPlanExpandVariable, EdgeUniquenessTwoVariableExpansions) {
|
||||
std::experimental::optional<size_t> upper,
|
||||
bool add_uniqueness_check) {
|
||||
auto e1 = Edge("r1", direction);
|
||||
auto first = AddMatch<ExpandVariable>(nullptr, "n1", layer, direction, {},
|
||||
lower, upper, e1, "m1");
|
||||
auto first =
|
||||
AddMatch<ExpandVariable>(nullptr, "n1", layer, direction, {}, lower,
|
||||
upper, e1, "m1", GraphView::OLD);
|
||||
auto e2 = Edge("r2", direction);
|
||||
auto last_op = AddMatch<ExpandVariable>(first, "n2", layer, direction, {},
|
||||
lower, upper, e2, "m2");
|
||||
auto last_op =
|
||||
AddMatch<ExpandVariable>(first, "n2", layer, direction, {}, lower,
|
||||
upper, e2, "m2", GraphView::OLD);
|
||||
if (add_uniqueness_check) {
|
||||
last_op = std::make_shared<ExpandUniquenessFilter<EdgeAccessor>>(
|
||||
last_op, e2, std::vector<Symbol>{e1});
|
||||
@ -785,8 +789,9 @@ TEST_F(QueryPlanExpandVariable, GraphState) {
|
||||
|
||||
TEST_F(QueryPlanExpandVariable, NamedPath) {
|
||||
auto e = Edge("r", EdgeAtom::Direction::OUT);
|
||||
auto expand = AddMatch<ExpandVariable>(
|
||||
nullptr, "n", 0, EdgeAtom::Direction::OUT, {}, 2, 2, e, "m");
|
||||
auto expand =
|
||||
AddMatch<ExpandVariable>(nullptr, "n", 0, EdgeAtom::Direction::OUT, {}, 2,
|
||||
2, e, "m", GraphView::OLD);
|
||||
auto find_symbol = [this](const std::string &name) {
|
||||
for (const auto &pos_sym : symbol_table.table())
|
||||
if (pos_sym.second.name() == name) return pos_sym.second;
|
||||
@ -876,7 +881,7 @@ class QueryPlanExpandBreadthFirst : public testing::Test {
|
||||
// defines and performs a breadth-first expansion with the given params
|
||||
// returns a vector of pairs. each pair is (vector-of-edges, vertex)
|
||||
auto ExpandBF(EdgeAtom::Direction direction, int max_depth, Expression *where,
|
||||
GraphView graph_view = GraphView::AS_IS,
|
||||
GraphView graph_view,
|
||||
std::experimental::optional<int> node_id = 0,
|
||||
ScanAllTuple *existing_node_input = nullptr) {
|
||||
// scan the nodes optionally filtering on property value
|
||||
@ -934,7 +939,8 @@ class QueryPlanExpandBreadthFirst : public testing::Test {
|
||||
#define EXPECT_EITHER(value, a, b) EXPECT_TRUE(value == a || value == b)
|
||||
|
||||
TEST_F(QueryPlanExpandBreadthFirst, Basic) {
|
||||
auto results = ExpandBF(EdgeAtom::Direction::BOTH, 1000, LITERAL(true));
|
||||
auto results =
|
||||
ExpandBF(EdgeAtom::Direction::BOTH, 1000, LITERAL(true), GraphView::OLD);
|
||||
|
||||
ASSERT_EQ(results.size(), 3);
|
||||
|
||||
@ -955,7 +961,8 @@ TEST_F(QueryPlanExpandBreadthFirst, Basic) {
|
||||
|
||||
TEST_F(QueryPlanExpandBreadthFirst, EdgeDirection) {
|
||||
{
|
||||
auto results = ExpandBF(EdgeAtom::Direction::IN, 1000, LITERAL(true));
|
||||
auto results =
|
||||
ExpandBF(EdgeAtom::Direction::IN, 1000, LITERAL(true), GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 3);
|
||||
EXPECT_EQ(GetProp(results[0].second), 2);
|
||||
EXPECT_EQ(GetProp(results[1].second), 3);
|
||||
@ -964,7 +971,8 @@ TEST_F(QueryPlanExpandBreadthFirst, EdgeDirection) {
|
||||
// assume edges are OK because vertices are (tested before)
|
||||
}
|
||||
{
|
||||
auto results = ExpandBF(EdgeAtom::Direction::OUT, 1000, LITERAL(true));
|
||||
auto results =
|
||||
ExpandBF(EdgeAtom::Direction::OUT, 1000, LITERAL(true), GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 3);
|
||||
EXPECT_EQ(GetProp(results[0].second), 1);
|
||||
EXPECT_EQ(GetProp(results[1].second), 3);
|
||||
@ -976,15 +984,15 @@ TEST_F(QueryPlanExpandBreadthFirst, EdgeDirection) {
|
||||
|
||||
TEST_F(QueryPlanExpandBreadthFirst, Where) {
|
||||
{
|
||||
auto results =
|
||||
ExpandBF(EdgeAtom::Direction::BOTH, 1000, PropNe(inner_node, 2));
|
||||
auto results = ExpandBF(EdgeAtom::Direction::BOTH, 1000,
|
||||
PropNe(inner_node, 2), GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 2);
|
||||
EXPECT_EQ(GetProp(results[0].second), 1);
|
||||
EXPECT_EQ(GetProp(results[1].second), 3);
|
||||
}
|
||||
{
|
||||
auto results =
|
||||
ExpandBF(EdgeAtom::Direction::BOTH, 1000, PropNe(inner_edge, 20));
|
||||
auto results = ExpandBF(EdgeAtom::Direction::BOTH, 1000,
|
||||
PropNe(inner_edge, 20), GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 3);
|
||||
EXPECT_EQ(GetProp(results[0].second), 1);
|
||||
EXPECT_EITHER(GetProp(results[1].second), 3, 2);
|
||||
@ -1014,7 +1022,7 @@ TEST_F(QueryPlanExpandBreadthFirst, GraphState) {
|
||||
|
||||
TEST_F(QueryPlanExpandBreadthFirst, MultipleInputs) {
|
||||
auto results = ExpandBF(EdgeAtom::Direction::OUT, 1000, LITERAL(true),
|
||||
GraphView::AS_IS, std::experimental::nullopt);
|
||||
GraphView::OLD, std::experimental::nullopt);
|
||||
// expect that each vertex has been returned 3 times
|
||||
EXPECT_EQ(results.size(), 12);
|
||||
std::vector<int> found(4, 0);
|
||||
@ -1037,7 +1045,7 @@ TEST_F(QueryPlanExpandBreadthFirst, ExistingNode) {
|
||||
}
|
||||
|
||||
return ExpandBF(EdgeAtom::Direction::OUT, 1000, LITERAL(true),
|
||||
GraphView::AS_IS, std::experimental::nullopt, &n0);
|
||||
GraphView::OLD, std::experimental::nullopt, &n0);
|
||||
};
|
||||
|
||||
EXPECT_EQ(ExpandPreceeding(std::experimental::nullopt).size(), 12);
|
||||
@ -1112,8 +1120,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
|
||||
// returns a vector of pairs. each pair is (vector-of-edges, vertex)
|
||||
auto ExpandWShortest(EdgeAtom::Direction direction,
|
||||
std::experimental::optional<int> max_depth,
|
||||
Expression *where,
|
||||
GraphView graph_view = GraphView::AS_IS,
|
||||
Expression *where, GraphView graph_view,
|
||||
std::experimental::optional<int> node_id = 0,
|
||||
ScanAllTuple *existing_node_input = nullptr) {
|
||||
// scan the nodes optionally filtering on property value
|
||||
@ -1191,8 +1198,8 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
|
||||
// 3 3 3
|
||||
|
||||
TEST_F(QueryPlanExpandWeightedShortestPath, Basic) {
|
||||
auto results =
|
||||
ExpandWShortest(EdgeAtom::Direction::BOTH, 1000, LITERAL(true));
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::BOTH, 1000, LITERAL(true),
|
||||
GraphView::OLD);
|
||||
|
||||
ASSERT_EQ(results.size(), 4);
|
||||
|
||||
@ -1225,8 +1232,8 @@ TEST_F(QueryPlanExpandWeightedShortestPath, Basic) {
|
||||
|
||||
TEST_F(QueryPlanExpandWeightedShortestPath, EdgeDirection) {
|
||||
{
|
||||
auto results =
|
||||
ExpandWShortest(EdgeAtom::Direction::OUT, 1000, LITERAL(true));
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::OUT, 1000,
|
||||
LITERAL(true), GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 4);
|
||||
EXPECT_EQ(GetProp(results[0].vertex), 2);
|
||||
EXPECT_EQ(results[0].total_weight, 3);
|
||||
@ -1238,8 +1245,8 @@ TEST_F(QueryPlanExpandWeightedShortestPath, EdgeDirection) {
|
||||
EXPECT_EQ(results[3].total_weight, 9);
|
||||
}
|
||||
{
|
||||
auto results =
|
||||
ExpandWShortest(EdgeAtom::Direction::IN, 1000, LITERAL(true));
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::IN, 1000, LITERAL(true),
|
||||
GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 4);
|
||||
EXPECT_EQ(GetProp(results[0].vertex), 4);
|
||||
EXPECT_EQ(results[0].total_weight, 12);
|
||||
@ -1255,7 +1262,7 @@ TEST_F(QueryPlanExpandWeightedShortestPath, EdgeDirection) {
|
||||
TEST_F(QueryPlanExpandWeightedShortestPath, Where) {
|
||||
{
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::BOTH, 1000,
|
||||
PropNe(filter_node, 2));
|
||||
PropNe(filter_node, 2), GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 3);
|
||||
EXPECT_EQ(GetProp(results[0].vertex), 1);
|
||||
EXPECT_EQ(results[0].total_weight, 5);
|
||||
@ -1266,7 +1273,7 @@ TEST_F(QueryPlanExpandWeightedShortestPath, Where) {
|
||||
}
|
||||
{
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::BOTH, 1000,
|
||||
PropNe(filter_node, 1));
|
||||
PropNe(filter_node, 1), GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 3);
|
||||
EXPECT_EQ(GetProp(results[0].vertex), 2);
|
||||
EXPECT_EQ(results[0].total_weight, 3);
|
||||
@ -1299,23 +1306,23 @@ TEST_F(QueryPlanExpandWeightedShortestPath, GraphState) {
|
||||
}
|
||||
|
||||
TEST_F(QueryPlanExpandWeightedShortestPath, ExistingNode) {
|
||||
auto ExpandPreceeding = [this](
|
||||
std::experimental::optional<int> preceeding_node_id) {
|
||||
// scan the nodes optionally filtering on property value
|
||||
auto n0 = MakeScanAll(storage, symbol_table, "n0");
|
||||
if (preceeding_node_id) {
|
||||
auto filter = std::make_shared<Filter>(
|
||||
n0.op_, EQ(PROPERTY_LOOKUP(n0.node_->identifier_, prop),
|
||||
LITERAL(*preceeding_node_id)));
|
||||
// inject the filter op into the ScanAllTuple. that way the filter op
|
||||
// can be passed into the ExpandWShortest function without too much
|
||||
// refactor
|
||||
n0.op_ = filter;
|
||||
}
|
||||
auto ExpandPreceeding =
|
||||
[this](std::experimental::optional<int> preceeding_node_id) {
|
||||
// scan the nodes optionally filtering on property value
|
||||
auto n0 = MakeScanAll(storage, symbol_table, "n0");
|
||||
if (preceeding_node_id) {
|
||||
auto filter = std::make_shared<Filter>(
|
||||
n0.op_, EQ(PROPERTY_LOOKUP(n0.node_->identifier_, prop),
|
||||
LITERAL(*preceeding_node_id)));
|
||||
// inject the filter op into the ScanAllTuple. that way the filter op
|
||||
// can be passed into the ExpandWShortest function without too much
|
||||
// refactor
|
||||
n0.op_ = filter;
|
||||
}
|
||||
|
||||
return ExpandWShortest(EdgeAtom::Direction::OUT, 1000, LITERAL(true),
|
||||
GraphView::AS_IS, std::experimental::nullopt, &n0);
|
||||
};
|
||||
return ExpandWShortest(EdgeAtom::Direction::OUT, 1000, LITERAL(true),
|
||||
GraphView::OLD, std::experimental::nullopt, &n0);
|
||||
};
|
||||
|
||||
EXPECT_EQ(ExpandPreceeding(std::experimental::nullopt).size(), 20);
|
||||
{
|
||||
@ -1327,8 +1334,9 @@ TEST_F(QueryPlanExpandWeightedShortestPath, ExistingNode) {
|
||||
|
||||
TEST_F(QueryPlanExpandWeightedShortestPath, UpperBound) {
|
||||
{
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::BOTH,
|
||||
std::experimental::nullopt, LITERAL(true));
|
||||
auto results =
|
||||
ExpandWShortest(EdgeAtom::Direction::BOTH, std::experimental::nullopt,
|
||||
LITERAL(true), GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 4);
|
||||
EXPECT_EQ(GetProp(results[0].vertex), 2);
|
||||
EXPECT_EQ(results[0].total_weight, 3);
|
||||
@ -1361,7 +1369,8 @@ TEST_F(QueryPlanExpandWeightedShortestPath, UpperBound) {
|
||||
EXPECT_EQ(results[4].total_weight, 12);
|
||||
}
|
||||
{
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::BOTH, 2, LITERAL(true));
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::BOTH, 2, LITERAL(true),
|
||||
GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 4);
|
||||
EXPECT_EQ(GetProp(results[0].vertex), 2);
|
||||
EXPECT_EQ(results[0].total_weight, 3);
|
||||
@ -1373,7 +1382,8 @@ TEST_F(QueryPlanExpandWeightedShortestPath, UpperBound) {
|
||||
EXPECT_EQ(results[3].total_weight, 10);
|
||||
}
|
||||
{
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::BOTH, 1, LITERAL(true));
|
||||
auto results = ExpandWShortest(EdgeAtom::Direction::BOTH, 1, LITERAL(true),
|
||||
GraphView::OLD);
|
||||
ASSERT_EQ(results.size(), 3);
|
||||
EXPECT_EQ(GetProp(results[0].vertex), 2);
|
||||
EXPECT_EQ(results[0].total_weight, 3);
|
||||
@ -1433,8 +1443,9 @@ TEST(QueryPlan, ExpandOptional) {
|
||||
|
||||
// MATCH (n) OPTIONAL MATCH (n)-[r]->(m)
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, nullptr, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, nullptr, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::OLD);
|
||||
auto optional = std::make_shared<plan::Optional>(
|
||||
n.op_, r_m.op_, std::vector<Symbol>{r_m.edge_sym_, r_m.node_sym_});
|
||||
|
||||
@ -1508,8 +1519,9 @@ TEST(QueryPlan, OptionalMatchEmptyDBExpandFromNode) {
|
||||
symbol_table[*n_ne] = with_n_sym;
|
||||
auto with = MakeProduce(optional, n_ne);
|
||||
// MATCH (n) -[r]-> (m)
|
||||
auto r_m = MakeExpand(storage, symbol_table, with, with_n_sym, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false);
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, with, with_n_sym, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::OLD);
|
||||
// RETURN m
|
||||
auto m_ne = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*m_ne->expression_] = r_m.node_sym_;
|
||||
@ -1558,7 +1570,7 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
|
||||
symbol_table[*node->identifier_] = with_n_sym;
|
||||
auto expand = std::make_shared<plan::Expand>(
|
||||
with_n_sym, edge_sym, edge_direction, std::vector<storage::EdgeType>{},
|
||||
m.op_, m.sym_, true);
|
||||
m.op_, m.sym_, true, GraphView::OLD);
|
||||
// RETURN m
|
||||
auto m_ne = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*m_ne->expression_] = m.sym_;
|
||||
@ -1587,11 +1599,13 @@ TEST(QueryPlan, ExpandExistingNode) {
|
||||
auto test_existing = [&](bool with_existing, int expected_result_count) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_n = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "n", with_existing);
|
||||
EdgeAtom::Direction::OUT, {}, "n", with_existing,
|
||||
GraphView::OLD);
|
||||
if (with_existing)
|
||||
r_n.op_ = std::make_shared<Expand>(
|
||||
n.sym_, r_n.edge_sym_, r_n.edge_->direction_,
|
||||
std::vector<storage::EdgeType>{}, n.op_, n.sym_, with_existing);
|
||||
r_n.op_ =
|
||||
std::make_shared<Expand>(n.sym_, r_n.edge_sym_, r_n.edge_->direction_,
|
||||
std::vector<storage::EdgeType>{}, n.op_,
|
||||
n.sym_, with_existing, GraphView::OLD);
|
||||
|
||||
// make a named expression and a produce
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
@ -1622,8 +1636,9 @@ TEST(QueryPlan, ExpandBothCycleEdgeCase) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_ = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "_", false);
|
||||
auto r_ =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "_", false, GraphView::OLD);
|
||||
EXPECT_EQ(1, PullAll(r_.op_, dba, symbol_table));
|
||||
}
|
||||
|
||||
@ -1670,7 +1685,8 @@ TEST(QueryPlan, EdgeFilter) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
const auto &edge_type = edge_types[0];
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {edge_type}, "m", false);
|
||||
EdgeAtom::Direction::OUT, {edge_type}, "m", false,
|
||||
GraphView::OLD);
|
||||
r_m.edge_->edge_types_.push_back(edge_type);
|
||||
r_m.edge_->properties_[prop] = LITERAL(42);
|
||||
auto *filter_expr =
|
||||
@ -1715,7 +1731,8 @@ TEST(QueryPlan, EdgeFilterMultipleTypes) {
|
||||
// make a scan all
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {type_1, type_2}, "m", false);
|
||||
EdgeAtom::Direction::OUT, {type_1, type_2}, "m", false,
|
||||
GraphView::OLD);
|
||||
|
||||
// make a named expression and a produce
|
||||
auto output = NEXPR("m", IDENT("m"));
|
||||
@ -1776,14 +1793,16 @@ TEST(QueryPlan, ExpandUniquenessFilter) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n1 = MakeScanAll(storage, symbol_table, "n1");
|
||||
auto r1_n2 = MakeExpand(storage, symbol_table, n1.op_, n1.sym_, "r1",
|
||||
EdgeAtom::Direction::OUT, {}, "n2", false);
|
||||
auto r1_n2 =
|
||||
MakeExpand(storage, symbol_table, n1.op_, n1.sym_, "r1",
|
||||
EdgeAtom::Direction::OUT, {}, "n2", false, GraphView::OLD);
|
||||
std::shared_ptr<LogicalOperator> last_op = r1_n2.op_;
|
||||
if (vertex_uniqueness)
|
||||
last_op = std::make_shared<ExpandUniquenessFilter<VertexAccessor>>(
|
||||
last_op, r1_n2.node_sym_, std::vector<Symbol>{n1.sym_});
|
||||
auto r2_n3 = MakeExpand(storage, symbol_table, last_op, r1_n2.node_sym_,
|
||||
"r2", EdgeAtom::Direction::OUT, {}, "n3", false);
|
||||
auto r2_n3 =
|
||||
MakeExpand(storage, symbol_table, last_op, r1_n2.node_sym_, "r2",
|
||||
EdgeAtom::Direction::OUT, {}, "n3", false, GraphView::OLD);
|
||||
last_op = r2_n3.op_;
|
||||
if (edge_uniqueness)
|
||||
last_op = std::make_shared<ExpandUniquenessFilter<EdgeAccessor>>(
|
||||
|
Loading…
Reference in New Issue
Block a user