From 967a8c9e022ccbec39191ae8b4f154ce21258910 Mon Sep 17 00:00:00 2001 From: jimingquan Date: Thu, 29 Dec 2022 10:17:40 +0800 Subject: [PATCH] add tagFilter for traverse (#5137) * add tagFilter for traverse * add test case Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com> --- src/graph/executor/query/TraverseExecutor.cpp | 2 +- src/graph/planner/match/MatchPathPlanner.cpp | 2 + src/graph/planner/plan/Query.cpp | 4 ++ src/graph/planner/plan/Query.h | 9 +++++ tests/tck/features/match/Base.IntVid.feature | 40 +++++++++++++++++++ tests/tck/features/match/Base.feature | 40 +++++++++++++++++++ 6 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/graph/executor/query/TraverseExecutor.cpp b/src/graph/executor/query/TraverseExecutor.cpp index 07f27af085f..72540c025b0 100644 --- a/src/graph/executor/query/TraverseExecutor.cpp +++ b/src/graph/executor/query/TraverseExecutor.cpp @@ -101,7 +101,7 @@ folly::Future TraverseExecutor::getNeighbors() { finalStep ? traverse_->orderBy() : std::vector(), finalStep ? traverse_->limit(qctx()) : -1, selectFilter(), - nullptr) + currentStep_ == 1 ? traverse_->tagFilter() : nullptr) .via(runner()) .thenValue([this, getNbrTime](StorageRpcResponse&& resp) mutable { vids_.clear(); diff --git a/src/graph/planner/match/MatchPathPlanner.cpp b/src/graph/planner/match/MatchPathPlanner.cpp index 44fb4ecbc11..129334967d9 100644 --- a/src/graph/planner/match/MatchPathPlanner.cpp +++ b/src/graph/planner/match/MatchPathPlanner.cpp @@ -209,6 +209,7 @@ Status MatchPathPlanner::leftExpandFromNode(size_t startIndex, SubPlan& subplan) traverse->setVertexProps(std::move(vertexProps).value()); traverse->setEdgeProps(SchemaUtil::getEdgeProps(edge, reversely, qctx, spaceId)); traverse->setVertexFilter(genVertexFilter(node)); + traverse->setTagFilter(genVertexFilter(node)); traverse->setEdgeFilter(genEdgeFilter(edge)); traverse->setEdgeDirection(edge.direction); traverse->setStepRange(edge.range); @@ -275,6 +276,7 @@ Status MatchPathPlanner::rightExpandFromNode(size_t startIndex, SubPlan& subplan traverse->setVertexProps(std::move(vertexProps).value()); traverse->setEdgeProps(SchemaUtil::getEdgeProps(edge, reversely, qctx, spaceId)); traverse->setVertexFilter(genVertexFilter(node)); + traverse->setTagFilter(genVertexFilter(node)); traverse->setEdgeFilter(genEdgeFilter(edge)); traverse->setEdgeDirection(edge.direction); traverse->setStepRange(edge.range); diff --git a/src/graph/planner/plan/Query.cpp b/src/graph/planner/plan/Query.cpp index 1c9fb8c028d..ad855bb112d 100644 --- a/src/graph/planner/plan/Query.cpp +++ b/src/graph/planner/plan/Query.cpp @@ -783,6 +783,9 @@ void Traverse::cloneMembers(const Traverse& g) { if (g.firstStepFilter_ != nullptr) { setFirstStepFilter(g.firstStepFilter_->clone()); } + if (g.tagFilter_ != nullptr) { + setTagFilter(g.tagFilter_->clone()); + } } std::unique_ptr Traverse::explain() const { @@ -794,6 +797,7 @@ std::unique_ptr Traverse::explain() const { addDescription("first step filter", firstStepFilter_ != nullptr ? firstStepFilter_->toString() : "", desc.get()); + addDescription("tag filter", tagFilter_ != nullptr ? tagFilter_->toString() : "", desc.get()); return desc; } diff --git a/src/graph/planner/plan/Query.h b/src/graph/planner/plan/Query.h index 1290f5e4740..ded9e30e2c4 100644 --- a/src/graph/planner/plan/Query.h +++ b/src/graph/planner/plan/Query.h @@ -1641,6 +1641,14 @@ class Traverse final : public GetNeighbors { firstStepFilter_ = filter; } + Expression* tagFilter() const { + return tagFilter_; + } + + void setTagFilter(Expression* tagFilter) { + tagFilter_ = tagFilter; + } + private: friend ObjectPool; Traverse(QueryContext* qctx, PlanNode* input, GraphSpaceID space) @@ -1657,6 +1665,7 @@ class Traverse final : public GetNeighbors { bool trackPrevPath_{true}; // Push down filter in first step Expression* firstStepFilter_{nullptr}; + Expression* tagFilter_{nullptr}; }; // Append vertices to a path. diff --git a/tests/tck/features/match/Base.IntVid.feature b/tests/tck/features/match/Base.IntVid.feature index 20a43766a8f..098a3ff22c5 100644 --- a/tests/tck/features/match/Base.IntVid.feature +++ b/tests/tck/features/match/Base.IntVid.feature @@ -593,3 +593,43 @@ Feature: Basic match Then the result should be, in any order: | v | | ("Boris Diaw" :player{age: 36, name: "Boris Diaw"}) | + + Scenario: match with tag filter + When executing query: + """ + MATCH (a:team)-[e*0..1]-(b) where id(a) == hash('Tim Duncan') return b + """ + Then the result should be, in any order, with relax comparison: + | b | + When executing query: + """ + MATCH (a:team)-[e*0..0]-(b) where id(a) in [hash('Tim Duncan'), hash('Spurs')] return b + """ + Then the result should be, in any order, with relax comparison: + | b | + | ('Spurs') | + When executing query: + """ + MATCH (a:team)-[e*0..1]-(b) where id(a) in [hash('Tim Duncan'), hash('Spurs')] return b + """ + Then the result should be, in any order, with relax comparison: + | b | + | ("Spurs") | + | ("Aron Baynes") | + | ("Boris Diaw") | + | ("Cory Joseph") | + | ("Danny Green") | + | ("David West") | + | ("Dejounte Murray") | + | ("Jonathon Simmons") | + | ("Kyle Anderson") | + | ("LaMarcus Aldridge") | + | ("Manu Ginobili") | + | ("Marco Belinelli") | + | ("Paul Gasol") | + | ("Rudy Gay") | + | ("Tiago Splitter") | + | ("Tim Duncan") | + | ("Tony Parker") | + | ("Tracy McGrady") | + | ("Marco Belinelli") | diff --git a/tests/tck/features/match/Base.feature b/tests/tck/features/match/Base.feature index 5f0ef7d3906..6b0c1793c03 100644 --- a/tests/tck/features/match/Base.feature +++ b/tests/tck/features/match/Base.feature @@ -970,3 +970,43 @@ Feature: Basic match MATCH (v{name: "Tim Duncan"}) return v """ Then a SemanticError should be raised at runtime: `name:"Tim Duncan"': No tag found for property. + + Scenario: match with tag filter + When executing query: + """ + MATCH (a:team)-[e*0..1]-(b) where id(a) == 'Tim Duncan' return b + """ + Then the result should be, in any order, with relax comparison: + | b | + When executing query: + """ + MATCH (a:team)-[e*0..0]-(b) where id(a) in ['Tim Duncan', 'Spurs'] return b + """ + Then the result should be, in any order, with relax comparison: + | b | + | ('Spurs') | + When executing query: + """ + MATCH (a:team)-[e*0..1]-(b) where id(a) in ['Tim Duncan', 'Spurs'] return b + """ + Then the result should be, in any order, with relax comparison: + | b | + | ("Spurs") | + | ("Aron Baynes") | + | ("Boris Diaw") | + | ("Cory Joseph") | + | ("Danny Green") | + | ("David West") | + | ("Dejounte Murray") | + | ("Jonathon Simmons") | + | ("Kyle Anderson") | + | ("LaMarcus Aldridge") | + | ("Manu Ginobili") | + | ("Marco Belinelli") | + | ("Paul Gasol") | + | ("Rudy Gay") | + | ("Tiago Splitter") | + | ("Tim Duncan") | + | ("Tony Parker") | + | ("Tracy McGrady") | + | ("Marco Belinelli") |