Skip to content

Commit

Permalink
fix index degeneration
Browse files Browse the repository at this point in the history
  • Loading branch information
czpmango committed Nov 16, 2021
1 parent e32c06d commit 14a1811
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 8 deletions.
14 changes: 6 additions & 8 deletions src/graph/optimizer/rule/IndexScanRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ StatusOr<OptRule::TransformResult> IndexScanRule::transform(OptContext* ctx,
FilterItems items;
ScanKind kind;
NG_RETURN_IF_ERROR(analyzeExpression(filter, &items, &kind, isEdge(groupNode)));
NG_RETURN_IF_ERROR(createIndexQueryCtx(iqctx, kind, items, qctx, groupNode));
auto status = createIndexQueryCtx(iqctx, kind, items, qctx, groupNode);
if (!status.ok()) {
NG_RETURN_IF_ERROR(createIndexQueryCtx(iqctx, qctx, groupNode));
}
}

const auto* oldIN = groupNode->node();
Expand Down Expand Up @@ -481,20 +484,15 @@ std::vector<IndexItem> IndexScanRule::findValidIndex(graph::QueryContext* qctx,
std::vector<IndexItem> validIndexes;
// Find indexes for match all fields by where condition.
for (const auto& index : indexes) {
bool allColsHint = true;
const auto& fields = index->get_fields();
for (const auto& item : items.items) {
auto it = std::find_if(fields.begin(), fields.end(), [item](const auto& field) {
return field.get_name() == item.col_;
});
if (it == fields.end()) {
allColsHint = false;
break;
if (it != fields.end()) {
validIndexes.emplace_back(index);
}
}
if (allColsHint) {
validIndexes.emplace_back(index);
}
}
// If the first field of the index does not match any condition, the index is
// invalid. remove it from validIndexes.
Expand Down
109 changes: 109 additions & 0 deletions tests/tck/features/match/Index.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Copyright (c) 2021 vesoft inc. All rights reserved.
#
# This source code is licensed under Apache 2.0 License.
Feature: Index selecting for match statement

Background: Prepare a new space
Given an empty graph
And create a space with following options:
| partition_num | 9 |
| replica_factor | 1 |
| vid_type | FIXED_STRING(30) |
| charset | utf8 |
| collate | utf8_bin |
And having executed:
"""
CREATE tag player(name string, age int, score int, gender bool);
"""
And having executed:
"""
INSERT VERTEX player(name, age, score, gender) VALUES "Tim Duncan":("Tim Duncan", 42, 28, true),"Yao Ming":("Yao Ming", 38, 23, true),"Nneka Ogwumike":("Nneka Ogwumike", 35, 13, false);
"""
And having executed:
"""
create tag index player_index on player();
create tag index player_name_index on player(name(8));
create tag index player_age_name_index on player(age,name(8));
"""
And wait 3 seconds

Scenario: Test Index selecting
When submit a job:
"""
rebuild tag index player_index;
"""
Then wait the job to finish
When submit a job:
"""
rebuild tag index player_name_index;
"""
Then wait the job to finish
When submit a job:
"""
rebuild tag index player_age_name_index;
"""
Then wait the job to finish
# Prefix Index
When profiling query:
"""
MATCH (v:player {name: "Yao Ming"}) RETURN v.name AS name
"""
Then the result should be, in any order, with relax comparison:
| name |
| "Yao Ming" |
And the execution plan should be:
| id | name | dependencies | operator info |
| 9 | Project | 8 | |
| 8 | Filter | 7 | |
| 7 | Project | 6 | |
| 6 | Project | 5 | |
| 5 | Filter | 14 | |
| 14 | GetVertices | 10 | |
| 10 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"PREFIX"}}} |
| 0 | Start | | |
# Range Index
When profiling query:
"""
MATCH (v:player) WHERE v.name > "Tim" and v.name < "Zom" RETURN v.name AS name
"""
Then the result should be, in any order, with relax comparison:
| name |
| "Yao Ming" |
| "Tim Duncan" |
And the execution plan should be:
| id | name | dependencies | operator info |
| 10 | Project | 13 | |
| 13 | Filter | 7 | |
| 7 | Project | 6 | |
| 6 | Project | 5 | |
| 5 | Filter | 16 | |
| 16 | GetVertices | 11 | |
| 11 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE"}}} |
| 0 | Start | | |
# Degeneration to FullScan Index
When executing query:
"""
MATCH (v:player) WHERE v.score < 20 RETURN v.name AS name
"""
Then the result should be, in any order, with relax comparison:
| name |
| "Nneka Ogwumike" |
# Degeneration to Prefix Index
When profiling query:
"""
MATCH (v:player) WHERE v.name == "Tim Duncan" and v.score == 28 RETURN v.name AS name
"""
Then the result should be, in any order, with relax comparison:
| name |
| "Tim Duncan" |
And the execution plan should be:
| id | name | dependencies | operator info |
| 10 | Project | 13 | |
| 13 | Filter | 7 | |
| 7 | Project | 6 | |
| 6 | Project | 5 | |
| 5 | Filter | 16 | |
| 16 | GetVertices | 11 | |
| 11 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"PREFIX"}}} |
| 0 | Start | | |
Then drop the used space

0 comments on commit 14a1811

Please sign in to comment.