diff --git a/src/graph/context/ast/QueryAstContext.h b/src/graph/context/ast/QueryAstContext.h index c3ab482e1ac..70dea565857 100644 --- a/src/graph/context/ast/QueryAstContext.h +++ b/src/graph/context/ast/QueryAstContext.h @@ -127,10 +127,13 @@ struct SubgraphContext final : public AstContext { struct FetchVerticesContext final : public AstContext { Starts from; - bool distince{false}; + bool distinct{false}; YieldColumns* yieldExpr{nullptr}; ExpressionProps exprProps; std::vector colNames; + + // store the result of the previous sentence + std::string inputVarName; }; } // namespace graph diff --git a/src/graph/planner/ngql/FetchVerticesPlanner.cpp b/src/graph/planner/ngql/FetchVerticesPlanner.cpp index 55f47499e72..33b6f8a65ad 100644 --- a/src/graph/planner/ngql/FetchVerticesPlanner.cpp +++ b/src/graph/planner/ngql/FetchVerticesPlanner.cpp @@ -36,14 +36,19 @@ std::unique_ptr FetchVerticesPlanner::buildVe StatusOr FetchVerticesPlanner::transform(AstContext* astCtx) { fetchCtx_ = static_cast(astCtx); auto qctx = fetchCtx_->qctx; + auto space = fetchCtx_->space; auto& starts = fetchCtx_->from; std::string vidsVar; - if (starts.vids.empty() && starts.originalSrc == nullptr) { + if (!starts.vids.empty() && starts.originalSrc == nullptr) { PlannerUtil::buildConstantInput(qctx, starts, vidsVar); } else { starts.src = starts.originalSrc; - vidsVar = starts.userDefinedVarName; + if (starts.fromType == kVariable) { + vidsVar = starts.userDefinedVarName; + } else { + vidsVar = fetchCtx_->inputVarName; + } } SubPlan subPlan; @@ -59,7 +64,7 @@ StatusOr FetchVerticesPlanner::transform(AstContext* astCtx) { subPlan.root = Project::make(qctx, getVertices, fetchCtx_->yieldExpr); if (fetchCtx_->distinct) { - subPlan.root = Dedup::make(qctx, subPlan.root) + subPlan.root = Dedup::make(qctx, subPlan.root); } subPlan.tail = getVertices; return subPlan; diff --git a/src/graph/planner/ngql/FetchVerticesPlanner.h b/src/graph/planner/ngql/FetchVerticesPlanner.h index c5b8f9ed7d4..b24a7085233 100644 --- a/src/graph/planner/ngql/FetchVerticesPlanner.h +++ b/src/graph/planner/ngql/FetchVerticesPlanner.h @@ -41,3 +41,5 @@ class FetchVerticesPlanner final : public Planner { }; } // namespace graph } // namespace nebula + +#endif // GRAPH_PLANNER_NGQL_FETCH_VERTICES_PLANNER_H diff --git a/src/graph/planner/ngql/GoPlanner.cpp b/src/graph/planner/ngql/GoPlanner.cpp index 98893056ad8..4c1e56dcac8 100644 --- a/src/graph/planner/ngql/GoPlanner.cpp +++ b/src/graph/planner/ngql/GoPlanner.cpp @@ -487,7 +487,7 @@ StatusOr GoPlanner::transform(AstContext* astCtx) { goCtx_->joinInput = goCtx_->from.fromType != FromType::kInstantExpr; goCtx_->joinDst = !goCtx_->exprProps.dstTagProps().empty(); - SubPlan startPlan = Planner::buildStart(qctx, goCtx_->from, goCtx_->vidsVar); + SubPlan startPlan = PlannerUtil::buildStart(qctx, goCtx_->from, goCtx_->vidsVar); auto& steps = goCtx_->steps; if (steps.isMToN()) { diff --git a/src/graph/util/ValidateUtil.cpp b/src/graph/util/ValidateUtil.cpp index cd38cfb87ba..953c7b75ab2 100644 --- a/src/graph/util/ValidateUtil.cpp +++ b/src/graph/util/ValidateUtil.cpp @@ -12,7 +12,7 @@ #include "graph/context/ast/QueryAstContext.h" #include "graph/planner/Planner.h" #include "graph/planner/plan/Query.h" -#include "graph/util/ExpressionUtil.h" +#include "graph/util/ExpressionUtils.h" namespace nebula { namespace graph { @@ -74,7 +74,7 @@ Status ValidateUtil::validateOver(QueryContext* qctx, const OverClause* clause, return Status::OK(); } -Status ValidateUtil::invalidLabelIdentifiers(const Expression* expr) const { +Status ValidateUtil::invalidLabelIdentifiers(const Expression* expr) { auto labelExprs = ExpressionUtils::collectAll(expr, {Expression::Kind::kLabel}); if (!labelExprs.empty()) { std::stringstream ss; diff --git a/src/graph/util/ValidateUtil.h b/src/graph/util/ValidateUtil.h index 312b5da996e..ea532e166ad 100644 --- a/src/graph/util/ValidateUtil.h +++ b/src/graph/util/ValidateUtil.h @@ -7,11 +7,15 @@ #ifndef GRAPH_UTIL_VALIDATE_UTIL_H_ #define GRAPH_UTIL_VALIDATE_UTIL_H_ #include "common/base/Base.h" +#include "common/base/StatusOr.h" +#include "common/expression/Expression.h" +#include "parser/Clauses.h" namespace nebula { namespace graph { class QueryContext; class PlanNode; +struct Over; class ValidateUtil final { public: @@ -21,7 +25,7 @@ class ValidateUtil final { static Status validateOver(QueryContext* qctx, const OverClause* clause, Over& over); - static Status invalidLabelIdentifiers(const Expression* expr) const; + static Status invalidLabelIdentifiers(const Expression* expr); }; } // namespace graph diff --git a/src/graph/validator/FetchEdgesValidator.cpp b/src/graph/validator/FetchEdgesValidator.cpp index 5909e1bbc4a..888b8fb9748 100644 --- a/src/graph/validator/FetchEdgesValidator.cpp +++ b/src/graph/validator/FetchEdgesValidator.cpp @@ -9,6 +9,7 @@ #include "graph/planner/plan/Query.h" #include "graph/util/ExpressionUtils.h" #include "graph/util/SchemaUtil.h" +#include "graph/util/ValidateUtil.h" namespace nebula { namespace graph { @@ -184,7 +185,7 @@ Status FetchEdgesValidator::preparePropertiesWithYield(const YieldClause *yield) dedup_ = newYield_->isDistinct(); for (auto col : newYield_->columns()) { col->setExpr(ExpressionUtils::rewriteLabelAttr2EdgeProp(col->expr())); - NG_RETURN_IF_ERROR(invalidLabelIdentifiers(col->expr())); + NG_RETURN_IF_ERROR(ValidateUtil::invalidLabelIdentifiers(col->expr())); const auto *invalidExpr = findInvalidYieldExpression(col->expr()); if (invalidExpr != nullptr) { return Status::SemanticError("Invalid newYield_ expression `%s'.", diff --git a/src/graph/validator/FetchVerticesValidator.cpp b/src/graph/validator/FetchVerticesValidator.cpp index 277cafaf1b6..9be40b0f040 100644 --- a/src/graph/validator/FetchVerticesValidator.cpp +++ b/src/graph/validator/FetchVerticesValidator.cpp @@ -8,7 +8,7 @@ #include "graph/planner/plan/Query.h" #include "graph/util/ExpressionUtils.h" #include "graph/util/SchemaUtil.h" -#include "graph/util/ValidateUtils.h" +#include "graph/util/ValidateUtil.h" #include "graph/visitor/DeducePropsVisitor.h" namespace nebula { @@ -18,13 +18,16 @@ static constexpr char VertexID[] = "VertexID"; Status FetchVerticesValidator::validateImpl() { auto *fSentence = static_cast(sentence_); + fetchCtx_ = getContext(); + fetchCtx_->inputVarName = inputVarName_; + NG_RETURN_IF_ERROR(validateTag(fSentence->tags())); - NG_RETURN_IF_ERROR(validateStart(fSentence->vertices(), fetchCtx_->from)); + NG_RETURN_IF_ERROR(validateStarts(fSentence->vertices(), fetchCtx_->from)); NG_RETURN_IF_ERROR(validateYield(fSentence->yieldClause())); return Status::OK(); } -Status FetchVerticesValidator::validateTag(NameLabelList *nameLabels) { +Status FetchVerticesValidator::validateTag(const NameLabelList *nameLabels) { if (nameLabels == nullptr) { // all tag const auto &tagStatus = qctx_->schemaMng()->getAllLatestVerTagSchema(space_.id); @@ -34,14 +37,14 @@ Status FetchVerticesValidator::validateTag(NameLabelList *nameLabels) { } } else { auto labels = nameLabels->labels(); - auto &schemaMng = qctx_->schemaMng(); + auto *schemaMng = qctx_->schemaMng(); for (const auto &label : labels) { auto tagStatus = schemaMng->toTagID(space_.id, *label); NG_RETURN_IF_ERROR(tagStatus); auto tagID = tagStatus.value(); auto tagSchema = schemaMng->getTagSchema(space_.id, tagID); if (tagSchema == nullptr) { - return Status::SemanticError("No schema found for `%s'", nameLabel->c_str()); + return Status::SemanticError("No schema found for `%s'", label->c_str()); } tagsSchema_.emplace(tagID, tagSchema); } @@ -51,22 +54,29 @@ Status FetchVerticesValidator::validateTag(NameLabelList *nameLabels) { Status FetchVerticesValidator::validateYield(YieldClause *yield) { auto pool = qctx_->objPool(); + if (yield == nullptr) { + // version 3.0: return Status::SemanticError("No YIELD Clause"); + auto *yieldColumns = new YieldColumns(); + auto *vertex = new YieldColumn(VertexExpression::make(pool)); + yieldColumns->addColumn(vertex); + yield = pool->add(new YieldClause(yieldColumns)); + } fetchCtx_->distinct = yield->isDistinct(); - auto size = yield->columns()->size(); - outputs_.reverse(size + 1); // VertexID + auto size = yield->columns().size(); + outputs_.reserve(size + 1); // VertexID outputs_.emplace_back(VertexID, vidType_); - auto &exprProps = fetctCtx_->exprProps; + auto &exprProps = fetchCtx_->exprProps; for (auto col : yield->columns()) { // yield vertex or id(vertex) - auto colExpr = col->expr(); - col->setExpr(ExpressionUtils::rewriteLabelAttr2TagProp(colExpr)); - NG_RETURN_IF_ERROR(ValidateUtil::invalidLabelIdentifiers(colExpr)); + col->setExpr(ExpressionUtils::rewriteLabelAttr2TagProp(col->expr())); + NG_RETURN_IF_ERROR(ValidateUtil::invalidLabelIdentifiers(col->expr())); + auto colExpr = col->expr(); auto typeStatus = deduceExprType(colExpr); NG_RETURN_IF_ERROR(typeStatus); - ouputs_.emplace_back(col->name(), typeStatus.value()); + outputs_.emplace_back(col->name(), typeStatus.value()); NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps)); } @@ -78,17 +88,17 @@ Status FetchVerticesValidator::validateYield(YieldClause *yield) { return Status::SemanticError("Unsupported src/dst property expression in yield."); } - for (const auto &tag : exprProps.tagNameIds()) { - if (tagsSchema_.find(tag.first) == tagsSchema_.end()) { - return Status::SemanticError("Mismatched tag `%s'", tag); - } - } + // for (const auto &tag : exprProps.tagNameIds()) { + // if (tagsSchema_.find(tag.first) == tagsSchema_.end()) { + // return Status::SemanticError("Mismatched tag `%s'", tag); + // } + // } auto *newCols = pool->add(new YieldColumns()); // TODO (will be deleted in version 3.0) - auto *col = new YieldColumn(InputPropertyExpression::make(pool, nebula::kVid), VertexID); - newCols->addColumn(col); + auto *vidCol = new YieldColumn(InputPropertyExpression::make(pool, nebula::kVid), VertexID); + newCols->addColumn(vidCol); for (const auto &col : yield->columns()) { - newCols->addColumn(col->clone()->release()); + newCols->addColumn(col->clone().release()); } fetchCtx_->yieldExpr = newCols; auto colNames = getOutColNames(); diff --git a/src/graph/validator/FetchVerticesValidator.h b/src/graph/validator/FetchVerticesValidator.h index c90fd166019..fcacaa2578d 100644 --- a/src/graph/validator/FetchVerticesValidator.h +++ b/src/graph/validator/FetchVerticesValidator.h @@ -7,8 +7,9 @@ #ifndef _VALIDATOR_FETCH_VERTICES_VALIDATOR_H_ #define _VALIDATOR_FETCH_VERTICES_VALIDATOR_H_ +#include "graph/context/ast/QueryAstContext.h" #include "graph/validator/Validator.h" -#include "parser/TraverseSentence.h" +#include "parser/TraverseSentences.h" namespace nebula { namespace graph { @@ -21,7 +22,7 @@ class FetchVerticesValidator final : public Validator { private: Status validateImpl() override; - Status validateTag(NameLabelList* nameLables); + Status validateTag(const NameLabelList* nameLables); Status validateYield(YieldClause* yield); diff --git a/src/graph/validator/FindPathValidator.cpp b/src/graph/validator/FindPathValidator.cpp index 9764dce4b25..2f4975149f9 100644 --- a/src/graph/validator/FindPathValidator.cpp +++ b/src/graph/validator/FindPathValidator.cpp @@ -9,6 +9,7 @@ #include "common/expression/VariableExpression.h" #include "graph/planner/plan/Algo.h" #include "graph/planner/plan/Logic.h" +#include "graph/util/ValidateUtil.h" namespace nebula { namespace graph { @@ -22,7 +23,7 @@ Status FindPathValidator::validateImpl() { NG_RETURN_IF_ERROR(validateStarts(fpSentence->from(), pathCtx_->from)); NG_RETURN_IF_ERROR(validateStarts(fpSentence->to(), pathCtx_->to)); - NG_RETURN_IF_ERROR(validateOver(fpSentence->over(), pathCtx_->over)); + NG_RETURN_IF_ERROR(ValidateUtil::validateOver(qctx_, fpSentence->over(), pathCtx_->over)); NG_RETURN_IF_ERROR(validateWhere(fpSentence->where())); NG_RETURN_IF_ERROR(ValidateUtil::validateStep(fpSentence->step(), pathCtx_->steps)); diff --git a/src/graph/validator/FindPathValidator.h b/src/graph/validator/FindPathValidator.h index 2cc367dc197..0f2d03a23ec 100644 --- a/src/graph/validator/FindPathValidator.h +++ b/src/graph/validator/FindPathValidator.h @@ -9,15 +9,14 @@ #include "common/base/Base.h" #include "graph/context/ast/QueryAstContext.h" -#include "graph/validator/TraversalValidator.h" +#include "graph/validator/Validator.h" namespace nebula { namespace graph { -class FindPathValidator final : public TraversalValidator { +class FindPathValidator final : public Validator { public: - FindPathValidator(Sentence* sentence, QueryContext* context) - : TraversalValidator(sentence, context) {} + FindPathValidator(Sentence* sentence, QueryContext* context) : Validator(sentence, context) {} private: Status validateImpl() override; diff --git a/src/graph/validator/GetSubgraphValidator.cpp b/src/graph/validator/GetSubgraphValidator.cpp index 332932a48b1..ad1b6ac576c 100644 --- a/src/graph/validator/GetSubgraphValidator.cpp +++ b/src/graph/validator/GetSubgraphValidator.cpp @@ -14,6 +14,7 @@ #include "graph/context/QueryExpressionContext.h" #include "graph/planner/plan/Logic.h" #include "graph/planner/plan/Query.h" +#include "graph/util/ValidateUtil.h" #include "parser/TraverseSentences.h" namespace nebula { diff --git a/src/graph/validator/GetSubgraphValidator.h b/src/graph/validator/GetSubgraphValidator.h index 140c481178d..2b07970faec 100644 --- a/src/graph/validator/GetSubgraphValidator.h +++ b/src/graph/validator/GetSubgraphValidator.h @@ -8,15 +8,14 @@ #define GRAPH_VALIDATOR_GETSUBGRAPHVALIDATOR_H_ #include "graph/context/ast/QueryAstContext.h" -#include "graph/validator/TraversalValidator.h" +#include "graph/validator/Validator.h" #include "parser/Clauses.h" namespace nebula { namespace graph { -class GetSubgraphValidator final : public TraversalValidator { +class GetSubgraphValidator final : public Validator { public: - GetSubgraphValidator(Sentence* sentence, QueryContext* context) - : TraversalValidator(sentence, context) {} + GetSubgraphValidator(Sentence* sentence, QueryContext* context) : Validator(sentence, context) {} private: Status validateImpl() override; diff --git a/src/graph/validator/GoValidator.cpp b/src/graph/validator/GoValidator.cpp index f77720c183d..ed43b87d03c 100644 --- a/src/graph/validator/GoValidator.cpp +++ b/src/graph/validator/GoValidator.cpp @@ -10,6 +10,7 @@ #include "common/expression/VariableExpression.h" #include "graph/planner/plan/Logic.h" #include "graph/util/ExpressionUtils.h" +#include "graph/util/ValidateUtil.h" #include "graph/visitor/ExtractPropExprVisitor.h" #include "parser/TraverseSentences.h" @@ -22,7 +23,7 @@ Status GoValidator::validateImpl() { NG_RETURN_IF_ERROR(ValidateUtil::validateStep(goSentence->stepClause(), goCtx_->steps)); NG_RETURN_IF_ERROR(validateStarts(goSentence->fromClause(), goCtx_->from)); - NG_RETURN_IF_ERROR(validateOver(goSentence->overClause(), goCtx_->over)); + NG_RETURN_IF_ERROR(ValidateUtil::validateOver(qctx_, goSentence->overClause(), goCtx_->over)); NG_RETURN_IF_ERROR(validateWhere(goSentence->whereClause())); NG_RETURN_IF_ERROR(validateYield(goSentence->yieldClause())); NG_RETURN_IF_ERROR(validateTruncate(goSentence->truncateClause())); diff --git a/src/graph/validator/GoValidator.h b/src/graph/validator/GoValidator.h index 140bf92530c..e2f97866b17 100644 --- a/src/graph/validator/GoValidator.h +++ b/src/graph/validator/GoValidator.h @@ -9,16 +9,16 @@ #include "graph/context/ast/QueryAstContext.h" #include "graph/planner/plan/Query.h" -#include "graph/validator/TraversalValidator.h" +#include "graph/validator/Validator.h" namespace nebula { namespace graph { -class GoValidator final : public TraversalValidator { +class GoValidator final : public Validator { public: using VertexProp = nebula::storage::cpp2::VertexProp; using EdgeProp = nebula::storage::cpp2::EdgeProp; - GoValidator(Sentence* sentence, QueryContext* context) : TraversalValidator(sentence, context) {} + GoValidator(Sentence* sentence, QueryContext* context) : Validator(sentence, context) {} private: Status validateImpl() override; diff --git a/src/graph/validator/MatchValidator.cpp b/src/graph/validator/MatchValidator.cpp index 4d8823e6a33..d6f969cbdb4 100644 --- a/src/graph/validator/MatchValidator.cpp +++ b/src/graph/validator/MatchValidator.cpp @@ -13,7 +13,7 @@ namespace nebula { namespace graph { MatchValidator::MatchValidator(Sentence *sentence, QueryContext *context) - : TraversalValidator(sentence, context) { + : Validator(sentence, context) { matchCtx_ = getContext(); } diff --git a/src/graph/validator/MatchValidator.h b/src/graph/validator/MatchValidator.h index 997744b2107..762589a2dc8 100644 --- a/src/graph/validator/MatchValidator.h +++ b/src/graph/validator/MatchValidator.h @@ -11,14 +11,14 @@ #include "graph/context/ast/CypherAstContext.h" #include "graph/planner/plan/Query.h" #include "graph/util/AnonVarGenerator.h" -#include "graph/validator/TraversalValidator.h" +#include "graph/validator/Validator.h" namespace nebula { class MatchStepRange; class ObjectPool; namespace graph { -class MatchValidator final : public TraversalValidator { +class MatchValidator final : public Validator { public: MatchValidator(Sentence *sentence, QueryContext *context); diff --git a/src/graph/validator/Validator.cpp b/src/graph/validator/Validator.cpp index 8b33525f542..135e161a6f7 100644 --- a/src/graph/validator/Validator.cpp +++ b/src/graph/validator/Validator.cpp @@ -6,6 +6,8 @@ #include "graph/validator/Validator.h" +#include + #include "common/function/FunctionManager.h" #include "graph/planner/plan/Query.h" #include "graph/util/ExpressionUtils.h" diff --git a/src/graph/validator/Validator.h b/src/graph/validator/Validator.h index 2d7d6379b44..3b204af51ab 100644 --- a/src/graph/validator/Validator.h +++ b/src/graph/validator/Validator.h @@ -19,7 +19,7 @@ namespace nebula { namespace graph { - +struct Starts; class Validator { public: virtual ~Validator() = default; @@ -127,14 +127,12 @@ class Validator { return Status::OK(); } - // Check the variable or input property reference - // return the input variable - StatusOr checkRef(const Expression* ref, const Value::Type type); - // Check the output for duplicate column names Status checkDuplicateColName(); - Status invalidLabelIdentifiers(const Expression* expr) const; + // Check the variable or input property reference + // return the input variable + StatusOr checkRef(const Expression* ref, const Value::Type type); Status validateStarts(const VerticesClause* clause, Starts& starts); diff --git a/src/graph/validator/YieldValidator.cpp b/src/graph/validator/YieldValidator.cpp index 73682d89078..e36c57f9271 100644 --- a/src/graph/validator/YieldValidator.cpp +++ b/src/graph/validator/YieldValidator.cpp @@ -10,6 +10,7 @@ #include "graph/context/QueryContext.h" #include "graph/planner/plan/Query.h" #include "graph/util/ExpressionUtils.h" +#include "graph/util/ValidateUtil.h" #include "parser/Clauses.h" #include "parser/TraverseSentences.h" diff --git a/src/graph/validator/test/FetchVerticesTest.cpp b/src/graph/validator/test/FetchVerticesTest.cpp index d574882b93c..ac2a210ddcd 100644 --- a/src/graph/validator/test/FetchVerticesTest.cpp +++ b/src/graph/validator/test/FetchVerticesTest.cpp @@ -40,9 +40,9 @@ TEST_F(FetchVerticesValidatorTest, FetchVerticesProp) { gv->setColNames({nebula::kVid, "person.name", "person.age"}); // project auto yieldColumns = std::make_unique(); - yieldColumns->addColumn(new YieldColumn(VertexExpression::make(pool), "vertices_")); + yieldColumns->addColumn(new YieldColumn(VertexExpression::make(pool), "VERTEX")); auto *project = Project::make(qctx, gv, yieldColumns.get()); - project->setColNames({"vertices_"}); + project->setColNames({"VERTEX"}); auto result = Eq(qctx->plan()->root(), project); ASSERT_TRUE(result.ok()) << result; }