Skip to content

Commit

Permalink
add plan
Browse files Browse the repository at this point in the history
  • Loading branch information
nevermore3 committed Aug 2, 2023
1 parent 9b096b2 commit 291dc17
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 27 deletions.
94 changes: 69 additions & 25 deletions src/graph/validator/YieldValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ Status YieldValidator::validateImpl() {
if (qctx_->vctx()->spaceChosen()) {
space_ = vctx_->whichSpace();
}

auto yield = static_cast<YieldSentence *>(sentence_);
isDistinct_ = yield->yield()->isDistinct();

if (yield->yield()->yields()->hasAgg()) {
NG_RETURN_IF_ERROR(makeImplicitGroupByValidator());
}
Expand All @@ -45,16 +46,18 @@ Status YieldValidator::validateImpl() {
return Status::SemanticError("Not support both input and variable.");
}

if (!exprProps_.varProps().empty() && exprProps_.varProps().size() > 1) {
return Status::SemanticError("Only one variable allowed to use.");
}
if (yield->joinClause() == nullptr) {
if (!exprProps_.varProps().empty() && exprProps_.varProps().size() > 1) {
return Status::SemanticError("Only one variable allowed to use.");
}

if (!exprProps_.varProps().empty() && !userDefinedVarNameList_.empty()) {
// TODO: Support Multiple userDefinedVars
if (userDefinedVarNameList_.size() != 1) {
return Status::SemanticError("Multiple user defined vars not supported yet.");
if (!exprProps_.varProps().empty() && !userDefinedVarNameList_.empty()) {
// TODO: Support Multiple userDefinedVars
if (userDefinedVarNameList_.size() != 1) {
return Status::SemanticError("Multiple user defined vars not supported yet.");
}
userDefinedVarName_ = *userDefinedVarNameList_.begin();
}
userDefinedVarName_ = *userDefinedVarNameList_.begin();
}

return Status::OK();
Expand Down Expand Up @@ -177,42 +180,83 @@ Status YieldValidator::validateJoin(const JoinClause *join) {
if (join == nullptr) {
return Status::OK();
}

if (join->joinMode() != JoinMode::kInnerJoin) {
return Status::SemanticError("only support inner join.");
}

auto *leftVarExpr = join->leftVarExpr();
auto *rightVarExpr = join->rightVarExpr();
DCHECK_EQ(leftVarExpr->kind(), Expression::Kind::kVar);
DCHECK_EQ(rightVarExpr->kind(), Expression::Kind::kVar);
auto leftVar = static_cast<VariableExpression *>(leftVarExpr)->var();
auto rightVar = static_cast<VariableExpression *>(rightVarExpr)->var();

auto *leftConditionExpr = join->leftConditionExpr();
auto *rightConditionExpr = join->rightConditionExpr();
DCHECK_EQ(leftConditionExpr->kind(), Expression::Kind::kVarProperty);
DCHECK_EQ(rightConditionExpr->kind(), Expression::Kind::kVarProperty);
auto &leftConditionVar = static_cast<VariablePropertyExpression *>(leftConditionExpr)->sym();
auto &rightConditionVar = static_cast<VariablePropertyExpression *>(rightConditionExpr)->sym();
leftVar_ = static_cast<VariableExpression *>(leftVarExpr)->var();
rightVar_ = static_cast<VariableExpression *>(rightVarExpr)->var();

leftConditionExpr_ = join->leftConditionExpr();
rightConditionExpr_ = join->rightConditionExpr();
DCHECK_EQ(leftConditionExpr_->kind(), Expression::Kind::kVarProperty);
DCHECK_EQ(rightConditionExpr_->kind(), Expression::Kind::kVarProperty);
auto &leftConditionVar = static_cast<VariablePropertyExpression *>(leftConditionExpr_)->sym();
auto &rightConditionVar = static_cast<VariablePropertyExpression *>(rightConditionExpr_)->sym();

if (leftVar_ == rightVar_) {
return Status::SemanticError("do not support self-join.");
}

if (leftVar != leftConditionVar) {
if (leftVar_ != leftConditionVar) {
return Status::SemanticError("`%s' should be consistent with join condition variable `%s'.",
leftVar.c_str(),
leftVar_.c_str(),
leftConditionVar.c_str());
}

if (rightVar != rightConditionVar) {
if (rightVar_ != rightConditionVar) {
return Status::SemanticError("`%s' should be consistent with join condition variable `%s'.",
rightVar.c_str(),
rightVar_.c_str(),
rightConditionVar.c_str());
}

auto typeStatus = deduceExprType(leftConditionExpr);
auto typeStatus = deduceExprType(leftConditionExpr_);
NG_RETURN_IF_ERROR(typeStatus);
typeStatus = deduceExprType(rightConditionExpr);
typeStatus = deduceExprType(rightConditionExpr_);
NG_RETURN_IF_ERROR(typeStatus);
return Status::OK();
}

Status YieldValidator::buildJoinPlan() {
auto *varPtr = qctx_->symTable()->getVar(leftVar_);
DCHECK(varPtr != nullptr);
std::vector<std::string> colNames = varPtr->colNames;

varPtr = qctx_->symTable()->getVar(rightVar_);
DCHECK(varPtr != nullptr);
colNames.insert(colNames.end(), varPtr->colNames.begin(), varPtr->colNames.end());

auto *join = InnerJoin::make(qctx_,
nullptr,
{leftVar_, ExecutionContext::kLatestVersion},
{rightVar_, ExecutionContext::kLatestVersion},
{leftConditionExpr_},
{rightConditionExpr_});
join->setColNames(std::move(colNames));

auto *project = Project::make(qctx_, join, columns_);
project->setColNames(getOutColNames());

if (isDistinct_) {
root_ = Dedup::make(qctx_, project);
} else {
root_ = project;
}
tail_ = join;
return Status::OK();
}

// Generate plan according to input, implicit group by and yield columns.
Status YieldValidator::toPlan() {
auto yield = static_cast<const YieldSentence *>(sentence_);
if (yield->joinClause()) {
return buildJoinPlan();
}

std::string inputVar;
std::vector<std::string> colNames(inputs_.size());
Expand Down Expand Up @@ -271,7 +315,7 @@ Status YieldValidator::toPlan() {
}
}

if (yield->yield()->isDistinct()) {
if (isDistinct_) {
root_ = Dedup::make(qctx_, dedupDep);
} else {
root_ = dedupDep;
Expand Down
8 changes: 7 additions & 1 deletion src/graph/validator/YieldValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,21 @@ class YieldValidator final : public Validator {
Status makeOutputColumn(YieldColumn *column);
Status makeImplicitGroupByValidator();
Status validateImplicitGroupBy();
void genConstantExprValues();
Status buildJoinPlan();

private:
bool isDistinct_{false};
YieldColumns *columns_{nullptr};
std::string constantExprVar_;
std::string userDefinedVarName_;
Expression *filterCondition_{nullptr};
// validate for agg
std::unique_ptr<GroupByValidator> groupByValidator_{nullptr};

std::string leftVar_;
std::string rightVar_;
Expression *leftConditionExpr_{nullptr};
Expression *rightConditionExpr_{nullptr};
};

} // namespace graph
Expand Down
4 changes: 4 additions & 0 deletions src/parser/Clauses.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,10 @@ class JoinClause final {
return rightConditionExpr_;
}

JoinMode joinMode() const {
return joinMode_;
}

std::string toString() const;

private:
Expand Down
1 change: 0 additions & 1 deletion src/parser/parser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include <cstddef>
#include "parser/ExplainSentence.h"
#include "parser/SequentialSentences.h"
#include "parser/Clauses.h"
#include "interface/gen-cpp2/meta_types.h"
#include "common/expression/AttributeExpression.h"
#include "common/expression/LabelAttributeExpression.h"
Expand Down

0 comments on commit 291dc17

Please sign in to comment.