diff --git a/src/graph/optimizer/rule/PushEFilterDownRule.cpp b/src/graph/optimizer/rule/PushEFilterDownRule.cpp index b49ccfb5d1d..1d212e7102e 100644 --- a/src/graph/optimizer/rule/PushEFilterDownRule.cpp +++ b/src/graph/optimizer/rule/PushEFilterDownRule.cpp @@ -53,8 +53,12 @@ StatusOr PushEFilterDownRule::transform( auto pool = qctx->objPool(); auto eFilter = traverse->eFilter()->clone(); - eFilter = rewriteStarEdge( - eFilter, traverse->space(), *DCHECK_NOTNULL(traverse->edgeProps()), qctx->schemaMng(), pool); + eFilter = rewriteStarEdge(eFilter, + traverse->space(), + *DCHECK_NOTNULL(traverse->edgeProps()), + qctx->schemaMng(), + traverse->edgeDirection() == storage::cpp2::EdgeDirection::BOTH, + pool); if (eFilter == nullptr) { return TransformResult::noTransform(); } @@ -93,6 +97,7 @@ std::string PushEFilterDownRule::toString() const { GraphSpaceID spaceId, const std::vector &edges, meta::SchemaManager *schemaMng, + bool isBothDirection, ObjectPool *pool) { graph::RewriteVisitor::Matcher matcher = [](const Expression *exp) -> bool { switch (exp->kind()) { @@ -113,7 +118,7 @@ std::string PushEFilterDownRule::toString() const { } }; graph::RewriteVisitor::Rewriter rewriter = - [spaceId, &edges, schemaMng, pool](const Expression *exp) -> Expression * { + [spaceId, &edges, schemaMng, isBothDirection, pool](const Expression *exp) -> Expression * { auto *propertyExpr = static_cast(exp); DCHECK_EQ(propertyExpr->sym(), "*"); DCHECK(!edges.empty()); @@ -126,6 +131,9 @@ std::string PushEFilterDownRule::toString() const { } else { auto args = ArgumentList::make(pool); for (auto &edge : edges) { + if (isBothDirection && edge.get_type() < 0) { + continue; + } auto reEdgeExp = rewriteStarEdge(propertyExpr, spaceId, edge, schemaMng, pool); if (reEdgeExp == nullptr) { return nullptr; diff --git a/src/graph/optimizer/rule/PushEFilterDownRule.h b/src/graph/optimizer/rule/PushEFilterDownRule.h index cb2b415d738..4add56e8ef3 100644 --- a/src/graph/optimizer/rule/PushEFilterDownRule.h +++ b/src/graph/optimizer/rule/PushEFilterDownRule.h @@ -26,6 +26,7 @@ class PushEFilterDownRule final : public OptRule { GraphSpaceID spaceId, const std::vector &edges, meta::SchemaManager *schemaMng, + bool isBothDirection, ObjectPool *pool); static Expression *rewriteStarEdge(const PropertyExpression *exp, GraphSpaceID spaceId, diff --git a/tests/tck/features/optimizer/PushEFilterDownRule.feature b/tests/tck/features/optimizer/PushEFilterDownRule.feature index 747e95fa6b8..7366594663c 100644 --- a/tests/tck/features/optimizer/PushEFilterDownRule.feature +++ b/tests/tck/features/optimizer/PushEFilterDownRule.feature @@ -32,7 +32,6 @@ Feature: Push EFilter down rule Then the result should be, in any order: | name | | "Tim Duncan" | - | "Tim Duncan" | And the execution plan should be: | id | name | dependencies | operator info | | 5 | Project | 8 | | @@ -41,18 +40,19 @@ Feature: Push EFilter down rule | 0 | Start | | | When profiling query: """ - MATCH (v:player{name: 'Tim Duncan'})-[e:like{likeness: 95}]-() return v.player.name AS name + MATCH (v:player{name: 'Tim Duncan'})-[e:like|serve{likeness: 95}]-() return v.player.name AS name """ Then the result should be, in any order: | name | | "Tim Duncan" | | "Tim Duncan" | + | "Tim Duncan" | And the execution plan should be: - | id | name | dependencies | operator info | - | 5 | Project | 8 | | - | 8 | Traverse | 7 | {"edge filter": "", "filter": "(like.likeness==95)"} | - | 7 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 5 | Project | 8 | | + | 8 | Traverse | 7 | {"edge filter": "", "filter": "(_any(like.likeness,serve.likeness)==95)"} | + | 7 | IndexScan | 0 | | + | 0 | Start | | | When profiling query: """ MATCH (v:player{name: 'Tim Duncan'})-[e:like*1..2{likeness: 95}]->() return v.player.name AS name