diff --git a/src/graph/context/Iterator.cpp b/src/graph/context/Iterator.cpp index 0be1a2f533f..2bc009a8a40 100644 --- a/src/graph/context/Iterator.cpp +++ b/src/graph/context/Iterator.cpp @@ -275,6 +275,29 @@ void GetNeighborsIter::next() { } } +size_t GetNeighborsIter::size() const { + size_t count = 0; + for (const auto& dsIdx : dsIndices_) { + for (const auto& row : dsIdx.ds->rows) { + for (const auto& edgeIdx : dsIdx.edgePropsMap) { + const auto& cell = row[edgeIdx.second.colIdx]; + if (LIKELY(cell.isList())) { + count += cell.getList().size(); + } + } + } + } + return count; +} + +size_t GetNeighborsIter::numRows() const { + size_t count = 0; + for (const auto& dsIdx : dsIndices_) { + count += dsIdx.ds->size(); + } + return count; +} + void GetNeighborsIter::erase() { DCHECK_GE(bitIdx_, 0); DCHECK_LT(bitIdx_, bitset_.size()); @@ -441,6 +464,7 @@ Value GetNeighborsIter::getVertex(const std::string& name) const { List GetNeighborsIter::getVertices() { List vertices; + vertices.reserve(numRows()); valid_ = true; colIdx_ = -2; for (currentDs_ = dsIndices_.begin(); currentDs_ < dsIndices_.end(); ++currentDs_) { @@ -512,6 +536,7 @@ Value GetNeighborsIter::getEdge() const { List GetNeighborsIter::getEdges() { List edges; + edges.reserve(size()); for (; valid(); next()) { auto edge = getEdge(); if (edge.isEdge()) { diff --git a/src/graph/context/Iterator.h b/src/graph/context/Iterator.h index 1a89b12d175..8a3a379255a 100644 --- a/src/graph/context/Iterator.h +++ b/src/graph/context/Iterator.h @@ -288,9 +288,11 @@ class GetNeighborsIter final : public Iterator { void sample(int64_t count) override; - size_t size() const override { - LOG(FATAL) << "Unimplemented method for Get Neighbros iterator."; - } + // num of edges + size_t size() const override; + + // num of vertices + size_t numRows() const; const Value& getColumn(const std::string& col) const override; diff --git a/src/graph/context/ast/QueryAstContext.h b/src/graph/context/ast/QueryAstContext.h index 0f6f71f0029..8fc3c2d1015 100644 --- a/src/graph/context/ast/QueryAstContext.h +++ b/src/graph/context/ast/QueryAstContext.h @@ -124,9 +124,10 @@ struct SubgraphContext final : public AstContext { Starts from; StepClause steps; std::string loopSteps; - YieldColumns* yieldExpr; std::vector colNames; std::unordered_set edgeTypes; + std::unordered_set biDirectEdgeTypes; + std::vector colType; bool withProp{false}; bool getVertexProp{false}; bool getEdgeProp{false}; diff --git a/src/graph/executor/algo/SubgraphExecutor.cpp b/src/graph/executor/algo/SubgraphExecutor.cpp index 121e732d031..8b98b6f9202 100644 --- a/src/graph/executor/algo/SubgraphExecutor.cpp +++ b/src/graph/executor/algo/SubgraphExecutor.cpp @@ -21,55 +21,69 @@ folly::Future SubgraphExecutor::execute() { DCHECK(currentStepVal.isInt()); auto currentStep = currentStepVal.getInt(); VLOG(1) << "Current Step is: " << currentStep << " Total Steps is: " << steps; - - if (currentStep == steps) { - oneMoreStep(); - return finish(ResultBuilder().value(Value(std::move(ds))).build()); - } + auto resultVar = subgraph->resultVar(); VLOG(1) << "input: " << subgraph->inputVar() << " output: " << node()->outputVar(); auto iter = ectx_->getResult(subgraph->inputVar()).iter(); - DCHECK(iter && iter->isGetNeighborsIter()); + auto gnSize = iter->size(); + + ResultBuilder builder; + builder.value(iter->valuePtr()); + + std::unordered_map currentVids; + currentVids.reserve(gnSize); + historyVids_.reserve(historyVids_.size() + gnSize); if (currentStep == 1) { for (; iter->valid(); iter->next()) { const auto& src = iter->getColumn(nebula::kVid); - historyVids_.emplace(src); + currentVids.emplace(src, 0); } iter->reset(); } - for (; iter->valid(); iter->next()) { - const auto& dst = iter->getEdgeProp("*", nebula::kDst); - if (historyVids_.emplace(dst).second) { - Row row; - row.values.emplace_back(std::move(dst)); - ds.rows.emplace_back(std::move(row)); - } - } - - VLOG(1) << "Next step vid is : " << ds; - return finish(ResultBuilder().value(Value(std::move(ds))).build()); -} - -void SubgraphExecutor::oneMoreStep() { - auto* subgraph = asNode(node()); - auto output = subgraph->oneMoreStepOutput(); - VLOG(1) << "OneMoreStep Input: " << subgraph->inputVar() << " Output: " << output; - auto iter = ectx_->getResult(subgraph->inputVar()).iter(); - DCHECK(iter && iter->isGetNeighborsIter()); - - ResultBuilder builder; - builder.value(iter->valuePtr()); + auto& biDirectEdgeTypes = subgraph->biDirectEdgeTypes(); while (iter->valid()) { const auto& dst = iter->getEdgeProp("*", nebula::kDst); - if (historyVids_.find(dst) == historyVids_.end()) { - iter->unstableErase(); + auto findIter = historyVids_.find(dst); + if (findIter != historyVids_.end()) { + if (biDirectEdgeTypes.empty()) { + iter->next(); + } else { + const auto& typeVal = iter->getEdgeProp("*", nebula::kType); + if (UNLIKELY(!typeVal.isInt())) { + iter->erase(); + continue; + } + auto type = typeVal.getInt(); + if (biDirectEdgeTypes.find(type) != biDirectEdgeTypes.end()) { + if (type < 0 || findIter->second + 2 == currentStep) { + iter->erase(); + } else { + iter->next(); + } + } else { + iter->next(); + } + } } else { + if (currentStep == steps) { + iter->erase(); + continue; + } + if (currentVids.emplace(dst, currentStep).second) { + Row row; + row.values.emplace_back(std::move(dst)); + ds.rows.emplace_back(std::move(row)); + } iter->next(); } } iter->reset(); builder.iter(std::move(iter)); - ectx_->setResult(output, builder.build()); + ectx_->setResult(resultVar, builder.build()); + // update historyVids + historyVids_.insert(std::make_move_iterator(currentVids.begin()), + std::make_move_iterator(currentVids.end())); + return finish(ResultBuilder().value(Value(std::move(ds))).build()); } } // namespace graph diff --git a/src/graph/executor/algo/SubgraphExecutor.h b/src/graph/executor/algo/SubgraphExecutor.h index 83da2e6cc82..0bd388c76f2 100644 --- a/src/graph/executor/algo/SubgraphExecutor.h +++ b/src/graph/executor/algo/SubgraphExecutor.h @@ -8,6 +8,34 @@ #include "graph/executor/Executor.h" +// Subgraph receive result from GetNeighbors +// There are two Main functions +// First : Extract the deduplicated destination VID from GetNeighbors +// Second: Delete previously visited edges and save the result(iter) to the variable `resultVar` +// +// Member: +// `historyVids_` : is hash table +// KEY : the VID of the visited destination Vertex +// VALUE : the number of steps to visit the KEY (starting vertex is 0) +// since each vertex will only be visited once, if it is a one-way edge expansion, there will be no +// duplicate edges. we only need to focus on the case of two-way expansion +// +// How to delete edges: +// determine whether a loop is formed by the number of steps. If the destination vid has been +// visited, and the number of steps of the destination vid differs by 2 from the current steps, it +// is judged that a loop is formed, the edge needs to be deleted +// +// For example: Topology is below +// a->c, a->b, b->a, b->c +// statement: get subgraph from 'a' both edge yield vertices as nodes, edges as relationships +// first steps : a->b, a->c, a<-b, all edges need to save +// second steps: b->a, b<-a, b->c, c<-a +// since it is a two-way expansion, the negative edge has already been visited, +// so b<-a & c<-a are deleted +// b->a : the number of steps of the destination vid `a` is 0, and the current steps is 2. it can be +// determined that a loop is formed, so this edge also needs to be deleted. +// b->c : determined by the number of steps that no loop is formed, so keep it + namespace nebula { namespace graph { class SubgraphExecutor : public Executor { @@ -18,10 +46,7 @@ class SubgraphExecutor : public Executor { folly::Future execute() override; private: - void oneMoreStep(); - - private: - std::unordered_set historyVids_; + std::unordered_map historyVids_; }; } // namespace graph diff --git a/src/graph/executor/query/DataCollectExecutor.cpp b/src/graph/executor/query/DataCollectExecutor.cpp index d165625c16c..7fefd9012a4 100644 --- a/src/graph/executor/query/DataCollectExecutor.cpp +++ b/src/graph/executor/query/DataCollectExecutor.cpp @@ -61,43 +61,49 @@ folly::Future DataCollectExecutor::doCollect() { } Status DataCollectExecutor::collectSubgraph(const std::vector& vars) { + const auto* dc = asNode(node()); + const auto& colType = dc->colType(); DataSet ds; ds.colNames = std::move(colNames_); - std::unordered_set> uniqueEdges; - for (auto i = vars.begin(); i != vars.end(); ++i) { - const auto& hist = ectx_->getHistory(*i); - for (auto j = hist.begin(); j != hist.end(); ++j) { - if (i == vars.begin() && j == hist.end() - 1) { - continue; - } - auto iter = (*j).iter(); - if (!iter->isGetNeighborsIter()) { - std::stringstream msg; - msg << "Iterator should be kind of GetNeighborIter, but was: " << iter->kind(); - return Status::Error(msg.str()); - } - List vertices; - List edges; - auto* gnIter = static_cast(iter.get()); - auto originVertices = gnIter->getVertices(); - for (auto& v : originVertices.values) { - if (UNLIKELY(!v.isVertex())) { - continue; + const auto& hist = ectx_->getHistory(vars[0]); + for (const auto& result : hist) { + auto iter = result.iter(); + auto* gnIter = static_cast(iter.get()); + List vertices; + List edges; + Row row; + bool notEmpty = false; + for (const auto& type : colType) { + if (type == Value::Type::VERTEX) { + auto originVertices = gnIter->getVertices(); + vertices.reserve(originVertices.size()); + for (auto& v : originVertices.values) { + if (UNLIKELY(!v.isVertex())) { + continue; + } + vertices.emplace_back(std::move(v)); } - vertices.emplace_back(std::move(v)); - } - auto originEdges = gnIter->getEdges(); - for (auto& edge : originEdges.values) { - if (UNLIKELY(!edge.isEdge())) { - continue; + if (!vertices.empty()) { + notEmpty = true; + row.emplace_back(std::move(vertices)); } - const auto& e = edge.getEdge(); - auto edgeKey = std::make_tuple(e.src, e.type, e.ranking, e.dst); - if (uniqueEdges.emplace(std::move(edgeKey)).second) { + } else { + auto originEdges = gnIter->getEdges(); + edges.reserve(originEdges.size()); + for (auto& edge : originEdges.values) { + if (UNLIKELY(!edge.isEdge())) { + continue; + } edges.emplace_back(std::move(edge)); } + if (!edges.empty()) { + notEmpty = true; + } + row.emplace_back(std::move(edges)); } - ds.rows.emplace_back(Row({std::move(vertices), std::move(edges)})); + } + if (notEmpty) { + ds.rows.emplace_back(std::move(row)); } } result_.setDataSet(std::move(ds)); diff --git a/src/graph/executor/test/DataCollectTest.cpp b/src/graph/executor/test/DataCollectTest.cpp index b44fd9f1dbb..fce4c2538bd 100644 --- a/src/graph/executor/test/DataCollectTest.cpp +++ b/src/graph/executor/test/DataCollectTest.cpp @@ -166,6 +166,7 @@ TEST_F(DataCollectTest, CollectSubgraph) { auto* dc = DataCollect::make(qctx_.get(), DataCollect::DCKind::kSubgraph); dc->setInputVars({"input_datasets"}); dc->setColNames(std::vector{"_vertices", "_edges"}); + dc->setColType({Value::Type::VERTEX, Value::Type::EDGE}); auto dcExe = std::make_unique(dc, qctx_.get()); auto future = dcExe->execute(); @@ -179,8 +180,6 @@ TEST_F(DataCollectTest, CollectSubgraph) { auto iter = hist[0].iter(); auto* gNIter = static_cast(iter.get()); Row row; - std::unordered_set vids; - std::unordered_set> edgeKeys; List vertices; List edges; auto originVertices = gNIter->getVertices(); @@ -188,20 +187,14 @@ TEST_F(DataCollectTest, CollectSubgraph) { if (!v.isVertex()) { continue; } - if (vids.emplace(v.getVertex().vid).second) { - vertices.emplace_back(std::move(v)); - } + vertices.emplace_back(std::move(v)); } auto originEdges = gNIter->getEdges(); for (auto& e : originEdges.values) { if (!e.isEdge()) { continue; } - auto edgeKey = - std::make_tuple(e.getEdge().src, e.getEdge().type, e.getEdge().ranking, e.getEdge().dst); - if (edgeKeys.emplace(std::move(edgeKey)).second) { - edges.emplace_back(std::move(e)); - } + edges.emplace_back(std::move(e)); } row.values.emplace_back(std::move(vertices)); row.values.emplace_back(std::move(edges)); @@ -243,10 +236,6 @@ TEST_F(DataCollectTest, EmptyResult) { DataSet expected; expected.colNames = {"_vertices", "_edges"}; - Row row; - row.values.emplace_back(Value(List())); - row.values.emplace_back(Value(List())); - expected.rows.emplace_back(std::move(row)); EXPECT_EQ(result.value().getDataSet(), expected); EXPECT_EQ(result.state(), Result::State::kSuccess); } diff --git a/src/graph/planner/ngql/SubgraphPlanner.cpp b/src/graph/planner/ngql/SubgraphPlanner.cpp index ce7a583701c..f071c58302d 100644 --- a/src/graph/planner/ngql/SubgraphPlanner.cpp +++ b/src/graph/planner/ngql/SubgraphPlanner.cpp @@ -19,6 +19,7 @@ StatusOr>> SubgraphPlanner::buildEdgeProps bool getEdgeProp = subgraphCtx_->withProp && subgraphCtx_->getEdgeProp; const auto& space = subgraphCtx_->space; auto& edgeTypes = subgraphCtx_->edgeTypes; + auto& biDirectEdgeTypes = subgraphCtx_->biDirectEdgeTypes; if (edgeTypes.empty()) { const auto allEdgesSchema = qctx->schemaMng()->getAllLatestVerEdgeSchema(space.id); @@ -27,6 +28,8 @@ StatusOr>> SubgraphPlanner::buildEdgeProps for (const auto& edge : allEdges) { edgeTypes.emplace(edge.first); edgeTypes.emplace(-edge.first); + biDirectEdgeTypes.emplace(edge.first); + biDirectEdgeTypes.emplace(-edge.first); } } std::vector vEdgeTypes(edgeTypes.begin(), edgeTypes.end()); @@ -65,11 +68,12 @@ StatusOr SubgraphPlanner::nSteps(SubPlan& startVidPlan, const std::stri gn->setEdgeProps(std::move(edgeProps).value()); gn->setInputVar(input); - auto oneMoreStepOutput = qctx->vctx()->anonVarGen()->getVar(); + auto resultVar = qctx->vctx()->anonVarGen()->getVar(); auto loopSteps = qctx->vctx()->anonVarGen()->getVar(); subgraphCtx_->loopSteps = loopSteps; - auto* subgraph = Subgraph::make(qctx, gn, oneMoreStepOutput, loopSteps, steps.steps() + 1); + auto* subgraph = Subgraph::make(qctx, gn, resultVar, loopSteps, steps.steps() + 1); subgraph->setOutputVar(input); + subgraph->setBiDirectEdgeTypes(subgraphCtx_->biDirectEdgeTypes); subgraph->setColNames({nebula::kVid}); auto* condition = loopCondition(steps.steps() + 1, gn->outputVar()); @@ -77,13 +81,12 @@ StatusOr SubgraphPlanner::nSteps(SubPlan& startVidPlan, const std::stri auto* dc = DataCollect::make(qctx, DataCollect::DCKind::kSubgraph); dc->addDep(loop); - dc->setInputVars({gn->outputVar(), oneMoreStepOutput}); - dc->setColNames({"VERTICES", "EDGES"}); - - auto* project = Project::make(qctx, dc, subgraphCtx_->yieldExpr); + dc->setInputVars({resultVar}); + dc->setColType(std::move(subgraphCtx_->colType)); + dc->setColNames(subgraphCtx_->colNames); SubPlan subPlan; - subPlan.root = project; + subPlan.root = dc; subPlan.tail = startVidPlan.tail != nullptr ? startVidPlan.tail : loop; return subPlan; } diff --git a/src/graph/planner/plan/Algo.h b/src/graph/planner/plan/Algo.h index 1320e618c88..17e2887354e 100644 --- a/src/graph/planner/plan/Algo.h +++ b/src/graph/planner/plan/Algo.h @@ -134,15 +134,14 @@ class Subgraph final : public SingleInputNode { public: static Subgraph* make(QueryContext* qctx, PlanNode* input, - const std::string& oneMoreStepOutput, + const std::string& resultVar, const std::string& currentStepVar, uint32_t steps) { - return qctx->objPool()->add( - new Subgraph(qctx, input, oneMoreStepOutput, currentStepVar, steps)); + return qctx->objPool()->add(new Subgraph(qctx, input, resultVar, currentStepVar, steps)); } - const std::string& oneMoreStepOutput() const { - return oneMoreStepOutput_; + const std::string& resultVar() const { + return resultVar_; } const std::string& currentStepVar() const { @@ -153,20 +152,29 @@ class Subgraph final : public SingleInputNode { return steps_; } + const std::unordered_set biDirectEdgeTypes() const { + return biDirectEdgeTypes_; + } + + void setBiDirectEdgeTypes(std::unordered_set edgeTypes) { + biDirectEdgeTypes_ = std::move(edgeTypes); + } + private: Subgraph(QueryContext* qctx, PlanNode* input, - const std::string& oneMoreStepOutput, + const std::string& resultVar, const std::string& currentStepVar, uint32_t steps) : SingleInputNode(qctx, Kind::kSubgraph, input), - oneMoreStepOutput_(oneMoreStepOutput), + resultVar_(resultVar), currentStepVar_(currentStepVar), steps_(steps) {} - std::string oneMoreStepOutput_; + std::string resultVar_; std::string currentStepVar_; uint32_t steps_; + std::unordered_set biDirectEdgeTypes_; }; class BiCartesianProduct final : public BinaryInputNode { diff --git a/src/graph/planner/plan/Query.h b/src/graph/planner/plan/Query.h index 206f1452485..3a070759cd9 100644 --- a/src/graph/planner/plan/Query.h +++ b/src/graph/planner/plan/Query.h @@ -1228,6 +1228,14 @@ class DataCollect final : public VariableDependencyNode { return distinct_; } + void setColType(std::vector&& colType) { + colType_ = std::move(colType); + } + + const std::vector& colType() const { + return colType_; + } + PlanNode* clone() const override; std::unique_ptr explain() const override; @@ -1242,6 +1250,7 @@ class DataCollect final : public VariableDependencyNode { DCKind kind_; // using for m to n steps StepClause step_; + std::vector colType_; bool distinct_{false}; }; diff --git a/src/graph/validator/GetSubgraphValidator.cpp b/src/graph/validator/GetSubgraphValidator.cpp index c50d3ef47ea..d4e31ff645f 100644 --- a/src/graph/validator/GetSubgraphValidator.cpp +++ b/src/graph/validator/GetSubgraphValidator.cpp @@ -75,10 +75,12 @@ Status GetSubgraphValidator::validateOutBound(OutBoundClause* out) { // Validate bidirectional(in-bound and out-bound) edge types Status GetSubgraphValidator::validateBothInOutBound(BothInOutClause* out) { auto& edgeTypes = subgraphCtx_->edgeTypes; + auto& biEdgeTypes = subgraphCtx_->biDirectEdgeTypes; if (out != nullptr) { auto space = vctx_->whichSpace(); auto edges = out->edges(); - edgeTypes.reserve(edgeTypes.size() + edges.size()); + edgeTypes.reserve(edgeTypes.size() + edges.size() * 2); + biEdgeTypes.reserve(edges.size() * 2); for (auto* e : out->edges()) { if (e->alias() != nullptr) { return Status::SemanticError("Get Subgraph not support rename edge name."); @@ -89,8 +91,9 @@ Status GetSubgraphValidator::validateBothInOutBound(BothInOutClause* out) { auto v = et.value(); edgeTypes.emplace(v); - v = -v; - edgeTypes.emplace(v); + edgeTypes.emplace(-v); + biEdgeTypes.emplace(v); + biEdgeTypes.emplace(-v); } } return Status::OK(); @@ -103,29 +106,25 @@ Status GetSubgraphValidator::validateYield(YieldClause* yield) { } auto size = yield->columns().size(); outputs_.reserve(size); - auto pool = qctx_->objPool(); - YieldColumns* newCols = pool->add(new YieldColumns()); - + std::vector colType; for (const auto& col : yield->columns()) { const std::string& colStr = col->expr()->toString(); if (colStr == "VERTICES") { subgraphCtx_->getVertexProp = true; - auto* newCol = new YieldColumn(InputPropertyExpression::make(pool, "VERTICES"), col->name()); - newCols->addColumn(newCol); + colType.emplace_back(Value::Type::VERTEX); } else if (colStr == "EDGES") { if (subgraphCtx_->steps.steps() == 0) { return Status::SemanticError("Get Subgraph 0 STEPS only support YIELD vertices"); } subgraphCtx_->getEdgeProp = true; - auto* newCol = new YieldColumn(InputPropertyExpression::make(pool, "EDGES"), col->name()); - newCols->addColumn(newCol); + colType.emplace_back(Value::Type::EDGE); } else { return Status::SemanticError("Get Subgraph only support YIELD vertices OR edges"); } outputs_.emplace_back(col->name(), Value::Type::LIST); } - subgraphCtx_->yieldExpr = newCols; subgraphCtx_->colNames = getOutColNames(); + subgraphCtx_->colType = std::move(colType); return Status::OK(); } diff --git a/src/graph/validator/test/GetSubgraphValidatorTest.cpp b/src/graph/validator/test/GetSubgraphValidatorTest.cpp index 46d86e1a36e..8eae1c3b757 100644 --- a/src/graph/validator/test/GetSubgraphValidatorTest.cpp +++ b/src/graph/validator/test/GetSubgraphValidatorTest.cpp @@ -21,7 +21,6 @@ TEST_F(GetSubgraphValidatorTest, Base) { { std::string query = "GET SUBGRAPH FROM \"1\" YIELD vertices as nodes"; std::vector expected = { - PK::kProject, PK::kDataCollect, PK::kLoop, PK::kStart, @@ -34,7 +33,6 @@ TEST_F(GetSubgraphValidatorTest, Base) { { std::string query = "GET SUBGRAPH WITH PROP 3 STEPS FROM \"1\" YIELD edges as relationships"; std::vector expected = { - PK::kProject, PK::kDataCollect, PK::kLoop, PK::kStart, @@ -47,7 +45,6 @@ TEST_F(GetSubgraphValidatorTest, Base) { { std::string query = "GET SUBGRAPH WITH PROP FROM \"1\" BOTH like YIELD vertices AS a"; std::vector expected = { - PK::kProject, PK::kDataCollect, PK::kLoop, PK::kStart, @@ -61,7 +58,6 @@ TEST_F(GetSubgraphValidatorTest, Base) { std::string query = "GET SUBGRAPH WITH PROP FROM \"1\", \"2\" IN like YIELD vertices as a, edges as b"; std::vector expected = { - PK::kProject, PK::kDataCollect, PK::kLoop, PK::kStart, @@ -79,7 +75,6 @@ TEST_F(GetSubgraphValidatorTest, Input) { "GO FROM \"1\" OVER like YIELD like._src AS src | GET SUBGRAPH WITH " "PROP FROM $-.src YIELD vertices as a, edges as b"; std::vector expected = { - PK::kProject, PK::kDataCollect, PK::kLoop, PK::kDedup, @@ -98,7 +93,6 @@ TEST_F(GetSubgraphValidatorTest, Input) { "$a = GO FROM \"1\" OVER like YIELD like._src AS src; GET SUBGRAPH " "FROM $a.src YIELD vertices as a, edges as b"; std::vector expected = { - PK::kProject, PK::kDataCollect, PK::kLoop, PK::kDedup, diff --git a/tests/tck/features/subgraph/subgraph.IntVid.feature b/tests/tck/features/subgraph/subgraph.IntVid.feature index fe051ef5dd8..e70c30ae9f1 100644 --- a/tests/tck/features/subgraph/subgraph.IntVid.feature +++ b/tests/tck/features/subgraph/subgraph.IntVid.feature @@ -955,7 +955,6 @@ Feature: Integer Vid subgraph | relationships | | <[edge1]> | | <[edge2]> | - | [] | When executing query: """ GET SUBGRAPH WITH PROP FROM hash('Tony Parker') BOTH like YIELD edges as relationships, vertices as nodes diff --git a/tests/tck/features/subgraph/subgraph.feature b/tests/tck/features/subgraph/subgraph.feature index c90b90017e9..e33ecd62c08 100644 --- a/tests/tck/features/subgraph/subgraph.feature +++ b/tests/tck/features/subgraph/subgraph.feature @@ -955,7 +955,6 @@ Feature: subgraph | b | | <[edge1]> | | <[edge2]> | - | [] | When executing query: """ GET SUBGRAPH WITH PROP FROM 'Tony Parker' BOTH like YIELD edges as a, vertices as b @@ -1033,28 +1032,3 @@ Feature: subgraph Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Tom")] | [] | - | [] | [] | - - Scenario: Get subgraph in a space which doesn't have edge schema - Given an empty graph - And create a space with following options: - | partition_num | 9 | - | replica_factor | 1 | - | vid_type | FIXED_STRING(20) | - And having executed: - """ - CREATE TAG IF NOT EXISTS person(name string); - """ - When try to execute query: - """ - INSERT VERTEX person VALUES "Tom":("Tom") - """ - Then the execution should be successful - When executing query: - """ - GET SUBGRAPH 1 STEPS FROM "Tom" YIELD vertices as nodes, edges as relationships - """ - Then the result should be, in any order, with relax comparison: - | nodes | relationships | - | [("Tom")] | [] | - | [] | [] |