diff --git a/src/graph/optimizer/rule/CollapseProjectRule.cpp b/src/graph/optimizer/rule/CollapseProjectRule.cpp index 1b44c387068..31785a25477 100644 --- a/src/graph/optimizer/rule/CollapseProjectRule.cpp +++ b/src/graph/optimizer/rule/CollapseProjectRule.cpp @@ -48,6 +48,10 @@ StatusOr CollapseProjectRule::transform( // 1. collect all property reference std::vector allPropRefNames; for (auto col : colsAbove) { + if (graph::ExpressionUtils::findAny( + col->expr(), {Expression::Kind::kVar, Expression::Kind::kVersionedVar}) != nullptr) { + return TransformResult::noTransform(); + } std::vector propRefs = graph::ExpressionUtils::collectAll( col->expr(), {Expression::Kind::kVarProperty, Expression::Kind::kInputProperty}); for (auto* expr : propRefs) { diff --git a/src/graph/validator/YieldValidator.cpp b/src/graph/validator/YieldValidator.cpp index 7476c096735..3023ca29076 100644 --- a/src/graph/validator/YieldValidator.cpp +++ b/src/graph/validator/YieldValidator.cpp @@ -37,22 +37,20 @@ Status YieldValidator::validateImpl() { if (!exprProps_.srcTagProps().empty() || !exprProps_.dstTagProps().empty() || !exprProps_.edgeProps().empty()) { - return Status::SemanticError("Only support input and variable in yield sentence."); + return Status::SemanticError("Not support vertex/edge property expression in yield sentence."); } - if (!exprProps_.inputProps().empty() && !exprProps_.varProps().empty()) { + if (!exprProps_.inputProps().empty() && !userDefinedVarNameList_.empty()) { return Status::SemanticError("Not support both input and variable."); } - if (!exprProps_.varProps().empty() && exprProps_.varProps().size() > 1) { - return Status::SemanticError("Only one variable allowed to use."); + if (userDefinedVarNameList_.size() > 1) { + // Now disable yield multiple user defined input for that means implicit dataset join + // As the inner variable take care don't make it a dataset + return Status::SemanticError("Multiple variables not supported yet."); } - if (!exprProps_.varProps().empty() && !userDefinedVarNameList_.empty()) { - // TODO: Support Multiple userDefinedVars - if (userDefinedVarNameList_.size() != 1) { - return Status::SemanticError("Multiple user defined vars not supported yet."); - } + if (!userDefinedVarNameList_.empty()) { userDefinedVarName_ = *userDefinedVarNameList_.begin(); } diff --git a/src/graph/validator/test/YieldValidatorTest.cpp b/src/graph/validator/test/YieldValidatorTest.cpp index 4e6c2ce6713..6a78da19d0d 100644 --- a/src/graph/validator/test/YieldValidatorTest.cpp +++ b/src/graph/validator/test/YieldValidatorTest.cpp @@ -436,7 +436,8 @@ TEST_F(YieldValidatorTest, Error) { // Not support reference two different variable auto query = var + "YIELD $var.name WHERE $var1.start > 2005"; auto result = checkResult(query); - EXPECT_EQ(std::string(result.message()), "SemanticError: Only one variable allowed to use."); + EXPECT_EQ(std::string(result.message()), + "SemanticError: Multiple variables not supported yet."); } { // Reference a non-existed prop is meaningless. @@ -453,13 +454,13 @@ TEST_F(YieldValidatorTest, Error) { auto query = var + "YIELD $$.person.name"; auto result = checkResult(query); EXPECT_EQ(std::string(result.message()), - "SemanticError: Only support input and variable in yield sentence."); + "SemanticError: Not support vertex/edge property expression in yield sentence."); } { auto query = var + "YIELD $^.person.name"; auto result = checkResult(query); EXPECT_EQ(std::string(result.message()), - "SemanticError: Only support input and variable in yield sentence."); + "SemanticError: Not support vertex/edge property expression in yield sentence."); } { auto query = var + "YIELD like.start"; diff --git a/src/graph/visitor/DeducePropsVisitor.cpp b/src/graph/visitor/DeducePropsVisitor.cpp index 10bed3fb1bd..4eb479ee89c 100644 --- a/src/graph/visitor/DeducePropsVisitor.cpp +++ b/src/graph/visitor/DeducePropsVisitor.cpp @@ -137,7 +137,10 @@ void DeducePropsVisitor::visit(InputPropertyExpression *expr) { void DeducePropsVisitor::visit(VariablePropertyExpression *expr) { exprProps_->insertVarProp(expr->sym(), expr->prop()); - userDefinedVarNameList_->emplace(expr->sym()); + if (expr->sym()[0] != '_') { + // exclude inner generated variable + userDefinedVarNameList_->emplace(expr->sym()); + } } void DeducePropsVisitor::visit(DestPropertyExpression *expr) { @@ -168,7 +171,12 @@ void DeducePropsVisitor::visit(EdgeDstIdExpression *expr) { visitEdgePropExpr(ex void DeducePropsVisitor::visit(UUIDExpression *expr) { reportError(expr); } -void DeducePropsVisitor::visit(VariableExpression *expr) { UNUSED(expr); } +void DeducePropsVisitor::visit(VariableExpression *expr) { + if (expr->var()[0] != '_') { + // exclude inner generated variable + userDefinedVarNameList_->emplace(expr->var()); + } +} void DeducePropsVisitor::visit(VersionedVariableExpression *expr) { reportError(expr); } diff --git a/tests/tck/features/bugfix/YieldVar.feature b/tests/tck/features/bugfix/YieldVar.feature new file mode 100644 index 00000000000..ff425ed06cf --- /dev/null +++ b/tests/tck/features/bugfix/YieldVar.feature @@ -0,0 +1,19 @@ +# Copyright (c) 2021 vesoft inc. All rights reserved. +# +# This source code is licensed under Apache 2.0 License, +# attached with Common Clause Condition 1.0, found in the LICENSES directory. +Feature: Test yield var + + Background: + Given a graph with space named "nba" + + # #2646 + Scenario: yield constant after pipe + When executing query: + """ + $var = GO FROM "Tim Duncan" OVER like YIELD like._dst; YIELD $var[0][0] as var00; + """ + Then the result should be, in any order: + | var00 | + | "Manu Ginobili" | + | "Manu Ginobili" | diff --git a/tests/tck/features/yield/yield.IntVid.feature b/tests/tck/features/yield/yield.IntVid.feature index e00a0c10284..54fd4b2873a 100644 --- a/tests/tck/features/yield/yield.IntVid.feature +++ b/tests/tck/features/yield/yield.IntVid.feature @@ -288,7 +288,7 @@ Feature: Yield Sentence """ $var = GO FROM hash("Boris Diaw") OVER serve YIELD $^.player.name AS name, serve.start_year AS start, $$.team.name AS team;YIELD $var.team WHERE $var1.start > 2005 """ - Then a SemanticError should be raised at runtime: Only one variable allowed to use. + Then a SemanticError should be raised at runtime: Multiple variables not supported yet. When executing query: """ $var = GO FROM hash("Boris Diaw") OVER serve YIELD $^.player.name AS name, serve.start_year AS start, $$.team.name AS team;YIELD $var.abc diff --git a/tests/tck/features/yield/yield.feature b/tests/tck/features/yield/yield.feature index 01ca33e0b6a..7d1a532a07c 100644 --- a/tests/tck/features/yield/yield.feature +++ b/tests/tck/features/yield/yield.feature @@ -298,7 +298,7 @@ Feature: Yield Sentence """ $var = GO FROM "Boris Diaw" OVER serve YIELD $^.player.name AS name, serve.start_year AS start, $$.team.name AS team;YIELD $var.team WHERE $var1.start > 2005 """ - Then a SemanticError should be raised at runtime: Only one variable allowed to use. + Then a SemanticError should be raised at runtime: Multiple variables not supported yet. When executing query: """ $var = GO FROM "Boris Diaw" OVER serve YIELD $^.player.name AS name, serve.start_year AS start, $$.team.name AS team;YIELD $var.abc