Skip to content

Commit

Permalink
format go yield (#2944)
Browse files Browse the repository at this point in the history
* add go yield edge, vertex

* rewriteVertex & Edge to VarProp

* change inner colname

* remove KW_DSTV & KW_SRCV, use  & 35000 instead

* add ci test case

* add gtest case

* change VertexExpresion interface

* address comment

* address comment
  • Loading branch information
nevermore3 authored Sep 30, 2021
1 parent dd2a7d2 commit 8450ba9
Show file tree
Hide file tree
Showing 24 changed files with 2,025 additions and 60 deletions.
2 changes: 1 addition & 1 deletion src/common/context/ExpressionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class ExpressionContext {
virtual const Value& getInputProp(const std::string& prop) const = 0;

// Get Vertex
virtual Value getVertex() const = 0;
virtual Value getVertex(const std::string& name = "") const = 0;

// Get Edge
virtual Value getEdge() const = 0;
Expand Down
27 changes: 24 additions & 3 deletions src/common/expression/VertexExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,32 @@

namespace nebula {

const Value &VertexExpression::eval(ExpressionContext &ctx) {
result_ = ctx.getVertex();
const Value& VertexExpression::eval(ExpressionContext& ctx) {
result_ = ctx.getVertex(name_);
return result_;
}

void VertexExpression::accept(ExprVisitor *visitor) { visitor->visit(this); }
bool VertexExpression::operator==(const Expression& rhs) const {
if (kind_ != rhs.kind()) {
return false;
}
const auto& expr = static_cast<const VertexExpression&>(rhs);
return name_ == expr.name();
}

void VertexExpression::writeTo(Encoder& encoder) const {
// kind_
encoder << kind_;

// name_
encoder << name_;
}

void VertexExpression::resetFrom(Decoder& decoder) {
// Read name_
name_ = decoder.readStr();
}

void VertexExpression::accept(ExprVisitor* visitor) { visitor->visit(this); }

} // namespace nebula
22 changes: 15 additions & 7 deletions src/common/expression/VertexExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,34 @@ namespace nebula {
*/
class VertexExpression final : public Expression {
public:
static VertexExpression *make(ObjectPool *pool) { return pool->add(new VertexExpression(pool)); }
// default name : VERTEX, $^ : startNode of EDGE, $$ : endNode of EDGE
// $$ & $^ only used in go sentence
static VertexExpression *make(ObjectPool *pool, const std::string &name = "VERTEX") {
return pool->add(new VertexExpression(pool, name));
}

const Value &eval(ExpressionContext &ctx) override;

void accept(ExprVisitor *visitor) override;

Expression *clone() const override { return VertexExpression::make(pool_); }
Expression *clone() const override { return VertexExpression::make(pool_, name()); }

std::string toString() const override { return "VERTEX"; }
std::string toString() const override { return name_; }

bool operator==(const Expression &expr) const override { return kind() == expr.kind(); }
const std::string &name() const { return name_; }

bool operator==(const Expression &expr) const override;

private:
explicit VertexExpression(ObjectPool *pool) : Expression(pool, Kind::kVertex) {}
explicit VertexExpression(ObjectPool *pool, const std::string &name)
: Expression(pool, Kind::kVertex), name_(name) {}

void writeTo(Encoder &encoder) const override { encoder << kind(); }
void writeTo(Encoder &encoder) const override;

void resetFrom(Decoder &) override {}
void resetFrom(Decoder &) override;

private:
std::string name_;
Value result_;
};

Expand Down
5 changes: 4 additions & 1 deletion src/common/expression/test/ExpressionContextMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ class ExpressionContextMock final : public ExpressionContext {
}
}

Value getVertex() const override { return Value(); }
Value getVertex(const std::string& name = "") const override {
UNUSED(name);
return Value();
}

Value getEdge() const override { return Value(); }

Expand Down
3 changes: 2 additions & 1 deletion src/common/utils/DefaultValueContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ class DefaultValueContext final : public ExpressionContext {

void setVar(const std::string&, Value) override {}

Value getVertex() const override {
Value getVertex(const std::string& name = "") const override {
UNUSED(name);
LOG(FATAL) << "Not allowed to call";
return Value::kEmpty;
}
Expand Down
10 changes: 8 additions & 2 deletions src/graph/context/Iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@ const Value& GetNeighborsIter::getEdgeProp(const std::string& edge, const std::s
return currentEdge_->values[propIndex->second];
}

Value GetNeighborsIter::getVertex() const {
Value GetNeighborsIter::getVertex(const std::string& name) const {
UNUSED(name);
if (!valid()) {
return Value::kNullValue;
}
Expand Down Expand Up @@ -595,6 +596,10 @@ const Value& SequentialIter::getColumn(int32_t index) const {
return getColumnByIndex(index, iter_);
}

Value SequentialIter::getVertex(const std::string& name) const { return getColumn(name); }

Value SequentialIter::getEdge() const { return getColumn("EDGE"); }

PropIter::PropIter(std::shared_ptr<Value> value) : SequentialIter(value) {
DCHECK(value->isDataSet());
auto& ds = value->getDataSet();
Expand Down Expand Up @@ -673,7 +678,8 @@ const Value& PropIter::getProp(const std::string& name, const std::string& prop)
return row[colId];
}

Value PropIter::getVertex() const {
Value PropIter::getVertex(const std::string& name) const {
UNUSED(name);
if (!valid()) {
return Value::kNullValue;
}
Expand Down
13 changes: 10 additions & 3 deletions src/graph/context/Iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ class Iterator {
return Value::kEmpty;
}

virtual Value getVertex() const { return Value(); }
virtual Value getVertex(const std::string& name = "") const {
UNUSED(name);
return Value();
}

virtual Value getEdge() const { return Value(); }

Expand Down Expand Up @@ -237,7 +240,7 @@ class GetNeighborsIter final : public Iterator {

const Value& getEdgeProp(const std::string& edge, const std::string& prop) const override;

Value getVertex() const override;
Value getVertex(const std::string& name = "") const override;

Value getEdge() const override;

Expand Down Expand Up @@ -406,6 +409,10 @@ class SequentialIter : public Iterator {

const Value& getColumn(int32_t index) const override;

Value getVertex(const std::string& name = "") const override;

Value getEdge() const override;

protected:
const Row* row() const override { return &*iter_; }

Expand Down Expand Up @@ -442,7 +449,7 @@ class PropIter final : public SequentialIter {

const Value& getColumn(int32_t index) const override;

Value getVertex() const override;
Value getVertex(const std::string& name = "") const override;

Value getEdge() const override;

Expand Down
4 changes: 2 additions & 2 deletions src/graph/context/QueryExpressionContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ Value QueryExpressionContext::getColumn(int32_t index) const {
return iter_->getColumn(index);
}

Value QueryExpressionContext::getVertex() const {
Value QueryExpressionContext::getVertex(const std::string& name) const {
if (iter_ == nullptr) {
return Value::kEmpty;
}
return iter_->getVertex();
return iter_->getVertex(name);
}

Value QueryExpressionContext::getEdge() const {
Expand Down
2 changes: 1 addition & 1 deletion src/graph/context/QueryExpressionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class QueryExpressionContext final : public ExpressionContext {
Value getColumn(int32_t index) const override;

// Get Vertex
Value getVertex() const override;
Value getVertex(const std::string& name = "") const override;

// Get Edge
Value getEdge() const override;
Expand Down
107 changes: 93 additions & 14 deletions src/graph/validator/GoValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

namespace nebula {
namespace graph {

static const char* COLNAME_EDGE = "EDGE";
static const char* SRC_VERTEX = "$^";
static const char* DST_VERTEX = "$$";

Status GoValidator::validateImpl() {
auto* goSentence = static_cast<GoSentence*>(sentence_);
goCtx_ = getContext<GoContext>();
Expand Down Expand Up @@ -68,7 +73,7 @@ Status GoValidator::validateWhere(WhereClause* where) {
if (type != Value::Type::BOOL && type != Value::Type::NULLVALUE &&
type != Value::Type::__EMPTY__) {
std::stringstream ss;
ss << "`" << filter->toString() << "', expected Boolean, "
ss << "`" << filter->toString() << "', expected boolean, "
<< "but was `" << type << "'";
return Status::SemanticError(ss.str());
}
Expand Down Expand Up @@ -114,51 +119,102 @@ Status GoValidator::validateYield(YieldClause* yield) {
goCtx_->distinct = yield->isDistinct();
const auto& over = goCtx_->over;
auto* pool = qctx_->objPool();
auto& exprProps = goCtx_->exprProps;

auto cols = yield->columns();
if (cols.empty() && over.isOverAll) {
DCHECK(!over.allEdges.empty());
auto* newCols = qctx_->objPool()->add(new YieldColumns());
auto* newCols = pool->add(new YieldColumns());
for (const auto& e : over.allEdges) {
auto* col = new YieldColumn(EdgeDstIdExpression::make(pool, e));
newCols->addColumn(col);
outputs_.emplace_back(col->name(), vidType_);
NG_RETURN_IF_ERROR(deduceProps(col->expr(), goCtx_->exprProps));
NG_RETURN_IF_ERROR(deduceProps(col->expr(), exprProps));
}
goCtx_->yieldExpr = newCols;
goCtx_->colNames = getOutColNames();
return Status::OK();
}

for (auto col : cols) {
if (ExpressionUtils::hasAny(col->expr(),
{Expression::Kind::kAggregate, Expression::Kind::kPathBuild})) {
return Status::SemanticError("`%s' is not support in go sentence.", col->toString().c_str());
}

auto* vertexExpr = ExpressionUtils::findAny(col->expr(), {Expression::Kind::kVertex});
if (vertexExpr != nullptr) {
const auto& colName = static_cast<const VertexExpression*>(vertexExpr)->name();
if (colName == SRC_VERTEX) {
NG_RETURN_IF_ERROR(extractVertexProp(exprProps, true));
} else if (colName == DST_VERTEX) {
NG_RETURN_IF_ERROR(extractVertexProp(exprProps, false));
} else {
return Status::SemanticError("`%s' is not support in go sentence.",
col->toString().c_str());
}
}

col->setExpr(ExpressionUtils::rewriteLabelAttr2EdgeProp(col->expr()));
NG_RETURN_IF_ERROR(ValidateUtil::invalidLabelIdentifiers(col->expr()));

auto* colExpr = col->expr();
if (graph::ExpressionUtils::findAny(colExpr, {Expression::Kind::kAggregate})) {
return Status::SemanticError("`%s', not support aggregate function in go sentence.",
col->toString().c_str());
if (ExpressionUtils::hasAny(colExpr, {Expression::Kind::kEdge})) {
extractEdgeProp(exprProps);
}
// check input var expression

auto typeStatus = deduceExprType(colExpr);
NG_RETURN_IF_ERROR(typeStatus);
auto type = typeStatus.value();
outputs_.emplace_back(col->name(), type);

NG_RETURN_IF_ERROR(deduceProps(colExpr, goCtx_->exprProps));
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps));
}

for (const auto& e : goCtx_->exprProps.edgeProps()) {
for (const auto& e : exprProps.edgeProps()) {
auto found = std::find(over.edgeTypes.begin(), over.edgeTypes.end(), e.first);
if (found == over.edgeTypes.end()) {
return Status::SemanticError("Edges should be declared first in over clause.");
return Status::SemanticError("edge should be declared first in over clause.");
}
}
goCtx_->yieldExpr = yield->yields();
goCtx_->colNames = getOutColNames();
return Status::OK();
}

Status GoValidator::extractVertexProp(ExpressionProps& exprProps, bool isSrc) {
const auto tagStatus = qctx_->schemaMng()->getAllLatestVerTagSchema(space_.id);
NG_RETURN_IF_ERROR(tagStatus);
for (const auto& tag : tagStatus.value()) {
auto tagID = tag.first;
const auto& tagSchema = tag.second;
if (isSrc) {
for (size_t i = 0; i < tagSchema->getNumFields(); ++i) {
exprProps.insertSrcTagProp(tagID, tagSchema->getFieldName(i));
}
} else {
for (size_t i = 0; i < tagSchema->getNumFields(); ++i) {
exprProps.insertDstTagProp(tagID, tagSchema->getFieldName(i));
}
}
}
return Status::OK();
}

Status GoValidator::extractEdgeProp(ExpressionProps& exprProps) {
const auto& edgeTypes = goCtx_->over.edgeTypes;
for (const auto& edgeType : edgeTypes) {
const auto& edgeSchema = qctx_->schemaMng()->getEdgeSchema(space_.id, std::abs(edgeType));
exprProps.insertEdgeProp(edgeType, kType);
exprProps.insertEdgeProp(edgeType, kSrc);
exprProps.insertEdgeProp(edgeType, kDst);
exprProps.insertEdgeProp(edgeType, kRank);
for (size_t i = 0; i < edgeSchema->getNumFields(); ++i) {
exprProps.insertEdgeProp(edgeType, edgeSchema->getFieldName(i));
}
}
return Status::OK();
}

void GoValidator::extractPropExprs(const Expression* expr) {
ExtractPropExprVisitor visitor(
vctx_, goCtx_->srcEdgePropsExpr, goCtx_->dstPropsExpr, inputPropCols_, propExprColMap_);
Expand Down Expand Up @@ -210,10 +266,33 @@ Status GoValidator::buildColumns() {
goCtx_->filter = rewrite2VarProp(newFilter);
}

std::unordered_map<std::string, bool> existExpr;
auto* newYieldExpr = pool->add(new YieldColumns());
for (auto* yield : goCtx_->yieldExpr->columns()) {
extractPropExprs(yield->expr());
newYieldExpr->addColumn(new YieldColumn(rewrite2VarProp(yield->expr()), yield->alias()));
for (auto* col : goCtx_->yieldExpr->columns()) {
auto* vertexExpr = ExpressionUtils::findAny(col->expr(), {Expression::Kind::kVertex});
if (vertexExpr != nullptr) {
const auto& colName = static_cast<const VertexExpression*>(vertexExpr)->name();
if (colName == SRC_VERTEX && existExpr.count(SRC_VERTEX) == 0) {
goCtx_->srcEdgePropsExpr->addColumn(
new YieldColumn(VertexExpression::make(pool), SRC_VERTEX));
existExpr[SRC_VERTEX] = true;
}
if (colName == DST_VERTEX && existExpr.count(DST_VERTEX) == 0) {
goCtx_->dstPropsExpr->addColumn(new YieldColumn(VertexExpression::make(pool), DST_VERTEX));
existExpr[DST_VERTEX] = true;
}
newYieldExpr->addColumn(col->clone().release());
} else if (ExpressionUtils::hasAny(col->expr(), {Expression::Kind::kEdge})) {
if (existExpr.count(COLNAME_EDGE) == 0) {
goCtx_->srcEdgePropsExpr->addColumn(
new YieldColumn(EdgeExpression::make(pool), COLNAME_EDGE));
existExpr[COLNAME_EDGE] = true;
}
newYieldExpr->addColumn(col->clone().release());
} else {
extractPropExprs(col->expr());
newYieldExpr->addColumn(new YieldColumn(rewrite2VarProp(col->expr()), col->alias()));
}
}
goCtx_->yieldExpr = newYieldExpr;

Expand Down
4 changes: 4 additions & 0 deletions src/graph/validator/GoValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class GoValidator final : public Validator {

Expression* rewrite2VarProp(const Expression* expr);

Status extractVertexProp(ExpressionProps& exprProps, bool isSrc);

Status extractEdgeProp(ExpressionProps& exprProps);

private:
std::unique_ptr<GoContext> goCtx_;

Expand Down
Loading

0 comments on commit 8450ba9

Please sign in to comment.