diff --git a/src/validator/MatchValidator.cpp b/src/validator/MatchValidator.cpp
index 4fed387e5c187a98e3c44943d6aa196aafbf6cb8..25ec9afaae049d244449dd4bc72297482aa18666 100644
--- a/src/validator/MatchValidator.cpp
+++ b/src/validator/MatchValidator.cpp
@@ -481,6 +481,13 @@ Status MatchValidator::buildStep() {
     auto edgeProps = std::make_unique<std::vector<EdgeProp>>();
     if (!edgeInfo.edgeTypes.empty()) {
         for (auto edgeType : edgeInfo.edgeTypes) {
+            if (edgeInfo.direction == Direction::IN_EDGE) {
+                edgeType = -edgeType;
+            } else if (edgeInfo.direction == Direction::BOTH) {
+                EdgeProp edgeProp;
+                edgeProp.set_type(-edgeType);
+                edgeProps->emplace_back(std::move(edgeProp));
+            }
             EdgeProp edgeProp;
             edgeProp.set_type(edgeType);
             edgeProps->emplace_back(std::move(edgeProp));
diff --git a/tests/query/v2/test_match.py b/tests/query/v2/test_match.py
index 0ecf676f6187b3c4db1ac0dd7a6bc9631d6a9509..2db0fa9f4e1a9a94db0d3386a1ff7fa23b23a904 100644
--- a/tests/query/v2/test_match.py
+++ b/tests/query/v2/test_match.py
@@ -174,6 +174,76 @@ class TestMatch(NebulaTestSuite):
         self.check_column_names(resp, expected['column_names'])
         self.check_out_of_order_result(resp, expected['rows'])
 
+        stmt = '''
+                  MATCH (v1:player{name: "Danny Green"}) -[:like]-> (v2)
+                  RETURN v1.name AS Name, v2.name AS Friend
+               '''
+        resp = self.execute_query(stmt)
+        self.check_resp_succeeded(resp)
+        expected = {
+            'column_names': ['Name', 'Friend'],
+            'rows': [
+                ['Danny Green', 'LeBron James'],
+                ['Danny Green', 'Marco Belinelli'],
+                ['Danny Green', 'Tim Duncan'],
+            ]
+        }
+
+        stmt = '''
+                  MATCH (v1:player{name: "Danny Green"}) <-[:like]- (v2)
+                  RETURN v1.name AS Name, v2.name AS Friend
+               '''
+        resp = self.execute_query(stmt)
+        self.check_resp_succeeded(resp)
+        expected = {
+            'column_names': ['Name', 'Friend'],
+            'rows': [
+                ['Danny Green', 'Dejounte Murray'],
+                ['Danny Green', 'Marco Belinelli'],
+            ]
+        }
+
+        self.check_column_names(resp, expected['column_names'])
+        self.check_out_of_order_result(resp, expected['rows'])
+
+        stmt = '''
+                  MATCH (v1:player{name: "Danny Green"}) <-[:like]-> (v2)
+                  RETURN v1.name AS Name, v2.name AS Friend
+               '''
+        resp = self.execute_query(stmt)
+        self.check_resp_succeeded(resp)
+        expected = {
+            'column_names': ['Name', 'Friend'],
+            'rows': [
+                ['Danny Green', 'Dejounte Murray'],
+                ['Danny Green', 'Marco Belinelli'],
+                ['Danny Green', 'LeBron James'],
+                ['Danny Green', 'Marco Belinelli'],
+                ['Danny Green', 'Tim Duncan'],
+            ]
+        }
+        self.check_column_names(resp, expected['column_names'])
+        self.check_out_of_order_result(resp, expected['rows'])
+
+        stmt = '''
+                  MATCH (v1:player{name: "Danny Green"}) -[:like]- (v2)
+                  RETURN v1.name AS Name, v2.name AS Friend
+               '''
+        resp = self.execute_query(stmt)
+        self.check_resp_succeeded(resp)
+        expected = {
+            'column_names': ['Name', 'Friend'],
+            'rows': [
+                ['Danny Green', 'Dejounte Murray'],
+                ['Danny Green', 'Marco Belinelli'],
+                ['Danny Green', 'LeBron James'],
+                ['Danny Green', 'Marco Belinelli'],
+                ['Danny Green', 'Tim Duncan'],
+            ]
+        }
+        self.check_column_names(resp, expected['column_names'])
+        self.check_out_of_order_result(resp, expected['rows'])
+
     def test_two_steps(self):
         stmt = '''
                   MATCH (v1:player{age: 28}) -[:like]-> (v2) -[:like]-> (v3)
@@ -193,6 +263,29 @@ class TestMatch(NebulaTestSuite):
         self.check_column_names(resp, expected['column_names'])
         self.check_out_of_order_result(resp, expected['rows'])
 
+        stmt = '''
+                  MATCH (v1:player{name: 'Tony Parker'}) -[r1:serve]-> (v2) <-[r2:serve]- (v3)
+                  WHERE r1.start_year <= r2.end_year AND
+                        r1.end_year >= r2.start_year AND
+                        v1.name <> v3.name AND
+                        v3.name STARTS WITH 'D'
+                  RETURN v1.name AS Player, v2.name AS Team, v3.name AS Teammate
+               '''
+        resp = self.execute_query(stmt)
+        self.check_resp_succeeded(resp)
+        expected = {
+            'column_names': ['Player', 'Team', 'Teammate'],
+            'rows': [
+                ['Tony Parker', 'Hornets', 'Dwight Howard'],
+                ['Tony Parker', 'Spurs', 'Danny Green'],
+                ['Tony Parker', 'Spurs', 'Dejounte Murray'],
+                ['Tony Parker', 'Spurs', 'David West'],
+            ]
+        }
+        self.check_column_names(resp, expected['column_names'])
+        self.check_out_of_order_result(resp, expected['rows'])
+
+
     def test_match_by_id(self):
         # single node
         stmt = '''
@@ -309,16 +402,6 @@ class TestMatch(NebulaTestSuite):
         resp = self.execute_query(stmt)
         self.check_resp_failed(resp)
 
-        # in bound
-        stmt = 'MATCH (v:player) -[]-> () return *'
-        resp = self.execute_query(stmt)
-        self.check_resp_failed(resp)
-
-        # bidirectly
-        stmt = 'MATCH (v:player) -[]- () return *'
-        resp = self.execute_query(stmt)
-        self.check_resp_failed(resp)
-
         # multiple steps
         stmt = 'MATCH (v:player:{name: "abc"}) -[r*2]-> () return *'
         resp = self.execute_query(stmt)