diff --git a/src/graph/context/ast/QueryAstContext.h b/src/graph/context/ast/QueryAstContext.h index 8fe175699f4..3e5146a318c 100644 --- a/src/graph/context/ast/QueryAstContext.h +++ b/src/graph/context/ast/QueryAstContext.h @@ -128,6 +128,7 @@ struct SubgraphContext final : public AstContext { StepClause steps; std::string loopSteps; Expression* filter{nullptr}; + Expression* tagFilter{nullptr}; Expression* edgeFilter{nullptr}; std::vector colNames; std::unordered_set edgeTypes; diff --git a/src/graph/executor/algo/SubgraphExecutor.cpp b/src/graph/executor/algo/SubgraphExecutor.cpp index e9bbfb014e5..fd5361ebcd5 100644 --- a/src/graph/executor/algo/SubgraphExecutor.cpp +++ b/src/graph/executor/algo/SubgraphExecutor.cpp @@ -47,7 +47,8 @@ folly::Future SubgraphExecutor::getNeighbors() { false, {}, -1, - currentStep_ == 1 ? subgraph_->edgeFilter() : subgraph_->filter()) + currentStep_ == 1 ? subgraph_->edgeFilter() : subgraph_->filter(), + currentStep_ == 1 ? nullptr : subgraph_->tagFilter()) .via(runner()) .thenValue([this, getNbrTime](RpcResponse&& resp) mutable { // addStats(resp, getNbrTime.elapsedInUSec()); diff --git a/src/graph/planner/ngql/SubgraphPlanner.cpp b/src/graph/planner/ngql/SubgraphPlanner.cpp index 93e7a9292f7..c7b480f7136 100644 --- a/src/graph/planner/ngql/SubgraphPlanner.cpp +++ b/src/graph/planner/ngql/SubgraphPlanner.cpp @@ -81,6 +81,7 @@ StatusOr SubgraphPlanner::nSteps(SubPlan& startVidPlan, const std::stri startVidPlan.root, space.id, subgraphCtx_->from.src, + subgraphCtx_->tagFilter, subgraphCtx_->edgeFilter, subgraphCtx_->filter, steps.steps() + 1); diff --git a/src/graph/planner/plan/Algo.cpp b/src/graph/planner/plan/Algo.cpp index 4270821990a..e3c4e09fa3e 100644 --- a/src/graph/planner/plan/Algo.cpp +++ b/src/graph/planner/plan/Algo.cpp @@ -135,9 +135,10 @@ BiCartesianProduct::BiCartesianProduct(QueryContext* qctx) std::unique_ptr Subgraph::explain() const { auto desc = SingleDependencyNode::explain(); - addDescription("src", src_ != nullptr ? src_->toString() : "", desc.get()); - addDescription("edge_filter", edgeFilter_ != nullptr ? edgeFilter_->toString() : "", desc.get()); - addDescription("filter", filter_ != nullptr ? filter_->toString() : "", desc.get()); + addDescription("src", src_ ? src_->toString() : "", desc.get()); + addDescription("tag_filter", tagFilter_ ? tagFilter_->toString() : "", desc.get()); + addDescription("edge_filter", edgeFilter_ ? edgeFilter_->toString() : "", desc.get()); + addDescription("filter", filter_ ? filter_->toString() : "", desc.get()); addDescription( "vertexProps", vertexProps_ ? folly::toJson(util::toJson(*vertexProps_)) : "", desc.get()); addDescription( diff --git a/src/graph/planner/plan/Algo.h b/src/graph/planner/plan/Algo.h index 7b5e28a914f..c6b6dac74fa 100644 --- a/src/graph/planner/plan/Algo.h +++ b/src/graph/planner/plan/Algo.h @@ -270,11 +270,12 @@ class Subgraph final : public SingleInputNode { PlanNode* input, GraphSpaceID space, Expression* src, + const Expression* tagFilter, const Expression* edgeFilter, const Expression* filter, size_t steps) { return qctx->objPool()->makeAndAdd( - qctx, input, space, DCHECK_NOTNULL(src), edgeFilter, filter, steps); + qctx, input, space, DCHECK_NOTNULL(src), tagFilter, edgeFilter, filter, steps); } GraphSpaceID space() const { @@ -285,6 +286,10 @@ class Subgraph final : public SingleInputNode { return src_; } + const Expression* tagFilter() const { + return tagFilter_; + } + const Expression* edgeFilter() const { return edgeFilter_; } @@ -337,12 +342,14 @@ class Subgraph final : public SingleInputNode { PlanNode* input, GraphSpaceID space, Expression* src, + const Expression* tagFilter, const Expression* edgeFilter, const Expression* filter, size_t steps) : SingleInputNode(qctx, Kind::kSubgraph, input), space_(space), src_(src), + tagFilter_(tagFilter), edgeFilter_(edgeFilter), filter_(filter), steps_(steps) {} @@ -350,6 +357,7 @@ class Subgraph final : public SingleInputNode { GraphSpaceID space_; // vertices may be parsing from runtime. Expression* src_{nullptr}; + const Expression* tagFilter_{nullptr}; const Expression* edgeFilter_{nullptr}; const Expression* filter_{nullptr}; size_t steps_{1}; diff --git a/src/graph/validator/GetSubgraphValidator.cpp b/src/graph/validator/GetSubgraphValidator.cpp index e90eb3da411..e2350c1d326 100644 --- a/src/graph/validator/GetSubgraphValidator.cpp +++ b/src/graph/validator/GetSubgraphValidator.cpp @@ -126,7 +126,8 @@ Status GetSubgraphValidator::validateWhere(WhereClause* where) { {Expression::Kind::kAggregate, Expression::Kind::kSrcProperty, Expression::Kind::kVarProperty, - Expression::Kind::kInputProperty})) { + Expression::Kind::kInputProperty, + Expression::Kind::kLogicalOr})) { return Status::SemanticError("Not support `%s' in where sentence.", expr->toString().c_str()); } @@ -152,7 +153,9 @@ Status GetSubgraphValidator::validateWhere(WhereClause* where) { if (!visitor.ok()) { return Status::SemanticError("filter error"); } - subgraphCtx_->edgeFilter = std::move(visitor).remainedExpr(); + subgraphCtx_->edgeFilter = visitor.remainedExpr(); + auto tagFilter = visitor.extractedExpr() ? visitor.extractedExpr() : filter; + subgraphCtx_->tagFilter = rewriteDstProp2SrcProp(tagFilter); } else { subgraphCtx_->edgeFilter = condition; } diff --git a/src/graph/visitor/ExtractFilterExprVisitor.cpp b/src/graph/visitor/ExtractFilterExprVisitor.cpp index 58768f841f6..6aca3bb22c9 100644 --- a/src/graph/visitor/ExtractFilterExprVisitor.cpp +++ b/src/graph/visitor/ExtractFilterExprVisitor.cpp @@ -230,6 +230,14 @@ void ExtractFilterExprVisitor::ExtractRemainExpr(LogicalExpression *expr, } operands.resize(lastUsedExprInd); + if (lastUsedExprInd > 1) { + auto extractedExpr = LogicalExpression::makeAnd(pool_); + extractedExpr->setOperands(std::move(operands)); + extractedExpr_ = std::move(extractedExpr); + } else { + extractedExpr_ = std::move(operands[0]); + } + if (remainedOperands.size() > 1) { auto remainedExpr = LogicalExpression::makeAnd(pool_); remainedExpr->setOperands(std::move(remainedOperands)); diff --git a/src/graph/visitor/ExtractFilterExprVisitor.h b/src/graph/visitor/ExtractFilterExprVisitor.h index f4c6fd98c43..43e2d74d004 100644 --- a/src/graph/visitor/ExtractFilterExprVisitor.h +++ b/src/graph/visitor/ExtractFilterExprVisitor.h @@ -20,6 +20,10 @@ class ExtractFilterExprVisitor final : public ExprVisitorImpl { return canBePushed_; } + Expression *extractedExpr() { + return extractedExpr_; + } + Expression *remainedExpr() { return remainedExpr_; } @@ -88,6 +92,7 @@ class ExtractFilterExprVisitor final : public ExprVisitorImpl { bool hasSplit{false}; bool splitForbidden{false}; Expression *remainedExpr_{nullptr}; + Expression *extractedExpr_{nullptr}; PushType pushType_{PushType::kGetNeighbors}; };