-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Conversation
@@ -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()); |
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.
match (v) return {abs(v.age),count(v.name)+1}
You should groupby abs(v.age)
rather than v.age
.
Please add test cases related to the issue you want to fix. |
namespace nebula { | ||
namespace graph { | ||
|
||
class ExtractGroupSuiteVisitor : public ExprVisitorImpl { |
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.
Please add unit test for ExtractGroupSuiteVisitor.
Codecov Report
@@ 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
Continue to review full report at Codecov.
|
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); | ||
} | ||
|
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.
Necessary?
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.
?
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 need the method
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.
Just wrap Expression::make
?
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.
emmm, just like other method.
} | ||
}; | ||
|
||
TEST_F(ExtractGroupSuiteVisitorTest, TestConstantExpression) { |
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.
You should test some nested expression scenarios.
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.
Yes. I do. TEST_F(ExtractGroupSuiteVisitorTest, TestUnaryExpression2)
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.
Add test case:
(abs(v.age)+1)+count(v.name)
Any tck case? |
Add test in tck? |
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.
Excellent!! But remember that we should add tck test for a bug fix like this one.
src/graph/util/ExpressionUtils.h
Outdated
@@ -73,6 +73,10 @@ class ExpressionUtils { | |||
// rewrite Agg to VarProp | |||
static Expression* rewriteAgg2VarProp(const Expression* expr); | |||
|
|||
// review the subExprs which are parts of expr. |
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.
review -> rewrite
rewrite subExprs to VariablePropertyExpression
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; | ||
} | ||
} | ||
} |
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.
Please add some comments here, i believe that these cases happend to only PredicateExpression, ListComprehensionExpression, ReduceExpression
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)); | ||
} |
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.
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)
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.
You mean, that constantExpr doesn't need to put groupkeys and groupItems?
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)); | ||
} |
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.
Ditto.
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)); | ||
} |
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.
Ditto.
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; | ||
} |
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.
Why need this?
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.
It is for PredicateExpression, ListComprehensionExpression or ReduceExpression. It will check the innerVar.
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.
Why collect AttributeExpression, but still check VariableExpression?
Is this code redundant?
if (!ExpressionUtils::checkAggExpr(static_cast<const AggregateExpression *>(item)).ok()) { | ||
return Status::SemanticError("Aggregate function nesting is not allowed: `%s'", | ||
colExpr->toString().c_str()); | ||
} |
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.
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: |
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.
Add test case:
MATCH (v:player{name:"Tim Duncan"})--(n:team) return [n in collect(v.player.age) where n>40| n]
if (s->kind() == Expression::Kind::kVar && | ||
static_cast<const VariableExpression *>(s)->isInner()) { | ||
return; | ||
} |
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.
Does this mean that no keys and items will be added if any subexpression is inner var?
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.
en. Is it incorrect?
What type of PR is this?
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:
Affects:
Release notes:
Please confirm whether to be reflected in release notes and how to describe: