Skip to content

Commit

Permalink
support cypher parameter(variable)
Browse files Browse the repository at this point in the history
  • Loading branch information
czpmango committed Dec 6, 2021
1 parent 43e4585 commit 37fcf81
Show file tree
Hide file tree
Showing 53 changed files with 515 additions and 126 deletions.
6 changes: 6 additions & 0 deletions src/graph/context/QueryContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ void QueryContext::init() {
objPool_ = std::make_unique<ObjectPool>();
ep_ = std::make_unique<ExecutionPlan>();
ectx_ = std::make_unique<ExecutionContext>();
// copy parameterMap into ExecutionContext
if (rctx_) {
for (auto item : rctx_->parameterMap()) {
ectx_->setValue(std::move(item.first), std::move(item.second));
}
}
idGen_ = std::make_unique<IdGenerator>(0);
symTable_ = std::make_unique<SymbolTable>(objPool_.get());
vctx_ = std::make_unique<ValidateContext>(std::make_unique<AnonVarGenerator>(symTable_.get()));
Expand Down
4 changes: 4 additions & 0 deletions src/graph/context/QueryContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ class QueryContext {

bool isKilled() const { return killed_.load(); }

bool existParameter(const std::string& param) const {
return ectx_->exist(param) && (ectx_->getValue(param).type() != Value::Type::DATASET);
}

private:
void init();

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 @@ -53,7 +53,7 @@ class QueryExpressionContext final : public ExpressionContext {

void setVar(const std::string&, Value val) override;

QueryExpressionContext& operator()(Iterator* iter) {
QueryExpressionContext& operator()(Iterator* iter = nullptr) {
iter_ = iter;
return *this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/graph/executor/query/AppendVerticesExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ folly::Future<Status> AppendVerticesExecutor::appendVertices() {
av->exprs(),
av->dedup(),
av->orderBy(),
av->limit(),
av->limit(qctx()),
av->filter())
.via(runner())
.ensure([this, getPropsTime]() {
Expand Down
2 changes: 1 addition & 1 deletion src/graph/executor/query/GetEdgesExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ folly::Future<Status> GetEdgesExecutor::getEdges() {
ge->exprs(),
ge->dedup(),
ge->orderBy(),
ge->limit(),
ge->limit(qctx()),
ge->filter())
.via(runner())
.ensure([this, getPropsTime]() {
Expand Down
2 changes: 1 addition & 1 deletion src/graph/executor/query/GetVerticesExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ folly::Future<Status> GetVerticesExecutor::getVertices() {
gv->exprs(),
gv->dedup(),
gv->orderBy(),
gv->limit(),
gv->limit(qctx()),
gv->filter())
.via(runner())
.ensure([this, getPropsTime]() {
Expand Down
2 changes: 1 addition & 1 deletion src/graph/executor/query/IndexScanExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ folly::Future<Status> IndexScanExecutor::indexScan() {
lookup->isEdge(),
lookup->schemaId(),
lookup->returnColumns(),
lookup->limit())
lookup->limit(qctx_))
.via(runner())
.thenValue([this](StorageRpcResponse<LookupIndexResp> &&rpcResp) {
addStats(rpcResp, otherStats_);
Expand Down
2 changes: 1 addition & 1 deletion src/graph/executor/query/TraverseExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void TraverseExecutor::getNeighbors() {
finalStep ? traverse_->dedup() : false,
finalStep ? traverse_->random() : false,
finalStep ? traverse_->orderBy() : std::vector<storage::cpp2::OrderBy>(),
finalStep ? traverse_->limit() : -1,
finalStep ? traverse_->limit(qctx()) : -1,
finalStep ? traverse_->filter() : nullptr)
.via(runner())
.thenValue([this, getNbrTime](StorageRpcResponse<GetNeighborsResponse>&& resp) mutable {
Expand Down
5 changes: 3 additions & 2 deletions src/graph/optimizer/OptimizerUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,15 +416,16 @@ bool OptimizerUtils::relExprHasIndex(
}

void OptimizerUtils::copyIndexScanData(const nebula::graph::IndexScan* from,
nebula::graph::IndexScan* to) {
nebula::graph::IndexScan* to,
QueryContext* qctx) {
to->setEmptyResultSet(from->isEmptyResultSet());
to->setSpace(from->space());
to->setReturnCols(from->returnColumns());
to->setIsEdge(from->isEdge());
to->setSchemaId(from->schemaId());
to->setDedup(from->dedup());
to->setOrderBy(from->orderBy());
to->setLimit(from->limit());
to->setLimit(from->limit(qctx));
to->setFilter(from->filter() == nullptr ? nullptr : from->filter()->clone());
}

Expand Down
4 changes: 3 additions & 1 deletion src/graph/optimizer/OptimizerUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ class OptimizerUtils {
const Expression* expr,
const std::vector<std::shared_ptr<nebula::meta::cpp2::IndexItem>>& indexItems);

static void copyIndexScanData(const nebula::graph::IndexScan* from, nebula::graph::IndexScan* to);
static void copyIndexScanData(const nebula::graph::IndexScan* from,
nebula::graph::IndexScan* to,
QueryContext* qctx);
};

} // namespace graph
Expand Down
2 changes: 1 addition & 1 deletion src/graph/optimizer/rule/GeoPredicateIndexScanBaseRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ StatusOr<TransformResult> GeoPredicateIndexScanBaseRule::transform(
}

auto scanNode = IndexScan::make(ctx->qctx(), nullptr);
OptimizerUtils::copyIndexScanData(scan, scanNode);
OptimizerUtils::copyIndexScanData(scan, scanNode, ctx->qctx());
scanNode->setIndexQueryContext(std::move(idxCtxs));
// TODO(jie): geo predicate's calculation is a little heavy,
// which is not suitable to push down to the storage
Expand Down
2 changes: 1 addition & 1 deletion src/graph/optimizer/rule/IndexFullScanBaseRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ StatusOr<TransformResult> IndexFullScanBaseRule::transform(OptContext* ctx,
idxCtxs.emplace_back(std::move(ictx));

auto scanNode = this->scan(ctx, scan);
OptimizerUtils::copyIndexScanData(scan, scanNode);
OptimizerUtils::copyIndexScanData(scan, scanNode, ctx->qctx());
scanNode->setOutputVar(scan->outputVar());
scanNode->setColNames(scan->colNames());
scanNode->setIndexQueryContext(std::move(idxCtxs));
Expand Down
17 changes: 16 additions & 1 deletion src/graph/optimizer/rule/IndexScanRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
#include "graph/optimizer/rule/IndexScanRule.h"

#include "common/expression/LabelAttributeExpression.h"
#include "common/expression/VariableExpression.h"
#include "graph/optimizer/OptContext.h"
#include "graph/optimizer/OptGroup.h"
#include "graph/optimizer/OptRule.h"
#include "graph/optimizer/OptimizerUtils.h"
#include "graph/planner/plan/PlanNode.h"
#include "graph/planner/plan/Query.h"
#include "graph/util/IndexUtil.h"
#include "graph/visitor/RewriteVisitor.h"

using nebula::graph::IndexScan;
using nebula::graph::IndexUtil;
Expand Down Expand Up @@ -63,7 +65,20 @@ StatusOr<OptRule::TransformResult> IndexScanRule::transform(OptContext* ctx,
} else {
FilterItems items;
ScanKind kind;
NG_RETURN_IF_ERROR(analyzeExpression(filter, &items, &kind, isEdge(groupNode)));
// rewrite ParameterExpression to ConstantExpression
// TODO: refactor index selector logic to avoid this rewriting
auto matcher = [qctx](const Expression* e) -> bool {
return e->kind() == Expression::Kind::kVar &&
qctx->existParameter(static_cast<const VariableExpression*>(e)->var());
};
auto rewriter = [qctx](const Expression* e) -> Expression* {
DCHECK_EQ(e->kind(), Expression::Kind::kVar);
auto& v = const_cast<Expression*>(e)->eval(graph::QueryExpressionContext(qctx->ectx())());
return ConstantExpression::make(qctx->objPool(), v);
};
auto* newFilter = graph::RewriteVisitor::transform(filter, matcher, rewriter);

NG_RETURN_IF_ERROR(analyzeExpression(newFilter, &items, &kind, isEdge(groupNode)));
auto status = createIndexQueryCtx(iqctx, kind, items, qctx, groupNode);
if (!status.ok()) {
NG_RETURN_IF_ERROR(createIndexQueryCtx(iqctx, qctx, groupNode));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ EdgeIndexScan* makeEdgeIndexScan(QueryContext* qctx, const EdgeIndexScan* scan,
} else {
scanNode = EdgeIndexRangeScan::make(qctx, nullptr, scan->edgeType());
}
OptimizerUtils::copyIndexScanData(scan, scanNode);
OptimizerUtils::copyIndexScanData(scan, scanNode, qctx);
return scanNode;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ TagIndexScan* makeTagIndexScan(QueryContext* qctx, const TagIndexScan* scan, boo
tagScan = TagIndexRangeScan::make(qctx, nullptr, scan->tagName());
}

OptimizerUtils::copyIndexScanData(scan, tagScan);
OptimizerUtils::copyIndexScanData(scan, tagScan, qctx);
return tagScan;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ const Pattern &PushLimitDownEdgeIndexFullScanRule::pattern() const {

StatusOr<OptRule::TransformResult> PushLimitDownEdgeIndexFullScanRule::transform(
OptContext *octx, const MatchedResult &matched) const {
auto *qctx = octx->qctx();
auto limitGroupNode = matched.node;
auto indexScanGroupNode = matched.dependencies.front().node;

const auto limit = static_cast<const Limit *>(limitGroupNode->node());
const auto indexScan = static_cast<const EdgeIndexFullScan *>(indexScanGroupNode->node());

int64_t limitRows = limit->offset() + limit->count();
if (indexScan->limit() >= 0 && limitRows >= indexScan->limit()) {
int64_t limitRows = limit->offset() + limit->count(qctx);
if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) {
return TransformResult::noTransform();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@ const Pattern &PushLimitDownEdgeIndexPrefixScanRule::pattern() const {

StatusOr<OptRule::TransformResult> PushLimitDownEdgeIndexPrefixScanRule::transform(
OptContext *octx, const MatchedResult &matched) const {
auto *qctx = octx->qctx();
auto limitGroupNode = matched.node;
auto indexScanGroupNode = matched.dependencies.front().node;

const auto limit = static_cast<const Limit *>(limitGroupNode->node());
const auto indexScan = static_cast<const EdgeIndexPrefixScan *>(indexScanGroupNode->node());

int64_t limitRows = limit->offset() + limit->count();
if (indexScan->limit() >= 0 && limitRows >= indexScan->limit()) {
int64_t limitRows = limit->offset() + limit->count(qctx);
if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) {
return TransformResult::noTransform();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ const Pattern &PushLimitDownEdgeIndexRangeScanRule::pattern() const {

StatusOr<OptRule::TransformResult> PushLimitDownEdgeIndexRangeScanRule::transform(
OptContext *octx, const MatchedResult &matched) const {
auto *qctx = octx->qctx();
auto limitGroupNode = matched.node;
auto indexScanGroupNode = matched.dependencies.front().node;

const auto limit = static_cast<const Limit *>(limitGroupNode->node());
const auto indexScan = static_cast<const EdgeIndexRangeScan *>(indexScanGroupNode->node());

int64_t limitRows = limit->offset() + limit->count();
if (indexScan->limit() >= 0 && limitRows >= indexScan->limit()) {
int64_t limitRows = limit->offset() + limit->count(qctx);
if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) {
return TransformResult::noTransform();
}

Expand Down
5 changes: 3 additions & 2 deletions src/graph/optimizer/rule/PushLimitDownGetNeighborsRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const Pattern &PushLimitDownGetNeighborsRule::pattern() const {

StatusOr<OptRule::TransformResult> PushLimitDownGetNeighborsRule::transform(
OptContext *octx, const MatchedResult &matched) const {
auto *qctx = octx->qctx();
auto limitGroupNode = matched.node;
auto gnGroupNode = matched.dependencies.front().node;

Expand All @@ -43,8 +44,8 @@ StatusOr<OptRule::TransformResult> PushLimitDownGetNeighborsRule::transform(
if (!graph::ExpressionUtils::isEvaluableExpr(limit->countExpr())) {
return TransformResult::noTransform();
}
int64_t limitRows = limit->offset() + limit->count();
if (gn->limit() >= 0 && limitRows >= gn->limit()) {
int64_t limitRows = limit->offset() + limit->count(qctx);
if (gn->limit(qctx) >= 0 && limitRows >= gn->limit(qctx)) {
return TransformResult::noTransform();
}

Expand Down
5 changes: 3 additions & 2 deletions src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ const Pattern &PushLimitDownIndexScanRule::pattern() const {

StatusOr<OptRule::TransformResult> PushLimitDownIndexScanRule::transform(
OptContext *octx, const MatchedResult &matched) const {
auto *qctx = octx->qctx();
auto limitGroupNode = matched.node;
auto indexScanGroupNode = matched.dependencies.front().node;

const auto limit = static_cast<const Limit *>(limitGroupNode->node());
const auto indexScan = static_cast<const IndexScan *>(indexScanGroupNode->node());

int64_t limitRows = limit->offset() + limit->count();
if (indexScan->limit() >= 0 && limitRows >= indexScan->limit()) {
int64_t limitRows = limit->offset() + limit->count(qctx);
if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) {
return TransformResult::noTransform();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ const Pattern &PushLimitDownTagIndexFullScanRule::pattern() const {

StatusOr<OptRule::TransformResult> PushLimitDownTagIndexFullScanRule::transform(
OptContext *octx, const MatchedResult &matched) const {
auto *qctx = octx->qctx();
auto limitGroupNode = matched.node;
auto indexScanGroupNode = matched.dependencies.front().node;

const auto limit = static_cast<const Limit *>(limitGroupNode->node());
const auto indexScan = static_cast<const TagIndexFullScan *>(indexScanGroupNode->node());

int64_t limitRows = limit->offset() + limit->count();
if (indexScan->limit() >= 0 && limitRows >= indexScan->limit()) {
int64_t limitRows = limit->offset() + limit->count(qctx);
if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) {
return TransformResult::noTransform();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ const Pattern &PushLimitDownTagIndexPrefixScanRule::pattern() const {

StatusOr<OptRule::TransformResult> PushLimitDownTagIndexPrefixScanRule::transform(
OptContext *octx, const MatchedResult &matched) const {
auto *qctx = octx->qctx();
auto limitGroupNode = matched.node;
auto indexScanGroupNode = matched.dependencies.front().node;

const auto limit = static_cast<const Limit *>(limitGroupNode->node());
const auto indexScan = static_cast<const TagIndexPrefixScan *>(indexScanGroupNode->node());

int64_t limitRows = limit->offset() + limit->count();
if (indexScan->limit() >= 0 && limitRows >= indexScan->limit()) {
int64_t limitRows = limit->offset() + limit->count(qctx);
if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) {
return TransformResult::noTransform();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ const Pattern &PushLimitDownTagIndexRangeScanRule::pattern() const {

StatusOr<OptRule::TransformResult> PushLimitDownTagIndexRangeScanRule::transform(
OptContext *octx, const MatchedResult &matched) const {
auto *qctx = octx->qctx();
auto limitGroupNode = matched.node;
auto indexScanGroupNode = matched.dependencies.front().node;

const auto limit = static_cast<const Limit *>(limitGroupNode->node());
const auto indexScan = static_cast<const TagIndexRangeScan *>(indexScanGroupNode->node());

int64_t limitRows = limit->offset() + limit->count();
if (indexScan->limit() >= 0 && limitRows >= indexScan->limit()) {
int64_t limitRows = limit->offset() + limit->count(qctx);
if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) {
return TransformResult::noTransform();
}

Expand Down
11 changes: 6 additions & 5 deletions src/graph/optimizer/rule/PushStepLimitDownGetNeighborsRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ StatusOr<OptRule::TransformResult> PushStepLimitDownGetNeighborsRule::transform(

const auto limit = static_cast<const Limit *>(limitGroupNode->node());
const auto gn = static_cast<const GetNeighbors *>(gnGroupNode->node());

if (gn->limitExpr() != nullptr && graph::ExpressionUtils::isEvaluableExpr(gn->limitExpr()) &&
graph::ExpressionUtils::isEvaluableExpr(limit->countExpr())) {
int64_t limitRows = limit->offset() + limit->count();
int64_t gnLimit = gn->limit();
auto *qctx = octx->qctx();
if (gn->limitExpr() != nullptr &&
graph::ExpressionUtils::isEvaluableExpr(gn->limitExpr(), qctx) &&
graph::ExpressionUtils::isEvaluableExpr(limit->countExpr(), qctx)) {
int64_t limitRows = limit->offset() + limit->count(qctx);
int64_t gnLimit = gn->limit(qctx);
if (gnLimit >= 0 && limitRows >= gnLimit) {
return TransformResult::noTransform();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ StatusOr<OptRule::TransformResult> PushStepSampleDownGetNeighborsRule::transform

const auto sample = static_cast<const Sample *>(sampleGroupNode->node());
const auto gn = static_cast<const GetNeighbors *>(gnGroupNode->node());

if (gn->limitExpr() != nullptr && graph::ExpressionUtils::isEvaluableExpr(gn->limitExpr()) &&
graph::ExpressionUtils::isEvaluableExpr(sample->countExpr())) {
int64_t limitRows = sample->count();
int64_t gnLimit = gn->limit();
int64_t gnLimit = gn->limit(octx->qctx());
if (gnLimit >= 0 && limitRows >= gnLimit) {
return TransformResult::noTransform();
}
Expand Down
2 changes: 1 addition & 1 deletion src/graph/optimizer/rule/TopNRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ StatusOr<OptRule::TransformResult> TopNRule::transform(OptContext *ctx,
}

auto qctx = ctx->qctx();
auto topn = TopN::make(qctx, nullptr, sort->factors(), limit->offset(), limit->count());
auto topn = TopN::make(qctx, nullptr, sort->factors(), limit->offset(), limit->count(qctx));
topn->setOutputVar(limit->outputVar());
topn->setInputVar(sort->inputVar());
topn->setColNames(sort->colNames());
Expand Down
8 changes: 4 additions & 4 deletions src/graph/optimizer/rule/UnionAllIndexScanBaseRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ StatusOr<TransformResult> UnionAllIndexScanBaseRule::transform(OptContext* ctx,
auto filter = static_cast<const Filter*>(matched.planNode());
auto node = matched.planNode({0, 0});
auto scan = static_cast<const IndexScan*>(node);

auto metaClient = ctx->qctx()->getMetaClient();
auto* qctx = ctx->qctx();
auto metaClient = qctx->getMetaClient();
auto status = node->kind() == graph::PlanNode::Kind::kTagIndexFullScan
? metaClient->getTagIndexesFromCache(scan->space())
: metaClient->getEdgeIndexesFromCache(scan->space());
Expand Down Expand Up @@ -170,8 +170,8 @@ StatusOr<TransformResult> UnionAllIndexScanBaseRule::transform(OptContext* ctx,
idxCtxs.emplace_back(std::move(ictx));
}

auto scanNode = IndexScan::make(ctx->qctx(), nullptr);
OptimizerUtils::copyIndexScanData(scan, scanNode);
auto scanNode = IndexScan::make(qctx, nullptr);
OptimizerUtils::copyIndexScanData(scan, scanNode, qctx);
scanNode->setIndexQueryContext(std::move(idxCtxs));
scanNode->setOutputVar(filter->outputVar());
scanNode->setColNames(filter->colNames());
Expand Down
Loading

0 comments on commit 37fcf81

Please sign in to comment.