This repository has been archived by the owner on Dec 1, 2022. It is now read-only.
Match by tag index. #485
Merged
Merged
Match by tag index. #485
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
22a0532
Match by tag index.
Shylock-Hg a589c68
Add the extend test cases.
Shylock-Hg d39f665
Merge branch 'master' into feature/match-by-tag
Shylock-Hg 54dafe8
Merge branch 'feature/match-by-tag' of github.com:Shylock-Hg/nebula-g…
Shylock-Hg 51cdb50
Merge branch 'master' into feature/match-by-tag
Shylock-Hg ff110be
Merge branch 'master' into feature/match-by-tag
Shylock-Hg 8947e65
Merge branch 'master' into feature/match-by-tag
Shylock-Hg b477ae8
Merge branch 'master' into feature/match-by-tag
Shylock-Hg cbbb16d
Address @CPWstatic's comment that need check the index when match pat…
Shylock-Hg bb668fe
Merge branch 'master' into feature/match-by-tag
Shylock-Hg ea5caf0
Merge branch 'master' of github.com:vesoft-inc/nebula-graph into feat…
Shylock-Hg 18b399d
Merge branch 'master' into feature/match-by-tag
Shylock-Hg f1e8920
Merge branch 'master' into feature/match-by-tag
Shylock-Hg 44bd0c5
Rebase the tag filter.
Shylock-Hg 2507a2f
Merge branch 'master' into feature/match-by-tag
Shylock-Hg 8ca8030
Fix the memory leak.
Shylock-Hg 1e0afb0
Merge branch 'master' into feature/match-by-tag
Shylock-Hg f5344de
Fix the format.
Shylock-Hg f68dbbe
Merge branch 'master' into feature/match-by-tag
Shylock-Hg d4d04c2
Merge branch 'master' into feature/match-by-tag
Shylock-Hg 949676b
Merge branch 'master' into feature/match-by-tag
bright-starry-sky 7aa893d
Rebase.
Shylock-Hg 504563c
Merge branch 'master' into feature/match-by-tag
CPWstatic File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,4 +34,5 @@ nebula_add_library( | |
match/PropIndexSeek.cpp | ||
match/VertexIdSeek.cpp | ||
match/Expand.cpp | ||
match/LabelIndexSeek.cpp | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* Copyright (c) 2020 vesoft inc. All rights reserved. | ||
* | ||
* This source code is licensed under Apache 2.0 License, | ||
* attached with Common Clause Condition 1.0, found in the LICENSES directory. | ||
*/ | ||
|
||
#include "planner/match/LabelIndexSeek.h" | ||
#include "planner/Query.h" | ||
#include "planner/match/MatchSolver.h" | ||
#include "util/ExpressionUtils.h" | ||
|
||
namespace nebula { | ||
namespace graph { | ||
|
||
bool LabelIndexSeek::matchNode(NodeContext* nodeCtx) { | ||
auto& node = *nodeCtx->info; | ||
// only require the tag | ||
if (node.tid <= 0) { | ||
return false; | ||
} | ||
|
||
nodeCtx->scanInfo.schemaId = node.tid; | ||
nodeCtx->scanInfo.schemaName = node.label; | ||
|
||
auto indexResult = pickTagIndex(nodeCtx); | ||
if (!indexResult.ok()) { | ||
return false; | ||
} | ||
|
||
nodeCtx->scanInfo.indexId = indexResult.value(); | ||
|
||
return true; | ||
} | ||
|
||
bool LabelIndexSeek::matchEdge(EdgeContext*) { | ||
// TODO | ||
return false; | ||
} | ||
|
||
StatusOr<SubPlan> LabelIndexSeek::transformNode(NodeContext* nodeCtx) { | ||
SubPlan plan; | ||
auto* matchClauseCtx = nodeCtx->matchClauseCtx; | ||
using IQC = nebula::storage::cpp2::IndexQueryContext; | ||
IQC iqctx; | ||
iqctx.set_index_id(nodeCtx->scanInfo.indexId); | ||
auto contexts = std::make_unique<std::vector<IQC>>(); | ||
contexts->emplace_back(std::move(iqctx)); | ||
auto columns = std::make_unique<std::vector<std::string>>(); | ||
columns->emplace_back(kVid); | ||
auto scan = IndexScan::make(matchClauseCtx->qctx, | ||
nullptr, | ||
matchClauseCtx->space.id, | ||
std::move(contexts), | ||
std::move(columns), | ||
false, | ||
nodeCtx->scanInfo.schemaId); | ||
scan->setColNames({kVid}); | ||
plan.tail = scan; | ||
plan.root = scan; | ||
|
||
// initialize start expression in project node | ||
nodeCtx->initialExpr.reset(ExpressionUtils::newVarPropExpr(kVid)); | ||
return plan; | ||
} | ||
|
||
StatusOr<SubPlan> LabelIndexSeek::transformEdge(EdgeContext*) { | ||
// TODO | ||
return Status::Error("TODO"); | ||
} | ||
|
||
/*static*/ StatusOr<IndexID> LabelIndexSeek::pickTagIndex(const NodeContext* nodeCtx) { | ||
auto tagId = nodeCtx->scanInfo.schemaId; | ||
const auto* qctx = nodeCtx->matchClauseCtx->qctx; | ||
auto tagIndexesResult = qctx->indexMng()->getTagIndexes(nodeCtx->matchClauseCtx->space.id); | ||
NG_RETURN_IF_ERROR(tagIndexesResult); | ||
auto tagIndexes = std::move(tagIndexesResult).value(); | ||
std::shared_ptr<meta::cpp2::IndexItem> candidateIndex{nullptr}; | ||
for (const auto& index : tagIndexes) { | ||
if (index->get_schema_id().get_tag_id() == tagId) { | ||
if (candidateIndex == nullptr) { | ||
candidateIndex = index; | ||
} else { | ||
candidateIndex = selectIndex(candidateIndex, index); | ||
} | ||
} | ||
} | ||
if (candidateIndex == nullptr) { | ||
return Status::SemanticError("No valid index for label `%s'.", | ||
nodeCtx->scanInfo.schemaName->c_str()); | ||
} | ||
return candidateIndex->get_index_id(); | ||
} | ||
|
||
} // namespace graph | ||
} // namespace nebula |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* Copyright (c) 2020 vesoft inc. All rights reserved. | ||
* | ||
* This source code is licensed under Apache 2.0 License, | ||
* attached with Common Clause Condition 1.0, found in the LICENSES directory. | ||
*/ | ||
|
||
#ifndef PLANNER_MATCH_LABELINDEXSEEK_H_ | ||
#define PLANNER_MATCH_LABELINDEXSEEK_H_ | ||
|
||
#include "planner/match/StartVidFinder.h" | ||
|
||
namespace nebula { | ||
namespace graph { | ||
|
||
/* | ||
* The LabelIndexSeek was designed to find if could get the starting vids by tag index. | ||
*/ | ||
class LabelIndexSeek final : public StartVidFinder { | ||
public: | ||
static std::unique_ptr<LabelIndexSeek> make() { | ||
return std::unique_ptr<LabelIndexSeek>(new LabelIndexSeek()); | ||
} | ||
|
||
private: | ||
LabelIndexSeek() = default; | ||
|
||
bool matchNode(NodeContext* nodeCtx) override; | ||
|
||
bool matchEdge(EdgeContext* edgeCtx) override; | ||
|
||
StatusOr<SubPlan> transformNode(NodeContext* nodeCtx) override; | ||
|
||
StatusOr<SubPlan> transformEdge(EdgeContext* edgeCtx) override; | ||
|
||
static StatusOr<IndexID> pickTagIndex(const NodeContext* nodeCtx); | ||
|
||
static std::shared_ptr<meta::cpp2::IndexItem> selectIndex( | ||
const std::shared_ptr<meta::cpp2::IndexItem> candidate, | ||
const std::shared_ptr<meta::cpp2::IndexItem> income) { | ||
// less fields is better | ||
// TODO(shylock) rank for field itself(e.g. INT is better than STRING) | ||
if (candidate->get_fields().size() > income->get_fields().size()) { | ||
return income; | ||
} | ||
return candidate; | ||
} | ||
}; | ||
|
||
} // namespace graph | ||
} // namespace nebula | ||
#endif // PLANNER_MATCH_LABELINDEXSEEK_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* Copyright (c) 2020 vesoft inc. All rights reserved. | ||
* | ||
* This source code is licensed under Apache 2.0 License, | ||
* attached with Common Clause Condition 1.0, found in the LICENSES directory. | ||
*/ | ||
|
||
#include "validator/MatchValidator.h" | ||
|
||
#include "validator/test/ValidatorTestBase.h" | ||
|
||
namespace nebula { | ||
namespace graph { | ||
|
||
class MatchValidatorTest : public ValidatorTestBase {}; | ||
|
||
TEST_F(MatchValidatorTest, SeekByTagIndex) { | ||
// empty properties index | ||
{ | ||
std::string query = "MATCH (v:person) RETURN id(v) AS id;"; | ||
std::vector<PlanNode::Kind> expected = {PlanNode::Kind::kProject, | ||
PlanNode::Kind::kFilter, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kProject, | ||
// TODO this tag filter could remove in this case | ||
PlanNode::Kind::kFilter, | ||
PlanNode::Kind::kGetVertices, | ||
PlanNode::Kind::kDedup, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kIndexScan, | ||
PlanNode::Kind::kStart}; | ||
EXPECT_TRUE(checkResult(query, expected)); | ||
} | ||
// non empty properties index | ||
{ | ||
std::string query = "MATCH (v:book) RETURN id(v) AS id;"; | ||
std::vector<PlanNode::Kind> expected = {PlanNode::Kind::kProject, | ||
PlanNode::Kind::kFilter, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kProject, | ||
// TODO this tag filter could remove in this case | ||
PlanNode::Kind::kFilter, | ||
PlanNode::Kind::kGetVertices, | ||
PlanNode::Kind::kDedup, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kIndexScan, | ||
PlanNode::Kind::kStart}; | ||
EXPECT_TRUE(checkResult(query, expected)); | ||
} | ||
// non empty properties index with extend | ||
{ | ||
std::string query = "MATCH (p:person)-[:like]->(b:book) RETURN b.name AS book;"; | ||
std::vector<PlanNode::Kind> expected = {PlanNode::Kind::kProject, | ||
PlanNode::Kind::kFilter, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kDataJoin, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kFilter, | ||
PlanNode::Kind::kGetVertices, | ||
PlanNode::Kind::kDedup, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kFilter, | ||
PlanNode::Kind::kPassThrough, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kFilter, | ||
PlanNode::Kind::kGetNeighbors, | ||
PlanNode::Kind::kDedup, | ||
PlanNode::Kind::kProject, | ||
PlanNode::Kind::kIndexScan, | ||
PlanNode::Kind::kStart}; | ||
EXPECT_TRUE(checkResult(query, expected)); | ||
} | ||
// non index | ||
{ | ||
std::string query = "MATCH (v:room) RETURN id(v) AS id;"; | ||
EXPECT_FALSE(validate(query)); | ||
} | ||
} | ||
|
||
} // namespace graph | ||
} // namespace nebula |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* Copyright (c) 2020 vesoft inc. All rights reserved. | ||
* | ||
* This source code is licensed under Apache 2.0 License, | ||
* attached with Common Clause Condition 1.0, found in the LICENSES directory. | ||
*/ | ||
|
||
#include "validator/test/MockIndexManager.h" | ||
#include <memory> | ||
#include <vector> | ||
|
||
// tag index: | ||
// person() | ||
// book(name(32)) | ||
|
||
namespace nebula { | ||
namespace graph { | ||
|
||
void MockIndexManager::init() { | ||
// index related | ||
meta::cpp2::IndexItem person_no_props_index; | ||
person_no_props_index.set_index_id(233); | ||
person_no_props_index.set_index_name("person_no_props_index"); | ||
meta::cpp2::SchemaID personSchemaId; | ||
personSchemaId.set_tag_id(2); | ||
person_no_props_index.set_schema_id(std::move(personSchemaId)); | ||
person_no_props_index.set_schema_name("person"); | ||
|
||
meta::cpp2::IndexItem book_name_index; | ||
book_name_index.set_index_id(234); | ||
book_name_index.set_index_name("book_name_index"); | ||
meta::cpp2::SchemaID bookSchemaId; | ||
bookSchemaId.set_tag_id(5); | ||
book_name_index.set_schema_id(std::move(bookSchemaId)); | ||
book_name_index.set_schema_name("book"); | ||
meta::cpp2::ColumnDef field; | ||
field.set_name("name"); | ||
meta::cpp2::ColumnTypeDef type; | ||
type.set_type(meta::cpp2::PropertyType::FIXED_STRING); | ||
type.set_type_length(32); | ||
field.set_type(std::move(type)); | ||
book_name_index.set_fields({}); | ||
book_name_index.fields.emplace_back(std::move(field)); | ||
|
||
tagIndexes_.emplace(1, std::vector<std::shared_ptr<meta::cpp2::IndexItem>>{}); | ||
tagIndexes_[1].emplace_back( | ||
std::make_shared<meta::cpp2::IndexItem>(std::move(person_no_props_index))); | ||
tagIndexes_[1].emplace_back( | ||
std::make_shared<meta::cpp2::IndexItem>(std::move(book_name_index))); | ||
} | ||
|
||
} // namespace graph | ||
} // namespace nebula |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should check if there exists index for such a tag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Fixed.