Skip to content

Commit

Permalink
fix optional match
Browse files Browse the repository at this point in the history
  • Loading branch information
czpmango committed Sep 22, 2022
1 parent f92c24c commit 7a11462
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/graph/planner/match/MatchPlanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "graph/planner/plan/Algo.h"
#include "graph/planner/plan/Logic.h"
#include "graph/planner/plan/Query.h"
#include "graph/util/ExpressionUtils.h"

namespace nebula {
namespace graph {
Expand Down Expand Up @@ -76,8 +77,28 @@ Status MatchPlanner::connectMatchPlan(SubPlan& queryPlan, MatchClauseContext* ma
if (!intersectedAliases.empty()) {
if (matchCtx->isOptional) {
// connect LeftJoin match filter
if (matchCtx->where != nullptr) {
matchCtx->where->inputColNames = matchPlan.root->colNames();
auto& whereCtx = matchCtx->where;
if (whereCtx.get() != nullptr) {
auto exprs =
ExpressionUtils::collectAll(whereCtx->filter, {Expression::Kind::kLabelTagProperty});

// Check if all aliases in where clause are generated by the current match statement pattern
std::vector<std::string> aliases;
for (const auto* expr : exprs) {
DCHECK_EQ(expr->kind(), Expression::Kind::kLabelTagProperty);
auto* labelExpr = static_cast<const LabelTagPropertyExpression*>(expr)->label();
DCHECK_EQ(labelExpr->kind(), Expression::Kind::kVarProperty);
aliases.emplace_back(static_cast<const PropertyExpression*>(labelExpr)->prop());
}
auto aliasesGenerated = matchCtx->aliasesGenerated;
if (!std::all_of(aliases.begin(), aliases.end(), [&aliasesGenerated](std::string& alias) {
return aliasesGenerated.find(alias) != aliasesGenerated.end();
})) {
return Status::SemanticError(
"The where clause of optional match statement that reference variables defined by "
"other statements is not supported yet.");
}
whereCtx->inputColNames = matchPlan.root->colNames();
auto wherePlanStatus =
std::make_unique<WhereClausePlanner>()->transform(matchCtx->where.get());
NG_RETURN_IF_ERROR(wherePlanStatus);
Expand All @@ -102,7 +123,7 @@ Status MatchPlanner::genQueryPartPlan(QueryContext* qctx,
const QueryPart& queryPart) {
// generate plan for matchs
for (auto& match : queryPart.matchs) {
connectMatchPlan(queryPlan, match.get());
NG_RETURN_IF_ERROR(connectMatchPlan(queryPlan, match.get()));
// connect match filter
if (match->where != nullptr && !match->isOptional) {
match->where->inputColNames = queryPlan.root->colNames();
Expand Down
7 changes: 7 additions & 0 deletions tests/tck/features/match/MultiLineMultiQueryParts.feature
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,10 @@ Feature: Multi Line Multi Query Parts
RETURN m
"""
Then a SemanticError should be raised at runtime: Alias used but not defined: `m'
When executing query:
"""
MATCH (m)-[]-(n) WHERE id(m)=="Tim Duncan"
OPTIONAL MATCH (n)-->(v) WHERE v.player.age < m.player.age
RETURN n,v
"""
Then a SemanticError should be raised at runtime: The where clause of optional match statement that reference variables defined by other statements is not supported yet.

0 comments on commit 7a11462

Please sign in to comment.