diff --git a/src/common/datatypes/DataSet.h b/src/common/datatypes/DataSet.h index b1230001ce8..62317df7e0d 100644 --- a/src/common/datatypes/DataSet.h +++ b/src/common/datatypes/DataSet.h @@ -216,6 +216,13 @@ struct DataSet { bool operator==(const DataSet& rhs) const { return colNames == rhs.colNames && rows == rhs.rows; } + + void removeColumn(size_t idx) { + for (auto& row : rows) { + row.values.erase(row.values.begin() + idx); + } + colNames.erase(colNames.begin() + idx); + } }; inline std::ostream& operator<<(std::ostream& os, const DataSet& d) { diff --git a/src/common/datatypes/Value.cpp b/src/common/datatypes/Value.cpp index c49adf90290..6632feb64ac 100644 --- a/src/common/datatypes/Value.cpp +++ b/src/common/datatypes/Value.cpp @@ -678,6 +678,11 @@ const DataSet& Value::getDataSet() const { return *(value_.gVal); } +DataSet& Value::getMutableDataSet() { + CHECK_EQ(type_, Type::DATASET); + return *(value_.gVal); +} + const DataSet* Value::getDataSetPtr() const { CHECK_EQ(type_, Type::DATASET); return value_.gVal.get(); diff --git a/src/common/datatypes/Value.h b/src/common/datatypes/Value.h index b55397a1566..329536d4127 100644 --- a/src/common/datatypes/Value.h +++ b/src/common/datatypes/Value.h @@ -309,6 +309,7 @@ struct Value { const Set& getSet() const; const Set* getSetPtr() const; const DataSet& getDataSet() const; + DataSet& getMutableDataSet(); const DataSet* getDataSetPtr() const; const Geography& getGeography() const; const Geography* getGeographyPtr() const; diff --git a/src/graph/context/Symbols.h b/src/graph/context/Symbols.h index fb30d957770..61c59c20c7d 100644 --- a/src/graph/context/Symbols.h +++ b/src/graph/context/Symbols.h @@ -49,6 +49,7 @@ struct Variable { // the count of use the variable std::atomic userCount{0}; + std::vector invisibleColIndicies; }; class SymbolTable final { diff --git a/src/graph/executor/query/ProjectExecutor.cpp b/src/graph/executor/query/ProjectExecutor.cpp index 789c847b866..64db18cede0 100644 --- a/src/graph/executor/query/ProjectExecutor.cpp +++ b/src/graph/executor/query/ProjectExecutor.cpp @@ -54,10 +54,8 @@ DataSet ProjectExecutor::handleJob(size_t begin, size_t end, Iterator *iter) { for (; iter->valid() && begin++ < end; iter->next()) { Row row; for (auto &col : columns->columns()) { - if (col->isVisible()) { - Value val = col->expr()->eval(ctx(iter)); - row.values.emplace_back(std::move(val)); - } + Value val = col->expr()->eval(ctx(iter)); + row.values.emplace_back(std::move(val)); } ds.rows.emplace_back(std::move(row)); } diff --git a/src/graph/executor/query/SortExecutor.cpp b/src/graph/executor/query/SortExecutor.cpp index ebeba5cd854..8e7fcee7d32 100644 --- a/src/graph/executor/query/SortExecutor.cpp +++ b/src/graph/executor/query/SortExecutor.cpp @@ -44,6 +44,9 @@ folly::Future SortExecutor::execute() { auto seqIter = static_cast(iter); std::sort(seqIter->begin(), seqIter->end(), comparator); + for (auto &idx : sort->inputVars()[0]->invisibleColIndicies) { + result.valuePtr()->getMutableDataSet().removeColumn(idx); + } return finish(ResultBuilder().value(result.valuePtr()).iter(std::move(result).iter()).build()); } diff --git a/src/graph/planner/match/ReturnClausePlanner.cpp b/src/graph/planner/match/ReturnClausePlanner.cpp index 87fa55714de..bf8d278dd5c 100644 --- a/src/graph/planner/match/ReturnClausePlanner.cpp +++ b/src/graph/planner/match/ReturnClausePlanner.cpp @@ -38,6 +38,13 @@ Status ReturnClausePlanner::buildReturn(ReturnClauseContext* rctx, SubPlan& subP NG_RETURN_IF_ERROR(orderPlan); auto plan = std::move(orderPlan).value(); subPlan = SegmentsConnector::addInput(plan, subPlan, true); + size_t idx = 0; + for (auto& yiledCol : rctx->yield->yieldColumns->columns()) { + if (!yiledCol->isVisible()) { + subPlan.root->mutableInputVars()[0]->invisibleColIndicies.push_back(idx); + } + idx++; + } } if (rctx->pagination != nullptr && diff --git a/src/graph/planner/plan/PlanNode.h b/src/graph/planner/plan/PlanNode.h index 621593970cf..5632c8cdc9c 100644 --- a/src/graph/planner/plan/PlanNode.h +++ b/src/graph/planner/plan/PlanNode.h @@ -278,6 +278,10 @@ class PlanNode { return inputVars_; } + std::vector& mutableInputVars() { + return inputVars_; + } + void releaseSymbols(); void updateSymbols(); diff --git a/src/graph/validator/MatchValidator.cpp b/src/graph/validator/MatchValidator.cpp index 94b552b69b7..f07c5fcb4f6 100644 --- a/src/graph/validator/MatchValidator.cpp +++ b/src/graph/validator/MatchValidator.cpp @@ -506,7 +506,7 @@ Status MatchValidator::validateReturn(MatchReturn *ret, col->setVisible(false); columns->addColumn(col->clone().release()); found = true; - orderByCtx->indexedOrderFactors.emplace_back(columns->size(), factor->orderType()); + orderByCtx->indexedOrderFactors.emplace_back(columns->size() - 1, factor->orderType()); break; } } @@ -518,6 +518,7 @@ Status MatchValidator::validateReturn(MatchReturn *ret, orderByCtx->indexedOrderFactors.emplace_back(iter->second, factor->orderType()); } } + retClauseCtx.order = std::move(orderByCtx); preValidatedOrderBy = true; } // finished producing columns for further validations diff --git a/src/parser/Clauses.h b/src/parser/Clauses.h index e9bd97d9c0c..d4fd8350f9b 100644 --- a/src/parser/Clauses.h +++ b/src/parser/Clauses.h @@ -254,13 +254,14 @@ class WhenClause : public WhereClause { class YieldColumn final { public: - explicit YieldColumn(Expression *expr, const std::string &alias = "") { + explicit YieldColumn(Expression *expr, const std::string &alias = "", bool visible = true) { expr_ = expr; alias_ = alias; + visible_ = visible; } std::unique_ptr clone() const { - return std::make_unique(expr_->clone(), alias_); + return std::make_unique(expr_->clone(), alias_, visible_); } void setExpr(Expression *expr) {