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

fix bug:Using the same statement to return same vertex different properties, the results show BAD TYPE. #4151

Merged
merged 23 commits into from
Apr 26, 2022

Conversation

zhaohaifei
Copy link
Contributor

@zhaohaifei zhaohaifei commented Apr 13, 2022

What type of PR is this?

  • bug
  • feature
  • enhancement

What problem(s) does this PR solve?

Issue(s) number:

#4076

Description:

Using the same statement to return same vertex different properties, the results show BAD TYPE.

How do you solve it?

Special notes for your reviewer, ex. impact of this fix, design document, etc:

Checklist:

Tests:

  • Unit test(positive and negative cases)
  • Function test
  • Performance test
  • N/A

Affects:

  • Documentation affected (Please add the label if documentation needs to be modified.)
  • Incompatibility (If it breaks the compatibility, please describe it and add the label.)
  • If it's needed to cherry-pick (If cherry-pick to some branches is required, please label the destination version(s).)
  • Performance impacted: Consumes more CPU/Memory

Release notes:

Please confirm whether to be reflected in release notes and how to describe:

ex. Fixed the bug .....
Fixed the bug:Using the same statement to return same vertex different properties, the results show BAD TYPE.

@zhaohaifei zhaohaifei added ready-for-testing PR: ready for the CI test wip Solution: work in progress labels Apr 13, 2022
@Sophie-Xie Sophie-Xie added the cherry-pick-v3.1 PR: need cherry-pick to this version label Apr 13, 2022
@zhaohaifei zhaohaifei changed the title fix bug fix bug:Using the same statement to return same vertex different properties, the results show BAD TYPE. Apr 14, 2022
@@ -818,9 +823,16 @@ Status MatchValidator::validateGroup(YieldClauseContext &yieldCtx,

yieldCtx.needGenProject_ = true;
yieldCtx.aggOutputColumnNames_.emplace_back(agg->toString());

for (auto *labelExpr : labelExprs) {
yieldCtx.groupKeys_.emplace_back(labelExpr->clone());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

match (v) return {abs(v.age),count(v.name)+1}
You should groupby abs(v.age) rather than v.age.

@zhaohaifei zhaohaifei added ready for review and removed wip Solution: work in progress labels Apr 19, 2022
@czpmango
Copy link
Contributor

Please add test cases related to the issue you want to fix.

namespace nebula {
namespace graph {

class ExtractGroupSuiteVisitor : public ExprVisitorImpl {
Copy link
Contributor

@czpmango czpmango Apr 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add unit test for ExtractGroupSuiteVisitor.

@Sophie-Xie Sophie-Xie requested a review from CPWstatic April 19, 2022 11:40
CPWstatic
CPWstatic previously approved these changes Apr 19, 2022
@codecov-commenter
Copy link

codecov-commenter commented Apr 19, 2022

Codecov Report

Merging #4151 (206eb69) into master (26f8fc8) will increase coverage by 0.06%.
The diff coverage is 86.73%.

@@            Coverage Diff             @@
##           master    #4151      +/-   ##
==========================================
+ Coverage   84.94%   85.01%   +0.06%     
==========================================
  Files        1319     1326       +7     
  Lines      131077   131682     +605     
==========================================
+ Hits       111343   111949     +606     
+ Misses      19734    19733       -1     
Impacted Files Coverage Δ
src/clients/meta/MetaClient.h 92.30% <ø> (ø)
src/graph/context/ast/CypherAstContext.h 100.00% <ø> (ø)
...rc/graph/executor/algo/MultiShortestPathExecutor.h 100.00% <ø> (ø)
src/graph/service/GraphFlags.cpp 100.00% <ø> (ø)
src/graph/util/ExpressionUtils.h 100.00% <ø> (ø)
src/meta/MetaServiceHandler.h 100.00% <ø> (ø)
.../processors/admin/VerifyClientVersionProcessor.cpp 100.00% <ø> (ø)
src/graph/visitor/ExtractGroupSuiteVisitor.cpp 59.39% <59.39%> (ø)
...eta/processors/admin/SaveGraphVersionProcessor.cpp 66.66% <66.66%> (ø)
src/clients/meta/MetaClient.cpp 76.96% <80.64%> (+0.15%) ⬆️
... and 87 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 607330d...206eb69. Read the comment docs.

Comment on lines +178 to +213
AggregateExpression *aggExpr(const std::string &name, Expression *arg, bool distinct) {
return AggregateExpression::make(pool, name, arg, distinct);
}

VertexExpression *vertexExpr(const std::string &name) {
return VertexExpression::make(pool, name);
}

PredicateExpression *predExpr(const std::string &name = "",
const std::string &innerVar = "",
Expression *collection = nullptr,
Expression *filter = nullptr) {
return PredicateExpression::make(pool, name, innerVar, collection, filter);
}

ListComprehensionExpression *lcExpr(const std::string &innerVar = "",
Expression *collection = nullptr,
Expression *filter = nullptr,
Expression *mapping = nullptr) {
return ListComprehensionExpression::make(pool, innerVar, collection, filter, mapping);
}

ReduceExpression *reduceExpr(const std::string &accumulator = "",
Expression *initial = nullptr,
const std::string &innerVar = "",
Expression *collection = nullptr,
Expression *mapping = nullptr) {
return ReduceExpression::make(pool, accumulator, initial, innerVar, collection, mapping);
}

SubscriptRangeExpression *srExpr(Expression *list = nullptr,
Expression *lo = nullptr,
Expression *hi = nullptr) {
return SubscriptRangeExpression::make(pool, list, lo, hi);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need the method

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wrap Expression::make?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emmm, just like other method.

}
};

TEST_F(ExtractGroupSuiteVisitorTest, TestConstantExpression) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should test some nested expression scenarios.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I do. TEST_F(ExtractGroupSuiteVisitorTest, TestUnaryExpression2)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add test case:
(abs(v.age)+1)+count(v.name)

@czpmango
Copy link
Contributor

Any tck case?

@Shylock-Hg
Copy link
Contributor

Add test in tck?

Copy link
Contributor

@CPWstatic CPWstatic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent!! But remember that we should add tck test for a bug fix like this one.

@@ -73,6 +73,10 @@ class ExpressionUtils {
// rewrite Agg to VarProp
static Expression* rewriteAgg2VarProp(const Expression* expr);

// review the subExprs which are parts of expr.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

review -> rewrite
rewrite subExprs to VariablePropertyExpression

Comment on lines 180 to 197
auto specialExprs =
ExpressionUtils::collectAll(expr, {Expression::Kind::kVar, Expression::Kind::kAttribute});
for (auto *s : specialExprs) {
if (s->kind() == Expression::Kind::kVar &&
static_cast<const VariableExpression *>(s)->isInner()) {
return;
}
if (s->kind() == Expression::Kind::kAttribute) {
auto *left = static_cast<const AttributeExpression *>(s)->left();
if (left->kind() == Expression::Kind::kVar &&
static_cast<const VariableExpression *>(left)->isInner()) {
return;
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some comments here, i believe that these cases happend to only PredicateExpression, ListComprehensionExpression, ReduceExpression

CPWstatic
CPWstatic previously approved these changes Apr 20, 2022
Comment on lines 135 to 149
TEST_F(ExtractGroupSuiteVisitorTest, TestArithmeticExpression2) {
auto* left = constantExpr(0);
auto* right = aggExpr("count", constantExpr(1), false);
auto* e = minusExpr(left, right);

ExtractGroupSuiteVisitor visitor;
e->accept(&visitor);

GroupSuite expect;
expect.groupKeys.push_back(left);
expect.groupItems.push_back(left);
expect.groupItems.push_back(right);

ASSERT_EQ(true, check(visitor.groupSuite(), expect));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's incorrect.
v.age+count(v.name) key: v.age items: v.age,count(v.name)
1+count(v.name) item: count(v.name)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean, that constantExpr doesn't need to put groupkeys and groupItems?

Comment on lines 151 to 165
TEST_F(ExtractGroupSuiteVisitorTest, TestRelationalExpression) {
auto* left = constantExpr(0);
auto* right = aggExpr("count", constantExpr(1), false);
auto* e = neExpr(left, right);

ExtractGroupSuiteVisitor visitor;
e->accept(&visitor);

GroupSuite expect;
expect.groupKeys.push_back(left);
expect.groupItems.push_back(left);
expect.groupItems.push_back(right);

ASSERT_EQ(true, check(visitor.groupSuite(), expect));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Comment on lines 197 to 211
TEST_F(ExtractGroupSuiteVisitorTest, TestLogicalExpression2) {
auto* left = constantExpr(0);
auto* right = aggExpr("count", constantExpr(1), false);
auto* e = orExpr(left, right);

ExtractGroupSuiteVisitor visitor;
e->accept(&visitor);

GroupSuite expect;
expect.groupKeys.push_back(left);
expect.groupItems.push_back(left);
expect.groupItems.push_back(right);

ASSERT_EQ(true, check(visitor.groupSuite(), expect));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Comment on lines 190 to 195
if (s->kind() == Expression::Kind::kAttribute) {
auto *left = static_cast<const AttributeExpression *>(s)->left();
if (left->kind() == Expression::Kind::kVar &&
static_cast<const VariableExpression *>(left)->isInner()) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is for PredicateExpression, ListComprehensionExpression or ReduceExpression. It will check the innerVar.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why collect AttributeExpression, but still check VariableExpression?
Is this code redundant?

Comment on lines 818 to 821
if (!ExpressionUtils::checkAggExpr(static_cast<const AggregateExpression *>(item)).ok()) {
return Status::SemanticError("Aggregate function nesting is not allowed: `%s'",
colExpr->toString().c_str());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NG_RETURN_IF_ERROR(ExpressionUtils::checkAggExpr(static_cast<const AggregateExpression *>(item)))

@@ -505,6 +505,23 @@ Feature: Basic Aggregate and GroupBy
Then the result should be, in order, with relax comparison:
| b |
| True |
When executing query:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add test case:

 MATCH (v:player{name:"Tim Duncan"})--(n:team) return [n in collect(v.player.age) where n>40| n]

Comment on lines +186 to +189
if (s->kind() == Expression::Kind::kVar &&
static_cast<const VariableExpression *>(s)->isInner()) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that no keys and items will be added if any subexpression is inner var?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

en. Is it incorrect?

CPWstatic
CPWstatic previously approved these changes Apr 20, 2022
@Sophie-Xie Sophie-Xie removed the cherry-pick-v3.1 PR: need cherry-pick to this version label Apr 21, 2022
@Sophie-Xie Sophie-Xie added this to the v3.2.0 milestone Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready for review ready-for-testing PR: ready for the CI test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants