diff --git a/src/common/expression/LabelTagPropertyExpression.cpp b/src/common/expression/LabelTagPropertyExpression.cpp index 525d4ace018..aebc61425d5 100644 --- a/src/common/expression/LabelTagPropertyExpression.cpp +++ b/src/common/expression/LabelTagPropertyExpression.cpp @@ -1,7 +1,6 @@ /* 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. + * This source code is licensed under Apache 2.0 License. */ #include "common/expression/LabelTagPropertyExpression.h" @@ -10,7 +9,7 @@ namespace nebula { const Value& LabelTagPropertyExpression::eval(ExpressionContext& ctx) { - const auto& var = ctx.getVar(label_); + const auto& var = label_->eval(ctx); if (var.type() != Value::Type::VERTEX) { return Value::kNullBadType; } @@ -26,7 +25,8 @@ const Value& LabelTagPropertyExpression::eval(ExpressionContext& ctx) { } std::string LabelTagPropertyExpression::toString() const { - return label_ + "." + tag_ + "." + prop_; + std::string labelStr = label_->toString(); + return labelStr.erase(0, 1) + "." + tag_ + "." + prop_; } bool LabelTagPropertyExpression::operator==(const Expression& rhs) const { @@ -34,18 +34,18 @@ bool LabelTagPropertyExpression::operator==(const Expression& rhs) const { return false; } const auto& expr = static_cast(rhs); - return label_ == expr.label_ && tag_ == expr.tag_ && prop_ == expr.prop_; + return *label_ == *expr.label_ && tag_ == expr.tag_ && prop_ == expr.prop_; } void LabelTagPropertyExpression::writeTo(Encoder& encoder) const { encoder << kind_; - encoder << label_; + encoder << *label_; encoder << tag_; encoder << prop_; } void LabelTagPropertyExpression::resetFrom(Decoder& decoder) { - label_ = decoder.readStr(); + label_ = decoder.readExpression(pool_); tag_ = decoder.readStr(); prop_ = decoder.readStr(); } diff --git a/src/common/expression/LabelTagPropertyExpression.h b/src/common/expression/LabelTagPropertyExpression.h index 14d66f1c78b..b546a8f20ad 100644 --- a/src/common/expression/LabelTagPropertyExpression.h +++ b/src/common/expression/LabelTagPropertyExpression.h @@ -1,7 +1,6 @@ /* 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. + * This source code is licensed under Apache 2.0 License. */ #pragma once @@ -22,7 +21,7 @@ class LabelTagPropertyExpression final : public Expression { LabelTagPropertyExpression& operator=(LabelTagPropertyExpression&&) = delete; static LabelTagPropertyExpression* make(ObjectPool* pool, - const std::string& label = "", + Expression* label = nullptr, const std::string& tag = "", const std::string& prop = "") { return pool->add(new LabelTagPropertyExpression(pool, label, tag, prop)); @@ -44,11 +43,11 @@ class LabelTagPropertyExpression final : public Expression { const std::string& tag() const { return tag_; } - const std::string& label() const { return label_; } + const Expression* label() const { return label_; } private: LabelTagPropertyExpression(ObjectPool* pool, - const std::string& label = "", + Expression* label = nullptr, const std::string& tag = "", const std::string& prop = "") : Expression(pool, Kind::kLabelTagProperty), label_(label), tag_(tag), prop_(prop) {} @@ -57,7 +56,7 @@ class LabelTagPropertyExpression final : public Expression { void resetFrom(Decoder& decoder) override; private: - std::string label_; + Expression* label_{nullptr}; std::string tag_; std::string prop_; }; diff --git a/src/graph/util/ExpressionUtils.cpp b/src/graph/util/ExpressionUtils.cpp index 8302b92543d..effd5c54870 100644 --- a/src/graph/util/ExpressionUtils.cpp +++ b/src/graph/util/ExpressionUtils.cpp @@ -114,7 +114,7 @@ Expression *ExpressionUtils::rewriteAttr2LabelTagProp(const Expression *expr) { if (e->kind() == Expression::Kind::kAttribute) { auto attrExpr = static_cast(e); if (attrExpr->left()->kind() == Expression::Kind::kLabelAttribute && - attrExpr->right()->kind() == Expression::Kind::kLabel) { + attrExpr->right()->kind() == Expression::Kind::kConstant) { return true; } } @@ -128,10 +128,11 @@ Expression *ExpressionUtils::rewriteAttr2LabelTagProp(const Expression *expr) { auto tagExpr = const_cast(labelAttrExpr->right()); auto propExpr = static_cast(attrExpr->right()); QueryExpressionContext ctx(nullptr); - const auto &label = labelExpr->eval(ctx); + const auto &labelVal = labelExpr->eval(ctx); + auto label = VariablePropertyExpression::make(pool, "", labelVal.getStr()); const auto &tag = tagExpr->eval(ctx); const auto &prop = const_cast(propExpr)->eval(ctx); - return LabelTagPropertyExpression::make(pool, label.getStr(), tag.getStr(), prop.getStr()); + return LabelTagPropertyExpression::make(pool, label, tag.getStr(), prop.getStr()); }; return RewriteVisitor::transform(expr, std::move(matcher), std::move(rewriter)); diff --git a/src/graph/validator/MatchValidator.cpp b/src/graph/validator/MatchValidator.cpp index 6dcc41acae1..efc3a322ebe 100644 --- a/src/graph/validator/MatchValidator.cpp +++ b/src/graph/validator/MatchValidator.cpp @@ -349,7 +349,9 @@ Status MatchValidator::validateReturn(MatchReturn *ret, return Status::SemanticError("RETURN * is not allowed when there are no variables in scope"); } } + std::vector exprs; if (ret->returnItems()->columns()) { + exprs.reserve(ret->returnItems()->columns()->size()); for (auto *column : ret->returnItems()->columns()->columns()) { if (ExpressionUtils::hasAny(column->expr(), {Expression::Kind::kVertex, Expression::Kind::kEdge})) { @@ -357,22 +359,18 @@ Status MatchValidator::validateReturn(MatchReturn *ret, "keywords: vertex and edge are not supported in return clause `%s'", column->toString().c_str()); } + if (!retClauseCtx.yield->hasAgg_ && + ExpressionUtils::hasAny(column->expr(), {Expression::Kind::kAggregate})) { + retClauseCtx.yield->hasAgg_ = true; + } + column->setExpr(ExpressionUtils::rewriteAttr2LabelTagProp(column->expr())); + exprs.push_back(column->expr()); columns->addColumn(column->clone().release()); } } DCHECK(!columns->empty()); retClauseCtx.yield->yieldColumns = columns; - // Check all referencing expressions are valid - std::vector exprs; - exprs.reserve(retClauseCtx.yield->yieldColumns->size()); - for (auto *col : retClauseCtx.yield->yieldColumns->columns()) { - if (!retClauseCtx.yield->hasAgg_ && - ExpressionUtils::hasAny(col->expr(), {Expression::Kind::kAggregate})) { - retClauseCtx.yield->hasAgg_ = true; - } - exprs.push_back(col->expr()); - } NG_RETURN_IF_ERROR(validateAliases(exprs, retClauseCtx.yield->aliasesUsed)); NG_RETURN_IF_ERROR(validateYield(*retClauseCtx.yield)); @@ -772,11 +770,12 @@ Status MatchValidator::checkAlias( return Status::OK(); } case Expression::Kind::kLabelTagProperty: { - auto name = static_cast(refExpr)->label(); + auto labelExpr = static_cast(refExpr)->label(); + auto name = static_cast(labelExpr)->prop(); auto res = getAliasType(aliasesUsed, name); NG_RETURN_IF_ERROR(res); if (res.value() != AliasType::kNode) { - return Status::SemanticError("Alias: %s 's type must be vertex", name.c_str()); + return Status::SemanticError("The type of `%s' must be tag", name.c_str()); } return Status::OK(); }