Skip to content
This repository has been archived by the owner on Dec 1, 2022. It is now read-only.

Fix use same filters to lookup index #1213

Merged
merged 8 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 64 additions & 22 deletions src/optimizer/OptimizerUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ using nebula::storage::cpp2::IndexColumnHint;
using nebula::storage::cpp2::IndexQueryContext;

using BVO = nebula::graph::OptimizerUtils::BoundValueOperator;
using ExprKind = nebula::Expression::Kind;

namespace nebula {
namespace graph {
Expand Down Expand Up @@ -682,25 +683,49 @@ StatusOr<IndexResult> selectRelExprIndex(const RelationalExpression* expr, const
return result;
}

bool mergeRangeColumnHints(const std::vector<ScoredColumnHint>& hints, Value* begin, Value* end) {
bool mergeRangeColumnHints(const ColumnDef& field,
const std::vector<ScoredColumnHint>& hints,
Value* begin,
Value* end) {
for (auto& h : hints) {
if (h.score != IndexScore::kRange) {
return false;
}
if (h.hint.begin_value_ref().is_set()) {
const auto& value = h.hint.get_begin_value();
if (begin->empty() || *begin < value) {
*begin = value;
switch (h.score) {
case IndexScore::kRange: {
if (h.hint.begin_value_ref().is_set()) {
const auto& value = h.hint.get_begin_value();
if (begin->empty() || *begin < value) {
*begin = value;
}
}
if (h.hint.end_value_ref().is_set()) {
const auto& value = h.hint.get_end_value();
if (end->empty() || *end > value) {
*end = value;
}
}
break;
}
case IndexScore::kPrefix: {
// Prefix value <=> range [value, value]
const auto& value = h.hint.get_begin_value();
Value b, e;
auto status = OptimizerUtils::boundValue(ExprKind::kRelGE, value, field, b, e);
if (!status.ok()) return false;
if (begin->empty() || *begin < b) {
*begin = b;
}
status = OptimizerUtils::boundValue(ExprKind::kRelLE, value, field, b, e);
if (!status.ok()) return false;
if (end->empty() || *end > e) {
*end = e;
}
break;
}
}
if (h.hint.end_value_ref().is_set()) {
const auto& value = h.hint.get_end_value();
if (end->empty() || *end > value) {
*end = value;
case IndexScore::kNotEqual: {
return false;
}
}
}
return !(*begin > *end);
return !(*begin >= *end);
}

bool getIndexColumnHintInExpr(const ColumnDef& field,
Expand All @@ -722,20 +747,37 @@ bool getIndexColumnHintInExpr(const ColumnDef& field,

if (hints.size() == 1) {
*hint = hints.front();
} else {
Value begin, end;
if (!mergeRangeColumnHints(hints, &begin, &end)) {
return false;
}
ScoredColumnHint h;
h.hint.set_column_name(field.get_name());
return true;
}
Value begin, end;
if (!mergeRangeColumnHints(field, hints, &begin, &end)) {
return false;
}
ScoredColumnHint h;
h.hint.set_column_name(field.get_name());
// Change scan type to prefix if begin + 1 == end
Value newBegin, newEnd;
auto status = OptimizerUtils::boundValue(ExprKind::kRelGT, begin, field, newBegin, newEnd);
if (!status.ok()) {
// TODO(yee): differentiate between empty set and invalid index to use
return false;
}
if (newBegin < end) {
// end > newBegin > begin
h.hint.set_scan_type(storage::cpp2::ScanType::RANGE);
h.hint.set_begin_value(std::move(begin));
h.hint.set_end_value(std::move(end));
h.score = IndexScore::kRange;
*hint = std::move(h);
} else if (newBegin == end) {
// end == neBegin == begin + 1
h.hint.set_scan_type(storage::cpp2::ScanType::PREFIX);
h.hint.set_begin_value(std::move(begin));
h.score = IndexScore::kPrefix;
} else {
return false;
}

*hint = std::move(h);
return true;
}

Expand Down
4 changes: 4 additions & 0 deletions tests/tck/features/lookup/LookupEdge.feature
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Feature: Test lookup on edge index
| lookup_edge_1.col1 >= 201 AND lookup_edge_1.col2 >= 201 AND lookup_edge_1.col3 == 201 |
| lookup_edge_1.col1 >= 201 AND lookup_edge_1.col2 != 200 AND lookup_edge_1.col3 == 201 |
| lookup_edge_1.col1 != 200 AND lookup_edge_1.col2 != 200 AND lookup_edge_1.col3 == 201 |
| lookup_edge_1.col1 == 201 AND lookup_edge_1.col2 >= 201 AND lookup_edge_1.col1 == 201 |
| lookup_edge_1.col1 == 201 AND lookup_edge_1.col2 >= 201 AND lookup_edge_1.col1 >= 201 |
| lookup_edge_1.col1 == 201 AND lookup_edge_1.col2 > 200 AND lookup_edge_1.col1 == 201 |
| lookup_edge_1.col1 == 201 AND lookup_edge_1.col2 > 200 AND lookup_edge_1.col1 > 200 |
| lookup_edge_1.col1 == 201 OR lookup_edge_1.col2 == 201 |
| lookup_edge_1.col1 == 201 OR lookup_edge_1.col2 >= 203 |
| lookup_edge_1.col1 == 201 OR lookup_edge_1.col3 == 201 |
Expand Down
6 changes: 6 additions & 0 deletions tests/tck/features/lookup/LookupEdge2.feature
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,10 @@ Feature: Test lookup on edge index 2
"""
Then the result should be, in any order:
| SrcVID | DstVID | Ranking |
When executing query:
"""
LOOKUP ON lookup_edge_1 WHERE lookup_edge_1.col1 == 201 AND lookup_edge_1.col2 > 200 AND lookup_edge_1.col1 > 201
"""
Then the result should be, in any order:
| SrcVID | DstVID | Ranking |
Then drop the used space
4 changes: 4 additions & 0 deletions tests/tck/features/lookup/LookupTag.feature
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Feature: Test lookup on tag index
| lookup_tag_1.col1 != 202 AND lookup_tag_1.col2 == 201 AND lookup_tag_1.col3 == 201 |
| lookup_tag_1.col1 != 202 AND lookup_tag_1.col2 == 201 AND lookup_tag_1.col3 >= 201 |
| lookup_tag_1.col1 != 202 AND lookup_tag_1.col2 >= 201 AND lookup_tag_1.col3 >= 201 |
| lookup_tag_1.col1 == 201 AND lookup_tag_1.col2 >= 201 AND lookup_tag_1.col1 == 201 |
| lookup_tag_1.col1 == 201 AND lookup_tag_1.col2 >= 201 AND lookup_tag_1.col1 >= 201 |
| lookup_tag_1.col1 == 201 AND lookup_tag_1.col2 > 200 AND lookup_tag_1.col1 == 201 |
| lookup_tag_1.col1 == 201 AND lookup_tag_1.col2 > 200 AND lookup_tag_1.col1 > 200 |
| lookup_tag_1.col1 == 201 OR lookup_tag_1.col2 == 201 |
| lookup_tag_1.col1 == 201 OR lookup_tag_1.col2 >= 203 |
| lookup_tag_1.col1 == 201 OR lookup_tag_1.col3 == 201 |
Expand Down
6 changes: 6 additions & 0 deletions tests/tck/features/lookup/LookupTag2.feature
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ Feature: Test lookup on tag index 2
"""
Then the result should be, in any order:
| VertexID |
When executing query:
"""
lookup on lookup_tag_1 WHERE lookup_tag_1.col1 == 201 AND lookup_tag_1.col2 > 200 AND lookup_tag_1.col1 > 201
"""
Then the result should be, in any order:
| VertexID |
Then drop the used space

Scenario Outline: [tag] scan without hints
Expand Down