Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

format go yield #2944

Merged
merged 9 commits into from
Sep 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (existExpr.count(colName)==0) {
  if (colName == SRC) {

  } else if (colName == DST) {}
  existExpr[colName] = true;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix in other PR

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