Skip to content

Commit

Permalink
fix error
Browse files Browse the repository at this point in the history
  • Loading branch information
nevermore3 committed Sep 24, 2021
1 parent a617d84 commit ef94fd8
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 47 deletions.
2 changes: 1 addition & 1 deletion src/graph/context/ast/QueryAstContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ struct FetchEdgesContext final : public AstContext {

ExpressionProps exprProps;
YieldColumns* yieldExpr{nullptr};

std::string edgeName;
bool distinct{false};
// store the result of the previous sentence
std::string inputVarName;
Expand Down
28 changes: 20 additions & 8 deletions src/graph/planner/ngql/FetchEdgesPlanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,12 @@
*/

#include "graph/planner/ngql/FetchEdgesPlanner.h"

#include "graph/util/ExpressionUtils.h"
#include "graph/util/QueryUtil.h"
#include "graph/util/SchemaUtil.h"
#include "graph/validator/Validator.h"

namespace nebula {
namespace graph {

std::unique_ptr<FetchEdgesPlanner::EdgeProps> FetchEdgesPlanner::buildEdgeProps() {
auto eProps = std::make_unique<EdgeProps>();
auto edgePropsMap = fetchCtx_->exprProps.edgeProps();
const auto &edgePropsMap = fetchCtx_->exprProps.edgeProps();
for (const auto &edgeProp : edgePropsMap) {
EdgeProp ep;
ep.set_type(edgeProp.first);
Expand All @@ -26,6 +20,22 @@ std::unique_ptr<FetchEdgesPlanner::EdgeProps> FetchEdgesPlanner::buildEdgeProps(
return eProps;
}

Expression *FetchEdgesPlanner::emptyEdgeFilter() {
auto *pool = fetchCtx_->qctx->objPool();
const auto &edgeName = fetchCtx_->edgeName;
auto notEmpty = [&pool](Expression *expr) {
return RelationalExpression::makeNE(pool, ConstantExpression::make(pool, Value::kEmpty), expr);
};
auto exprAnd = [&pool](Expression *left, Expression *right) {
return LogicalExpression::makeAnd(pool, left, right);
};

auto *srcNotEmpty = notEmpty(EdgeSrcIdExpression::make(pool, edgeName));
auto *dstNotEmpty = notEmpty(EdgeDstIdExpression::make(pool, edgeName));
auto *rankNotEmpty = notEmpty(EdgeRankExpression::make(pool, edgeName));
return exprAnd(srcNotEmpty, exprAnd(dstNotEmpty, rankNotEmpty));
}

StatusOr<SubPlan> FetchEdgesPlanner::transform(AstContext *astCtx) {
fetchCtx_ = static_cast<FetchEdgesContext *>(astCtx);
auto qctx = fetchCtx_->qctx;
Expand All @@ -44,7 +54,9 @@ StatusOr<SubPlan> FetchEdgesPlanner::transform(AstContext *astCtx) {
fetchCtx_->distinct);
getEdges->setInputVar(fetchCtx_->inputVarName);

subPlan.root = Project::make(qctx, getEdges, fetchCtx_->yieldExpr);
subPlan.root = Filter::make(qctx, getEdges, emptyEdgeFilter());

subPlan.root = Project::make(qctx, subPlan.root, fetchCtx_->yieldExpr);
if (fetchCtx_->distinct) {
subPlan.root = Dedup::make(qctx, subPlan.root);
}
Expand Down
2 changes: 2 additions & 0 deletions src/graph/planner/ngql/FetchEdgesPlanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class FetchEdgesPlanner final : public Planner {

std::unique_ptr<EdgeProps> buildEdgeProps();

Expression* emptyEdgeFilter();

private:
FetchEdgesPlanner() = default;

Expand Down
62 changes: 37 additions & 25 deletions src/graph/validator/FetchEdgesValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ namespace nebula {
namespace graph {

Status FetchEdgesValidator::validateImpl() {
auto *fsentence = static_cast<FetchEdgesSentence *>(sentence_);
edgeName_ = fsentence->edgeName();
auto *sentence = static_cast<FetchEdgesSentence *>(sentence_);
if (sentence->edgeSize() != 1) {
return Status::SemanticError("only allow fetch on one edge");
}
edgeName_ = sentence->edgeName();
fetchCtx_->edgeName = edgeName_;
fetchCtx_ = getContext<FetchEdgesContext>();
NG_RETURN_IF_ERROR(validateEdgeName());
NG_RETURN_IF_ERROR(validateEdgeKey());
NG_RETURN_IF_ERROR(validateYield(fsentence->yieldClause()));
NG_RETURN_IF_ERROR(validateYield(sentence->yieldClause()));
return Status::OK();
}

Expand All @@ -40,7 +44,7 @@ StatusOr<std::string> FetchEdgesValidator::validateEdgeRef(const Expression *exp
Value::Type type) {
const auto &kind = expr->kind();
if (kind != Expression::Kind::kInputProperty && kind != EdgeExpression::Kind::kVarProperty) {
return Status::SemanticError("`%s', Only input and variable expression is acceptable",
return Status::SemanticError("`%s', only input and variable expression is acceptable",
expr->toString().c_str());
}
auto exprType = deduceExprType(expr);
Expand Down Expand Up @@ -74,15 +78,19 @@ Status FetchEdgesValidator::validateEdgeKey() {
result = validateEdgeRef(rankExpr, Value::Type::INT);
NG_RETURN_IF_ERROR(result);
if (inputVarName != result.value()) {
return Status::SemanticError("Can't refer to different variable as key at same time.");
return Status::SemanticError(
"`%s' the src dst and rank of the edge must use the same reference.",
rankExpr->toString().c_str());
}
}

auto *dstExpr = sentence->ref()->dstid();
result = validateEdgeRef(dstExpr, vidType_);
NG_RETURN_IF_ERROR(result);
if (inputVarName != result.value()) {
return Status::SemanticError("Can't refer to different variable as key at same time.");
return Status::SemanticError(
"`%s' the src dst and rank of the edge must use the same reference.",
dstExpr->toString().c_str());
}
fetchCtx_->src = srcExpr;
fetchCtx_->dst = dstExpr;
Expand All @@ -107,6 +115,7 @@ Status FetchEdgesValidator::validateEdgeKey() {
return Status::SemanticError(ss.str());
}
auto ranking = key->rank();

if (!evaluableExpr(key->dstid())) {
return Status::SemanticError("`%s' is not evaluable.", key->dstid()->toString().c_str());
}
Expand Down Expand Up @@ -142,29 +151,20 @@ void FetchEdgesValidator::extractEdgeProp(ExpressionProps &exprProps) {

Status FetchEdgesValidator::validateYield(const YieldClause *yield) {
auto pool = qctx_->objPool();
fetchCtx_->distinct = yield->isDistinct();
bool existEdge = false;
bool noYield = false;
if (yield == nullptr) {
// TODO: compatible with previous version, this will be deprecated in version 3.0.
auto *yieldColumns = new YieldColumns();
auto *edge = new YieldColumn(EdgeExpression::make(pool));
auto *edge = new YieldColumn(EdgeExpression::make(pool), "edges_");
yieldColumns->addColumn(edge);
yield = pool->add(new YieldClause(yieldColumns));
existEdge = true;
}
for (const auto &col : yield->columns()) {
if (col->expr()->kind() == Expression::Kind::kEdge) {
existEdge = true;
break;
}
// TODO return error when yield vertex
noYield = true;
}
auto size = yield->columns().size();
outputs_.reserve(size + 3);
fetchCtx_->distinct = yield->isDistinct();

ExpressionProps exprProps;
auto &exprProps = fetchCtx_->exprProps;
auto *newCols = pool->add(new YieldColumns());
if (!existEdge) {
if (!noYield) {
auto *src = new YieldColumn(EdgeSrcIdExpression::make(pool, edgeName_));
auto *dst = new YieldColumn(EdgeDstIdExpression::make(pool, edgeName_));
auto *rank = new YieldColumn(EdgeRankExpression::make(pool, edgeName_));
Expand All @@ -177,18 +177,30 @@ Status FetchEdgesValidator::validateYield(const YieldClause *yield) {
exprProps.insertEdgeProp(edgeType_, kSrc);
exprProps.insertEdgeProp(edgeType_, kDst);
exprProps.insertEdgeProp(edgeType_, kRank);
} else {
extractEdgeProp(exprProps);
}

for (const auto &col : yield->columns()) {
if (ExpressionUtils::hasAny(col->expr(), {Expression::Kind::kEdge})) {
extractEdgeProp(exprProps);
break;
}
}
auto size = yield->columns().size();
outputs_.reserve(size + 3);

for (auto col : yield->columns()) {
if (ExpressionUtils::hasAny(col->expr(),
{Expression::Kind::kVertex, Expression::Kind::kPathBuild})) {
return Status::SemanticError("illegal yield clauses `%s'", col->toString().c_str());
}
col->setExpr(ExpressionUtils::rewriteLabelAttr2EdgeProp(col->expr()));
NG_RETURN_IF_ERROR(ValidateUtil::invalidLabelIdentifiers(col->expr()));

auto colExpr = col->expr();
auto typeStatus = deduceExprType(colExpr);
NG_RETURN_IF_ERROR(typeStatus);
outputs_.emplace_back(col->name(), typeStatus.value());
newCols->addColumn(col->clone().release());

NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps));
}
Expand All @@ -203,10 +215,10 @@ Status FetchEdgesValidator::validateYield(const YieldClause *yield) {

for (const auto &edge : exprProps.edgeProps()) {
if (edge.first != edgeType_) {
return Status::SemanticError("MisMatch edge name");
return Status::SemanticError("should use edge name `%s'", edgeName_.c_str());
}
}

fetchCtx_->yieldExpr = newCols;
return Status::OK();
}

Expand Down
2 changes: 2 additions & 0 deletions src/graph/validator/FetchEdgesValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class FetchEdgesValidator final : public Validator {

Status validateYield(const YieldClause* yieldClause);

AstContext* getAstContext() override { return fetchCtx_.get(); }

private:
std::string edgeName_;

Expand Down
14 changes: 8 additions & 6 deletions src/parser/TraverseSentences.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,16 +261,16 @@ class FetchVerticesSentence final : public Sentence {

class FetchEdgesSentence final : public Sentence {
public:
FetchEdgesSentence(const std::string& edgeName, EdgeKeys* keys, YieldClause* clause) {
FetchEdgesSentence(NameLabelList* edge, EdgeKeys* keys, YieldClause* clause) {
kind_ = Kind::kFetchEdges;
edgeName_ = edgeName;
edge_.reset(edge);
edgeKeys_.reset(keys);
yieldClause_.reset(clause);
}

FetchEdgesSentence(const std::string& edgeName, EdgeKeyRef* ref, YieldClause* clause) {
FetchEdgesSentence(NameLabelList* edge, EdgeKeyRef* ref, YieldClause* clause) {
kind_ = Kind::kFetchEdges;
edgeName_ = edgeName;
edge_.reset(edge);
keyRef_.reset(ref);
yieldClause_.reset(clause);
}
Expand All @@ -289,12 +289,14 @@ class FetchEdgesSentence final : public Sentence {

YieldClause* yieldClause() const { return yieldClause_.get(); }

std::string edgeName() const { return edgeName_; }
std::string edgeName() const { return *edge_->front(); }

std::size_t edgeSize() const { return edge_->size(); }

std::string toString() const override;

private:
std::string edgeName_;
std::unique_ptr<NameLabelList> edge_;
std::unique_ptr<EdgeKeys> edgeKeys_;
std::unique_ptr<EdgeKeyRef> keyRef_;
std::unique_ptr<YieldClause> yieldClause_;
Expand Down
10 changes: 4 additions & 6 deletions src/parser/parser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -1985,14 +1985,12 @@ edge_key_ref
;

fetch_edges_sentence
: KW_FETCH KW_PROP KW_ON name_label edge_keys yield_clause {
auto fetch = new FetchEdgesSentence(*$4, $5, $6);
delete $4;
: KW_FETCH KW_PROP KW_ON name_label_list edge_keys yield_clause {
auto fetch = new FetchEdgesSentence($4, $5, $6);
$$ = fetch;
}
| KW_FETCH KW_PROP KW_ON name_label edge_key_ref yield_clause {
auto fetch = new FetchEdgesSentence(*$4, $5, $6);
delete $4;
| KW_FETCH KW_PROP KW_ON name_label_list edge_key_ref yield_clause {
auto fetch = new FetchEdgesSentence($4, $5, $6);
$$ = fetch;
}
;
Expand Down
1 change: 1 addition & 0 deletions tests/tck/features/delete/DeleteEdge.IntVid.feature
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# This source code is licensed under Apache 2.0 License,
# attached with Common Clause Condition 1.0, found in the LICENSES directory.
@jmq
Feature: Delete int vid of edge

Scenario: delete edges
Expand Down
1 change: 0 additions & 1 deletion tests/tck/features/delete/DeleteTag.IntVid.feature
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#
# This source code is licensed under Apache 2.0 License,
# attached with Common Clause Condition 1.0, found in the LICENSES directory.
@jmq
Feature: Delete int vid of tag

Scenario: delete int vid one vertex one tag
Expand Down
1 change: 1 addition & 0 deletions tests/tck/features/fetch/FetchEdges.strVid.feature
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@jmq
Feature: Fetch String Vid Edges

Background:
Expand Down

0 comments on commit ef94fd8

Please sign in to comment.