Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add alias check for lookup #2000

Merged
merged 4 commits into from
Mar 31, 2020
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
19 changes: 19 additions & 0 deletions src/graph/LookupExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ Status LookupExecutor::prepareYield() {
return Status::SyntaxError("Expressions other than AliasProp are not supported");
}
auto* aExpr = dynamic_cast<const AliasPropertyExpression*>(prop);
auto st = checkAliasProperty(aExpr);
if (!st.ok()) {
return st;
}
if (schema->getFieldIndex(aExpr->prop()->c_str()) < 0) {
LOG(ERROR) << "Unknown column " << aExpr->prop()->c_str();
return Status::Error("Unknown column `%s' in schema", aExpr->prop()->c_str());
Expand All @@ -139,6 +143,13 @@ Status LookupExecutor::prepareYield() {
return Status::OK();
}

Status LookupExecutor::checkAliasProperty(const AliasPropertyExpression* aExpr) {
if (*aExpr->alias() != *from_) {
return Status::SyntaxError("Edge or Tag name error : %s ", aExpr->alias()->c_str());
}
return Status::OK();
}

Status LookupExecutor::optimize() {
Status status = Status::OK();
do {
Expand Down Expand Up @@ -183,10 +194,18 @@ Status LookupExecutor::traversalExpr(const Expression *expr) {
*/
if (left->kind() == nebula::Expression::kAliasProp) {
auto* aExpr = dynamic_cast<const AliasPropertyExpression*>(left);
auto st = checkAliasProperty(aExpr);
if (!st.ok()) {
return st;
}
prop = *aExpr->prop();
filters_.emplace_back(std::make_pair(prop, rExpr->op()));
} else if (right->kind() == nebula::Expression::kAliasProp) {
auto* aExpr = dynamic_cast<const AliasPropertyExpression*>(right);
auto st = checkAliasProperty(aExpr);
if (!st.ok()) {
return st;
}
prop = *aExpr->prop();
filters_.emplace_back(std::make_pair(prop, rExpr->op()));
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/graph/LookupExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class LookupExecutor final : public TraverseExecutor {

Status prepareYield();

Status checkAliasProperty(const AliasPropertyExpression* aExpr);

Status optimize();

Status traversalExpr(const Expression *expr);
Expand Down
60 changes: 60 additions & 0 deletions src/graph/test/LookupTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,5 +687,65 @@ TEST_F(LookupTest, FunctionExprTest) {
}
}

TEST_F(LookupTest, YieldClauseTest) {
{
cpp2::ExecutionResponse resp;
auto stmt = "CREATE TAG student(name string, age int)";
auto code = client_->execute(stmt, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
{
cpp2::ExecutionResponse resp;
auto stmt = "CREATE TAG INDEX student_index ON student(name, age)";
auto code = client_->execute(stmt, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
{
cpp2::ExecutionResponse resp;
auto stmt = "CREATE TAG teacher(name string, age int)";
auto code = client_->execute(stmt, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
sleep(FLAGS_heartbeat_interval_secs + 1);
{
cpp2::ExecutionResponse resp;
auto query = "INSERT VERTEX student(name, age), teacher(name, age) VALUES "
"220:(\"student_1\", 20, \"teacher_1\", 30), "
"221:(\"student_2\", 22, \"teacher_1\", 32)";
auto code = client_->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
// Invalid tag name in yield clause.
{
cpp2::ExecutionResponse resp;
auto query = "LOOKUP ON student WHERE student.name == \"student_1\" YIELD teacher.age";
auto code = client_->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
}
// Invalid tag name in yield clause. and Alias is same with tag name.
{
cpp2::ExecutionResponse resp;
auto query = "LOOKUP ON student WHERE student.name == \"student_1\" YIELD teacher.age"
" as student_name";
auto code = client_->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
}
// Invalid tag name in where clause.
{
cpp2::ExecutionResponse resp;
auto query = "LOOKUP ON student WHERE teacher.name == \"student_1\" YIELD student.age";
auto code = client_->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
}
{
cpp2::ExecutionResponse resp;
auto query = "LOOKUP ON student WHERE student.name == \"student_1\" YIELD student.age";
auto code = client_->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
std::vector<std::tuple<VertexID, int64_t>> expected = {{220, 20}};
ASSERT_TRUE(verifyResult(resp, expected));
}
}

} // namespace graph
} // namespace nebula