Skip to content

Commit

Permalink
cherry pick from nebula: Fix PushLimitDownFulltextIndexScanRule (veso…
Browse files Browse the repository at this point in the history
…ft-inc#5601) (vesoft-inc#2846)

Fix PushLimitDownFulltextIndexScanRule  (vesoft-inc#5601)

* Fix push limit down ft index scan rule

* Fix limit offset bug in OptRule

* Add plan tests

Co-authored-by: Yee <2520865+yixinglu@users.noreply.github.com>
  • Loading branch information
Sophie-Xie and yixinglu committed Jun 16, 2023
1 parent 6739028 commit cbf879e
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 34 deletions.
40 changes: 26 additions & 14 deletions src/graph/optimizer/rule/PushLimitDownFulltextIndexScanRule2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ using nebula::graph::FulltextIndexScan;
using nebula::graph::HashInnerJoin;
using nebula::graph::Limit;
using nebula::graph::PlanNode;
using nebula::graph::Project;
using nebula::graph::QueryContext;

namespace nebula {
Expand All @@ -38,9 +39,16 @@ const Pattern &PushLimitDownFulltextIndexScanRule2::pattern() const {
PlanNode::Kind::kHashInnerJoin,
{
Pattern::create(PlanNode::Kind::kFulltextIndexScan),
Pattern::create({PlanNode::Kind::kGetVertices, PlanNode::Kind::kGetEdges},
Pattern::create(PlanNode::Kind::kProject,
{
Pattern::create(PlanNode::Kind::kArgument),
Pattern::create(
{
PlanNode::Kind::kGetVertices,
PlanNode::Kind::kGetEdges,
},
{
Pattern::create(PlanNode::Kind::kArgument),
}),
}),
}),
});
Expand All @@ -56,18 +64,13 @@ StatusOr<OptRule::TransformResult> PushLimitDownFulltextIndexScanRule2::transfor
OptContext *octx, const MatchedResult &matched) const {
auto limitGroupNode = matched.result().node;
const auto limit = static_cast<const Limit *>(limitGroupNode->node());
auto newLimit = static_cast<Limit *>(limit->clone());
newLimit->setOutputVar(limit->outputVar());
auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group());

auto joinGroupNode = matched.result({0, 0}).node;
auto join = static_cast<const HashInnerJoin *>(joinGroupNode->node());
auto newJoin = static_cast<HashInnerJoin *>(join->clone());
auto newJoinGroup = OptGroup::create(octx);
auto newJoinGroupNode = newJoinGroup->makeGroupNode(newJoin);
auto newJoinGroupNode = OptGroupNode::create(octx, newJoin, limitGroupNode->group());

newLimitGroupNode->dependsOn(newJoinGroup);
newLimit->setInputVar(newJoin->outputVar());
newJoin->setOutputVar(limit->outputVar());

auto ftGroupNode = matched.result({0, 0, 0}).node;
const auto ft = static_cast<const FulltextIndexScan *>(ftGroupNode->node());
Expand All @@ -83,16 +86,25 @@ StatusOr<OptRule::TransformResult> PushLimitDownFulltextIndexScanRule2::transfor
newFtGroupNode->dependsOn(dep);
}

auto exploreGroupNode = matched.result({0, 0, 1}).node;
auto projGroupNode = matched.result({0, 0, 1}).node;
auto proj = static_cast<const Project *>(projGroupNode->node());
auto newProj = static_cast<Project *>(proj->clone());
auto newProjGroup = OptGroup::create(octx);
auto newProjGroupNode = newProjGroup->makeGroupNode(newProj);

newJoinGroupNode->dependsOn(newProjGroup);
newJoin->setRightVar(newProj->outputVar());

auto exploreGroupNode = matched.result({0, 0, 1, 0}).node;
auto explore = static_cast<const Explore *>(exploreGroupNode->node());
auto newExplore = static_cast<Explore *>(explore->clone());
auto newExploreGroup = OptGroup::create(octx);
auto newExploreGroupNode = newExploreGroup->makeGroupNode(newExplore);

newJoinGroupNode->dependsOn(newExploreGroup);
newJoin->setRightVar(newExplore->outputVar());
newProjGroupNode->dependsOn(newExploreGroup);
newProj->setInputVar(newExplore->outputVar());

auto argGroupNode = matched.result({0, 0, 1, 0}).node;
auto argGroupNode = matched.result({0, 0, 1, 0, 0}).node;
auto arg = static_cast<const Argument *>(argGroupNode->node());
auto newArg = static_cast<Argument *>(arg->clone());
auto newArgGroup = OptGroup::create(octx);
Expand All @@ -106,7 +118,7 @@ StatusOr<OptRule::TransformResult> PushLimitDownFulltextIndexScanRule2::transfor

TransformResult result;
result.eraseAll = true;
result.newGroupNodes.emplace_back(newLimitGroupNode);
result.newGroupNodes.emplace_back(newJoinGroupNode);
return result;
}

Expand Down
15 changes: 8 additions & 7 deletions src/graph/optimizer/rule/PushLimitDownFulltextIndexScanRule2.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ namespace opt {
//
// Limit (count=3, offset=1)
// `- HashInnerJoin
// |- GetVertices/GetEdges
// | `- Argument
// |- Project
// | `- GetVertices/GetEdges
// | `- Argument
// `- FulltextIndexScan
//
// After:
//
// Limit (count=3, offset=1)
// `- HashInnerJoin
// |- GetVertices/GetEdges
// | `- Argument
// `- FulltextIndexScan (limit=4, offset=1)
// HashInnerJoin
// |- Project
// | `- GetVertices/GetEdges
// | `- Argument
// `-FulltextIndexScan (limit=4, offset=1)
//

class PushLimitDownFulltextIndexScanRule2 final : public OptRule {
Expand Down
72 changes: 59 additions & 13 deletions tests/tck/features/fulltext_index/FulltextIndexScan.feature
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Feature: FulltextIndexTest
When executing query:
"""
CREATE FULLTEXT TAG INDEX nebula_index_tag2_prop1 on tag2(prop1);
CREATE FULLTEXT TAG INDEX nebula_index_tag2_prop2 on tag2(prop2);
CREATE FULLTEXT TAG INDEX nebula_index_tag2_props on tag2(prop1, prop2);
CREATE FULLTEXT EDGE INDEX nebula_index_edge2_prop1 on edge2(prop1);
"""
Then the execution should be successful
Expand Down Expand Up @@ -53,7 +53,7 @@ Feature: FulltextIndexTest
"""
Then the execution should be successful
And wait 10 seconds
When executing query:
When profiling query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop1, "abc")
Expand All @@ -65,7 +65,13 @@ Feature: FulltextIndexTest
Then the result should be, in any order:
| id | prop1 | prop2 |
| "1" | "abc" | "nebula graph" |
When executing query:
And the execution plan should be:
| id | name | dependencies | profiling data | operator info |
| 5 | Project | 14 | | |
| 14 | GetVertices | 15 | | |
| 15 | FulltextIndexScan | 0 | | |
| 0 | Start | | | |
When profiling query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop1, "abc")
Expand All @@ -78,7 +84,14 @@ Feature: FulltextIndexTest
Then the result should be, in any order:
| id | prop1 | prop2 |
| "1" | "abc" | "nebula graph" |
When executing query:
And the execution plan should be:
| id | name | dependencies | profiling data | operator info |
| 10 | Project | 11 | | |
| 11 | Limit | 13 | | {"count": 3} |
| 13 | GetVertices | 14 | | {"limit": 3} |
| 14 | FulltextIndexScan | 0 | | {"limit": 3} |
| 0 | Start | | | |
When profiling query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop1, "abc")
Expand All @@ -90,7 +103,13 @@ Feature: FulltextIndexTest
"""
Then the result should be, in any order:
| id | prop1 | prop2 |
When executing query:
And the execution plan should be:
| id | name | dependencies | profiling data | operator info |
| 10 | Project | 15 | | |
| 15 | GetVertices | 16 | | {"limit":4} |
| 16 | FulltextIndexScan | 0 | | {"offset":1, "limit":4} |
| 0 | Start | | | |
When profiling query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop1, "abc")
Expand All @@ -103,7 +122,16 @@ Feature: FulltextIndexTest
Then the result should be, in any order:
| id | prop1 | prop2 | sc |
| "1" | "abc" | "nebula graph" | 1.7917595 |
When executing query:
And the execution plan should be:
| id | name | dependencies | profiling data | operator info |
| 6 | Project | 5 | | |
| 5 | HashInnerJoin | 1,4 | | |
| 1 | FulltextIndexScan | 0 | | |
| 0 | Start | | | |
| 4 | Project | 3 | | |
| 3 | GetVertices | 2 | | |
| 2 | Argument | | | |
When profiling query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop1, "abc")
Expand All @@ -117,7 +145,16 @@ Feature: FulltextIndexTest
Then the result should be, in any order:
| id | prop1 | prop2 | sc |
| "1" | "abc" | "nebula graph" | 1.7917595 |
When executing query:
And the execution plan should be:
| id | name | dependencies | profiling data | operator info |
| 9 | Project | 10 | | |
| 10 | HashInnerJoin | 11,12 | | |
| 11 | FulltextIndexScan | 0 | | {"limit":3} |
| 0 | Start | | | |
| 12 | Project | 13 | | |
| 13 | GetVertices | 14 | | |
| 14 | Argument | | | |
When profiling query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop1, "abc")
Expand All @@ -130,10 +167,19 @@ Feature: FulltextIndexTest
"""
Then the result should be, in any order:
| id | prop1 | prop2 | sc |
And the execution plan should be:
| id | name | dependencies | profiling data | operator info |
| 9 | Project | 10 | | |
| 10 | HashInnerJoin | 11,12 | | |
| 11 | FulltextIndexScan | 0 | | {"offset":1,"limit":4} |
| 0 | Start | | | |
| 12 | Project | 13 | | |
| 13 | GetVertices | 14 | | |
| 14 | Argument | | | |
When executing query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop2, "nebula")
WHERE ES_QUERY(nebula_index_tag2_props, "nebula")
YIELD
id(vertex) AS id,
tag2.prop1 AS prop1,
Expand All @@ -152,7 +198,7 @@ Feature: FulltextIndexTest
When executing query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop2, "nebula")
WHERE ES_QUERY(nebula_index_tag2_props, "nebula")
YIELD
id(vertex) AS id,
tag2.prop1 AS prop1,
Expand All @@ -167,7 +213,7 @@ Feature: FulltextIndexTest
When executing query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop2, "nebula")
WHERE ES_QUERY(nebula_index_tag2_props, "nebula")
YIELD
id(vertex) AS id,
tag2.prop1 AS prop1,
Expand All @@ -182,7 +228,7 @@ Feature: FulltextIndexTest
When executing query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop2, "nebula")
WHERE ES_QUERY(nebula_index_tag2_props, "nebula")
YIELD
id(vertex) AS id,
tag2.prop1 AS prop1,
Expand All @@ -202,7 +248,7 @@ Feature: FulltextIndexTest
When executing query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop2, "nebula")
WHERE ES_QUERY(nebula_index_tag2_props, "nebula")
YIELD
id(vertex) AS id,
tag2.prop1 AS prop1,
Expand All @@ -218,7 +264,7 @@ Feature: FulltextIndexTest
When executing query:
"""
LOOKUP ON tag2
WHERE ES_QUERY(nebula_index_tag2_prop2, "nebula")
WHERE ES_QUERY(nebula_index_tag2_props, "nebula")
YIELD
id(vertex) AS id,
tag2.prop1 AS prop1,
Expand Down

0 comments on commit cbf879e

Please sign in to comment.