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)