diff --git a/src/executor/query/DataCollectExecutor.cpp b/src/executor/query/DataCollectExecutor.cpp
index 955a35f95ea20d27678ad62c676b26573c1b787d..8ce77958f5ae935b4c08424a421f3253592613a5 100644
--- a/src/executor/query/DataCollectExecutor.cpp
+++ b/src/executor/query/DataCollectExecutor.cpp
@@ -108,7 +108,7 @@ Status DataCollectExecutor::rowBasedMove(const std::vector<std::string>& vars) {
     for (auto& var : vars) {
         auto& result = ectx_->getResult(var);
         auto iter = result.iter();
-        if (iter->isSequentialIter()) {
+        if (iter->isSequentialIter() || iter->isPropIter()) {
             auto* seqIter = static_cast<SequentialIter*>(iter.get());
             for (; seqIter->valid(); seqIter->next()) {
                 ds.rows.emplace_back(seqIter->moveRow());
diff --git a/src/validator/FetchEdgesValidator.cpp b/src/validator/FetchEdgesValidator.cpp
index 5ae5f5798e35ea25b5b68e2899710bba2ccabd6e..61e83bda0ec19f085f6e83605757515399c654b1 100644
--- a/src/validator/FetchEdgesValidator.cpp
+++ b/src/validator/FetchEdgesValidator.cpp
@@ -51,6 +51,7 @@ Status FetchEdgesValidator::toPlan() {
     // filter when the edge key is empty which means not exists edge in fact
     auto *notExistEdgeFilter = Filter::make(qctx_, current, emptyEdgeKeyFilter());
     notExistEdgeFilter->setInputVar(current->outputVar());
+    notExistEdgeFilter->setColNames(geColNames_);
     current = notExistEdgeFilter;
 
     if (withProject_) {
diff --git a/src/validator/SequentialValidator.cpp b/src/validator/SequentialValidator.cpp
index bd4e59318f21e3e6d461139a84632727140f519f..bfc6da685deecaa219d2a2e8bb26c8407a61df97 100644
--- a/src/validator/SequentialValidator.cpp
+++ b/src/validator/SequentialValidator.cpp
@@ -77,7 +77,8 @@ void SequentialValidator::ifBuildDataCollectForRoot(PlanNode* root) {
         case PlanNode::Kind::kDedup:
         case PlanNode::Kind::kUnion:
         case PlanNode::Kind::kIntersect:
-        case PlanNode::Kind::kMinus: {
+        case PlanNode::Kind::kMinus:
+        case PlanNode::Kind::kFilter: {
             auto* dc = DataCollect::make(
                 qctx_, root, DataCollect::CollectKind::kRowBasedMove, {root->outputVar()});
             dc->setColNames(root->colNames());
diff --git a/src/validator/test/FetchEdgesTest.cpp b/src/validator/test/FetchEdgesTest.cpp
index 7675b720b7e6aff3cf89a44745577403a1e7b279..d4b56916b6e7cfb948693b4cfb672e70e61e9fea 100644
--- a/src/validator/test/FetchEdgesTest.cpp
+++ b/src/validator/test/FetchEdgesTest.cpp
@@ -42,24 +42,26 @@ TEST_F(FetchEdgesValidatorTest, FetchEdgesProp) {
         prop.set_props({kSrc, kDst, kRank, "start", "end", "likeness"});
         std::vector<storage::cpp2::EdgeProp> props;
         props.emplace_back(std::move(prop));
-        auto *ge = GetEdges::make(qctx,
-                                  start,
-                                  1,
-                                  src.get(),
-                                  type.get(),
-                                  rank.get(),
-                                  dst.get(),
-                                  std::move(props),
-                                  {});
-        ge->setColNames({std::string("like.") + kSrc,
-                         std::string("like.") + kDst,
-                         std::string("like.") + kRank,
-                         "like.start",
-                         "like.end",
-                         "like.likeness"});
+        auto *ge = GetEdges::make(
+            qctx, start, 1, src.get(), type.get(), rank.get(), dst.get(), std::move(props), {});
+        std::vector<std::string> colNames{std::string("like.") + kSrc,
+                                          std::string("like.") + kDst,
+                                          std::string("like.") + kRank,
+                                          "like.start",
+                                          "like.end",
+                                          "like.likeness"};
+        ge->setColNames(colNames);
+
         // filter
-        auto *filter = Filter::make(qctx, ge, nullptr/*TODO*/);
-        auto result = Eq(qctx->plan()->root(), filter);
+        auto *filter = Filter::make(qctx, ge, nullptr /*TODO*/);
+        filter->setColNames(colNames);
+
+        // data collect
+        auto *dataCollect = DataCollect::make(
+            qctx, filter, DataCollect::CollectKind::kRowBasedMove, {filter->outputVar()});
+        dataCollect->setColNames(colNames);
+
+        auto result = Eq(qctx->plan()->root(), dataCollect);
         ASSERT_TRUE(result.ok()) << result;
     }
     // With YIELD
@@ -94,14 +96,16 @@ TEST_F(FetchEdgesValidatorTest, FetchEdgesProp) {
                                   dst.get(),
                                   std::move(props),
                                   std::move(exprs));
-        ge->setColNames({std::string("like.") + kSrc,
-                         std::string("like.") + kDst,
-                         std::string("like.") + kRank,
-                         "like.start",
-                         "like.end"});
+        std::vector<std::string> colNames{std::string("like.") + kSrc,
+                                          std::string("like.") + kDst,
+                                          std::string("like.") + kRank,
+                                          "like.start",
+                                          "like.end"};
+        ge->setColNames(colNames);
 
         // filter
-        auto *filter = Filter::make(qctx, ge, nullptr/*TODO*/);
+        auto *filter = Filter::make(qctx, ge, nullptr /*TODO*/);
+        filter->setColNames(colNames);
 
         // Project
         auto yieldColumns = std::make_unique<YieldColumns>();
@@ -154,14 +158,16 @@ TEST_F(FetchEdgesValidatorTest, FetchEdgesProp) {
                                   dst.get(),
                                   std::move(props),
                                   std::move(exprs));
-        ge->setColNames({std::string("like.") + kSrc,
-                         std::string("like.") + kDst,
-                         std::string("like.") + kRank,
-                         "like.start",
-                         "like.end"});
+        std::vector<std::string> colNames{std::string("like.") + kSrc,
+                                          std::string("like.") + kDst,
+                                          std::string("like.") + kRank,
+                                          "like.start",
+                                          "like.end"};
+        ge->setColNames(colNames);
 
         // filter
-        auto *filter = Filter::make(qctx, ge, nullptr/*TODO*/);
+        auto *filter = Filter::make(qctx, ge, nullptr /*TODO*/);
+        filter->setColNames(colNames);
 
         // Project
         auto yieldColumns = std::make_unique<YieldColumns>();
@@ -217,14 +223,16 @@ TEST_F(FetchEdgesValidatorTest, FetchEdgesProp) {
                                   dst.get(),
                                   std::move(props),
                                   std::move(exprs));
-        ge->setColNames({std::string("like.") + kSrc,
-                         std::string("like.") + kDst,
-                         std::string("like.") + kRank,
-                         "like.start",
-                         "like.end"});
+        std::vector<std::string> colNames{std::string("like.") + kSrc,
+                                          std::string("like.") + kDst,
+                                          std::string("like.") + kRank,
+                                          "like.start",
+                                          "like.end"};
+        ge->setColNames(colNames);
 
         // filter
-        auto *filter = Filter::make(qctx, ge, nullptr/*TODO*/);
+        auto *filter = Filter::make(qctx, ge, nullptr /*TODO*/);
+        filter->setColNames(colNames);
 
         // project, TODO(shylock) it's could push-down to storage if it supported
         auto yieldColumns = std::make_unique<YieldColumns>();
@@ -285,7 +293,8 @@ TEST_F(FetchEdgesValidatorTest, FetchEdgesProp) {
         ge->setColNames(colNames);
 
         // filter
-        auto *filter = Filter::make(qctx, ge, nullptr/*TODO*/);
+        auto *filter = Filter::make(qctx, ge, nullptr /*TODO*/);
+        filter->setColNames(colNames);
 
         // project
         auto yieldColumns = std::make_unique<YieldColumns>();
@@ -324,6 +333,7 @@ TEST_F(FetchEdgesValidatorTest, FetchEdgesInputOutput) {
                                   "FETCH PROP ON like $a.src->$a.dst";
         EXPECT_TRUE(checkResult(query,
                                 {
+                                    PlanNode::Kind::kDataCollect,
                                     PlanNode::Kind::kFilter,
                                     PlanNode::Kind::kGetEdges,
                                     PlanNode::Kind::kProject,
@@ -339,6 +349,7 @@ TEST_F(FetchEdgesValidatorTest, FetchEdgesInputOutput) {
                                   " | FETCH PROP ON like $-.src->$-.dst@$-.rank";
         EXPECT_TRUE(checkResult(query,
                                 {
+                                    PlanNode::Kind::kDataCollect,
                                     PlanNode::Kind::kFilter,
                                     PlanNode::Kind::kGetEdges,
                                     PlanNode::Kind::kProject,
diff --git a/tests/query/v1/test_fetch_edges.py b/tests/query/v1/test_fetch_edges.py
index 93ae854ff424da6bd85ec150814509d1809713a2..3d389a468121796b56527bcd69557e661dda26bd 100644
--- a/tests/query/v1/test_fetch_edges.py
+++ b/tests/query/v1/test_fetch_edges.py
@@ -272,6 +272,26 @@ class TestFetchEdges(NebulaTestSuite):
         self.check_column_names(resp, expect_columns_name)
         self.check_out_of_order_result(resp, expect_result)
 
+        query = 'FETCH PROP ON serve "Zion Williamson"->"Spurs"'
+        resp = self.execute_query(query)
+        expect_columns_name = ['serve._src',
+                               'serve._dst',
+                               'serve._rank',
+                               'serve.start_year',
+                               'serve.end_year']
+        expect_result = []
+        self.check_resp_succeeded(resp)
+        self.check_column_names(resp, expect_columns_name)
+        self.check_out_of_order_result(resp, expect_result)
+
+        query = 'FETCH PROP ON serve "Zion Williamson"->"Spurs", "Boris Diaw"->"Hawks"'
+        resp = self.execute_query(query)
+        expect_result = [["Boris Diaw", "Hawks", 0, 2003, 2005]]
+        self.check_resp_succeeded(resp)
+        self.check_column_names(resp, expect_columns_name)
+        self.check_out_of_order_result(resp, expect_result)
+
+
     def test_fetch_edges_not_duplicate_column(self):
         query = 'FETCH PROP ON serve "Boris Diaw"->"Hawks" YIELD serve.start_year, serve.start_year'
         resp = self.execute_query(query)