diff --git a/src/planner/PlanNode.h b/src/planner/PlanNode.h index f958733560045c2ae4b94c8541e369c38339539e..8c7b9cefe8220f5e77b28e691e9b27eda87bba34 100644 --- a/src/planner/PlanNode.h +++ b/src/planner/PlanNode.h @@ -228,6 +228,12 @@ public: protected: static void addDescription(std::string key, std::string value, PlanNodeDescription* desc); + void clone(const PlanNode &node) { + // TODO maybe shall copy cost_ and dependencies_ too + inputVars_ = node.inputVars_; + outputVars_ = node.outputVars_; + } + QueryContext* qctx_{nullptr}; Kind kind_{Kind::kUnknown}; int64_t id_{-1}; @@ -255,6 +261,10 @@ protected: dependencies_.emplace_back(dep); } + void clone(const SingleDependencyNode &node) { + PlanNode::clone(node); + } + std::unique_ptr<PlanNodeDescription> explain() const override; }; @@ -292,6 +302,10 @@ public: std::unique_ptr<PlanNodeDescription> explain() const override; protected: + void clone(const SingleInputNode &node) { + SingleDependencyNode::clone(node); + } + SingleInputNode(QueryContext* qctx, Kind kind, const PlanNode* dep) : SingleDependencyNode(qctx, kind, dep) { if (dep != nullptr) { diff --git a/src/planner/Query.cpp b/src/planner/Query.cpp index 6aed83971ac7cb78d33e6305dad68079a1fe3718..a7b75b0d0761ffdddd2367896b9247c34b8b6785 100644 --- a/src/planner/Query.cpp +++ b/src/planner/Query.cpp @@ -29,39 +29,7 @@ std::unique_ptr<PlanNodeDescription> Explore::explain() const { GetNeighbors* GetNeighbors::clone(QueryContext* qctx) const { auto newGN = GetNeighbors::make(qctx, nullptr, space_); - newGN->setSrc(qctx->objPool()->add(src_->clone().release())); - newGN->setEdgeTypes(edgeTypes_); - newGN->setEdgeDirection(edgeDirection_); - newGN->setDedup(dedup_); - newGN->setRandom(random_); - newGN->setLimit(limit_); - newGN->setOrderBy(orderBy_); - newGN->setInputVar(inputVar()); - newGN->setOutputVar(outputVar()); - - if (vertexProps_) { - auto vertexProps = *vertexProps_; - auto vertexPropsPtr = std::make_unique<decltype(vertexProps)>(vertexProps); - newGN->setVertexProps(std::move(vertexPropsPtr)); - } - - if (edgeProps_) { - auto edgeProps = *edgeProps_; - auto edgePropsPtr = std::make_unique<decltype(edgeProps)>(std::move(edgeProps)); - newGN->setEdgeProps(std::move(edgePropsPtr)); - } - - if (statProps_) { - auto statProps = *statProps_; - auto statPropsPtr = std::make_unique<decltype(statProps)>(std::move(statProps)); - newGN->setStatProps(std::move(statPropsPtr)); - } - - if (exprs_) { - auto exprs = *exprs_; - auto exprsPtr = std::make_unique<decltype(exprs)>(exprs); - newGN->setExprs(std::move(exprsPtr)); - } + newGN->clone(*this); return newGN; } @@ -83,6 +51,38 @@ std::unique_ptr<PlanNodeDescription> GetNeighbors::explain() const { return desc; } +void GetNeighbors::clone(const GetNeighbors& g) { + Explore::clone(g); + setSrc(qctx_->objPool()->add(g.src_->clone().release())); + setEdgeTypes(g.edgeTypes_); + setEdgeDirection(g.edgeDirection_); + setRandom(g.random_); + if (g.vertexProps_) { + auto vertexProps = *g.vertexProps_; + auto vertexPropsPtr = std::make_unique<decltype(vertexProps)>(vertexProps); + setVertexProps(std::move(vertexPropsPtr)); + } + + if (g.edgeProps_) { + auto edgeProps = *g.edgeProps_; + auto edgePropsPtr = std::make_unique<decltype(edgeProps)>(std::move(edgeProps)); + setEdgeProps(std::move(edgePropsPtr)); + } + + if (g.statProps_) { + auto statProps = *g.statProps_; + auto statPropsPtr = std::make_unique<decltype(statProps)>(std::move(statProps)); + setStatProps(std::move(statPropsPtr)); + } + + if (g.exprs_) { + auto exprs = *g.exprs_; + auto exprsPtr = std::make_unique<decltype(exprs)>(exprs); + setExprs(std::move(exprsPtr)); + } +} + + std::unique_ptr<PlanNodeDescription> GetVertices::explain() const { auto desc = Explore::explain(); addDescription("src", src_ ? src_->toString() : "", desc.get()); @@ -103,14 +103,25 @@ std::unique_ptr<PlanNodeDescription> GetEdges::explain() const { } IndexScan* IndexScan::clone(QueryContext* qctx) const { - auto ctx = std::make_unique<std::vector<storage::cpp2::IndexQueryContext>>(); - auto returnCols = std::make_unique<std::vector<std::string>>(*returnColumns()); auto* scan = IndexScan::make( - qctx, nullptr, space(), std::move(ctx), std::move(returnCols), isEdge(), schemaId()); - scan->setOutputVar(this->outputVar()); + qctx, nullptr, space(), nullptr, nullptr, isEdge(), schemaId()); + scan->clone(*this); return scan; } +void IndexScan::clone(const IndexScan &g) { + Explore::clone(g); + if (g.contexts_ != nullptr) { + contexts_ = std::make_unique<std::vector<storage::cpp2::IndexQueryContext>>(*g.contexts_); + } + if (g.returnCols_ != nullptr) { + returnCols_ = std::make_unique<std::vector<std::string>>(*g.returnCols_); + } + isEdge_ = g.isEdge_; + schemaId_ = g.schemaId_; + isEmptyResultSet_ = g.isEmptyResultSet_; +} + std::unique_ptr<PlanNodeDescription> IndexScan::explain() const { auto desc = Explore::explain(); addDescription("schemaId", util::toJson(schemaId_), desc.get()); @@ -127,17 +138,19 @@ std::unique_ptr<PlanNodeDescription> Filter::explain() const { } Project* Project::clone(QueryContext* qctx) const { - auto cols = qctx->objPool()->add(new YieldColumns()); - for (auto col : columns()->columns()) { - cols->addColumn((col->clone()).release()); - } - - auto newProj = Project::make(qctx, nullptr, cols); - newProj->setInputVar(inputVar()); - newProj->setOutputVar(outputVar()); + auto newProj = Project::make(qctx, nullptr, nullptr); + newProj->clone(*this); return newProj; } +void Project::clone(const Project &p) { + SingleInputNode::clone(p); + cols_ = qctx_->objPool()->makeAndAdd<YieldColumns>(); + for (const auto &col : p.columns()->columns()) { + cols_->addColumn(col->clone().release()); + } +} + std::unique_ptr<PlanNodeDescription> Project::explain() const { auto desc = SingleInputNode::explain(); addDescription("columns", cols_ ? cols_->toString() : "", desc.get()); @@ -152,11 +165,16 @@ std::unique_ptr<PlanNodeDescription> Sort::explain() const { Limit* Limit::clone(QueryContext* qctx) const { auto newLimit = Limit::make(qctx, nullptr, offset_, count_); - newLimit->setInputVar(inputVar()); - newLimit->setOutputVar(outputVar()); + newLimit->clone(*this); return newLimit; } +void Limit::clone(const Limit &l) { + SingleInputNode::clone(l); + offset_ = l.offset_; + count_ = l.count_; +} + std::unique_ptr<PlanNodeDescription> Limit::explain() const { auto desc = SingleInputNode::explain(); addDescription("offset", folly::to<std::string>(offset_), desc.get()); diff --git a/src/planner/Query.h b/src/planner/Query.h index 6ac8b06822fa744493429a1144e638e95f6a084e..d6d6ca2a4180524fdd8dd9da42f3bf7b3a8313eb 100644 --- a/src/planner/Query.h +++ b/src/planner/Query.h @@ -90,6 +90,15 @@ protected: : SingleInputNode(qctx, kind, input), space_(space) {} protected: + void clone(const Explore& e) { + SingleInputNode::clone(e); + space_ = e.space_; + dedup_ = e.dedup_; + limit_ = e.limit_; + filter_ = e.filter_; + orderBy_ = e.orderBy_; + } + GraphSpaceID space_; bool dedup_{false}; int64_t limit_{std::numeric_limits<int64_t>::max()}; @@ -215,6 +224,8 @@ private: : Explore(qctx, Kind::kGetNeighbors, input, space) {} private: + void clone(const GetNeighbors& g); + Expression* src_{nullptr}; std::vector<EdgeType> edgeTypes_; storage::cpp2::EdgeDirection edgeDirection_{storage::cpp2::EdgeDirection::OUT_EDGE}; @@ -502,6 +513,8 @@ private: isEmptyResultSet_ = isEmptyResultSet; } + void clone(const IndexScan &g); + private: IndexQueryCtx contexts_; IndexReturnCols returnCols_; @@ -617,6 +630,8 @@ private: Project(QueryContext* qctx, PlanNode* input, YieldColumns* cols) : SingleInputNode(qctx, Kind::kProject, input), cols_(cols) { } + void clone(const Project &p); + private: YieldColumns* cols_{nullptr}; }; @@ -694,6 +709,8 @@ private: count_ = count; } + void clone(const Limit &l); + private: int64_t offset_{-1}; int64_t count_{-1}; diff --git a/tests/tck/features/go/GO.IntVid.feature b/tests/tck/features/go/GO.IntVid.feature index f5462b44a5c7a03c101383937dfe41aaa5a75625..c802d664267733527b6970bb7f456326dfc243fc 100644 --- a/tests/tck/features/go/GO.IntVid.feature +++ b/tests/tck/features/go/GO.IntVid.feature @@ -1593,3 +1593,13 @@ Feature: IntegerVid Go Sentence Then the result should be, in any order, with relax comparison: | COUNT($-.id) | | 4 | + + @skip + Scenario: Integer Vid Bugfix filter not pushdown + When executing query: + """ + GO FROM hash("Tim Duncan") OVER like WHERE like._dst == hash("Tony Parker") | limit 10; + """ + Then the result should be, in any order, with relax comparison: + | like._dst | + | hash("Tony Parker") | diff --git a/tests/tck/features/go/GO.feature b/tests/tck/features/go/GO.feature index 61400991ab4fa91c91d5dfc3d139d3a8a7b3e88f..f0ca0849474b658c1be234f5c1fd1137c9db3cee 100644 --- a/tests/tck/features/go/GO.feature +++ b/tests/tck/features/go/GO.feature @@ -1593,3 +1593,12 @@ Feature: Go Sentence Then the result should be, in any order, with relax comparison: | COUNT($-.id) | | 4 | + + Scenario: Bugfix filter not pushdown + When executing query: + """ + GO FROM "Tim Duncan" OVER like WHERE like._dst == "Tony Parker" | limit 10; + """ + Then the result should be, in any order, with relax comparison: + | like._dst | + | "Tony Parker" |