Skip to content

Commit

Permalink
fix SubGraph edge type in filter does not exist in tranversed edge ty…
Browse files Browse the repository at this point in the history
…pe (#4941)

* fix SubGraph edge type in filter does not exist in tranversed edge type

* fix tck

* fix tck

* fix tck

* minor
  • Loading branch information
codesigner authored Nov 29, 2022
1 parent aa62416 commit 298c7d9
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/graph/context/ast/QueryAstContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ struct SubgraphContext final : public AstContext {
Expression* tagFilter{nullptr};
Expression* edgeFilter{nullptr};
std::vector<std::string> colNames;
std::unordered_set<std::string> edgeNames;
std::unordered_set<EdgeType> edgeTypes;
std::unordered_set<EdgeType> biDirectEdgeTypes;
std::vector<Value::Type> colType;
Expand Down
40 changes: 31 additions & 9 deletions src/graph/validator/GetSubgraphValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Status GetSubgraphValidator::validateImpl() {
// Validate in-bound edge types
Status GetSubgraphValidator::validateInBound(InBoundClause* in) {
auto& edgeTypes = subgraphCtx_->edgeTypes;
auto& edgeNames = subgraphCtx_->edgeNames;
if (in != nullptr) {
auto space = vctx_->whichSpace();
auto edges = in->edges();
Expand All @@ -42,8 +43,10 @@ Status GetSubgraphValidator::validateInBound(InBoundClause* in) {
return Status::SemanticError("Get Subgraph not support rename edge name.");
}

auto et = qctx_->schemaMng()->toEdgeType(space.id, *e->edge());
std::string edgeName = *e->edge();
auto et = qctx_->schemaMng()->toEdgeType(space.id, edgeName);
NG_RETURN_IF_ERROR(et);
edgeNames.emplace(edgeName);

auto v = -et.value();
edgeTypes.emplace(v);
Expand All @@ -56,6 +59,7 @@ Status GetSubgraphValidator::validateInBound(InBoundClause* in) {
// Validate out-bound edge types
Status GetSubgraphValidator::validateOutBound(OutBoundClause* out) {
auto& edgeTypes = subgraphCtx_->edgeTypes;
auto& edgeNames = subgraphCtx_->edgeNames;
if (out != nullptr) {
auto space = vctx_->whichSpace();
auto edges = out->edges();
Expand All @@ -64,10 +68,10 @@ Status GetSubgraphValidator::validateOutBound(OutBoundClause* out) {
if (e->alias() != nullptr) {
return Status::SemanticError("Get Subgraph not support rename edge name.");
}

auto et = qctx_->schemaMng()->toEdgeType(space.id, *e->edge());
std::string edgeName = *e->edge();
auto et = qctx_->schemaMng()->toEdgeType(space.id, edgeName);
NG_RETURN_IF_ERROR(et);

edgeNames.emplace(edgeName);
edgeTypes.emplace(et.value());
}
}
Expand All @@ -79,19 +83,20 @@ Status GetSubgraphValidator::validateOutBound(OutBoundClause* out) {
Status GetSubgraphValidator::validateBothInOutBound(BothInOutClause* out) {
auto& edgeTypes = subgraphCtx_->edgeTypes;
auto& biEdgeTypes = subgraphCtx_->biDirectEdgeTypes;
auto& edgeNames = subgraphCtx_->edgeNames;
if (out != nullptr) {
auto space = vctx_->whichSpace();
auto& space = vctx_->whichSpace();
auto edges = out->edges();
edgeTypes.reserve(edgeTypes.size() + edges.size() * 2);
biEdgeTypes.reserve(edges.size() * 2);
for (auto* e : out->edges()) {
if (e->alias() != nullptr) {
return Status::SemanticError("Get Subgraph not support rename edge name.");
}

auto et = qctx_->schemaMng()->toEdgeType(space.id, *e->edge());
std::string edgeName = *e->edge();
auto et = qctx_->schemaMng()->toEdgeType(space.id, edgeName);
NG_RETURN_IF_ERROR(et);

edgeNames.emplace(edgeName);
auto v = et.value();
edgeTypes.emplace(v);
edgeTypes.emplace(-v);
Expand Down Expand Up @@ -146,12 +151,29 @@ Status GetSubgraphValidator::validateWhere(WhereClause* where) {

NG_RETURN_IF_ERROR(deduceProps(filter, subgraphCtx_->exprProps));

// check EdgeFilter's edge type is in the edge type list
// e.g. "like" is not in the edge list ["serve"]
// GET SUBGRAPH FROM 'xxx' both serve WHERE like.likeness < 90 YIELD vertices as v, edges as e
if (!subgraphCtx_->edgeNames.empty()) {
for (auto edgeProp : subgraphCtx_->exprProps.edgeProps()) {
auto filterEdgeName = qctx_->schemaMng()->toEdgeName(vctx_->whichSpace().id, edgeProp.first);
NG_RETURN_IF_ERROR(filterEdgeName);
if (subgraphCtx_->edgeNames.find(filterEdgeName.value()) == subgraphCtx_->edgeNames.end()) {
return Status::SemanticError(
fmt::format("Edge type \"{}\" in filter \"{}\" is not in the edge types [{}]",
filterEdgeName.value(),
filter->toString(),
folly::join(",", subgraphCtx_->edgeNames)));
}
}
}

auto condition = filter->clone();
if (ExpressionUtils::findAny(expr, {Expression::Kind::kDstProperty})) {
auto visitor = ExtractFilterExprVisitor::makePushGetVertices(qctx_->objPool());
filter->accept(&visitor);
if (!visitor.ok()) {
return Status::SemanticError("filter error");
return Status::SemanticError("Push target vertices filter error: " + expr->toString());
}
subgraphCtx_->edgeFilter = visitor.remainedExpr();
auto tagFilter = visitor.extractedExpr() ? visitor.extractedExpr() : filter;
Expand Down
27 changes: 27 additions & 0 deletions tests/tck/features/subgraph/subgraph.feature
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,33 @@ Feature: subgraph
| <[vertex4]> | <[edge4]> |
| <[vertex5]> | [] |

Scenario: Filter on edge type
When executing query:
"""
GET SUBGRAPH FROM 'Tim Duncan' BOTH serve WHERE like.likeness < 90 YIELD vertices as v, edges as e
"""
Then a SemanticError should be raised at runtime: Edge type "like" in filter "(like.likeness<90)" is not in the edge types [serve]
When executing query:
"""
GET SUBGRAPH FROM 'Tim Duncan' BOTH serve,teammate WHERE like.likeness >= 90 YIELD vertices as v, edges as e
"""
Then a SemanticError should be raised at runtime: Edge type "like" in filter "(like.likeness>=90)" is not in the edge types [teammate,serve]
When executing query:
"""
GET SUBGRAPH FROM 'Tim Duncan' BOTH serve WHERE serve.start_year < 1997 YIELD vertices as v, edges as e
"""
Then the result should be, in any order, with relax comparison:
| v | e |
| [("Tim Duncan" :player{} :bachelor{})] | [] |
When executing query:
"""
GET SUBGRAPH FROM 'Tim Duncan' BOTH serve WHERE serve.start_year >= 1997 YIELD vertices as v, edges as e
"""
Then the result should be, in any order, with relax comparison:
| v | e |
| [("Tim Duncan" :player{} :bachelor{})] | [[:serve "Tim Duncan"->"Spurs" @0 {start_year: 1997}]] |
| [("Spurs" :team{})] | [] |

Scenario: Get subgraph in a space which doesn't have edge schema
Given an empty graph
And create a space with following options:
Expand Down

0 comments on commit 298c7d9

Please sign in to comment.