Compare commits

...

2 Commits

Author SHA1 Message Date
Marko Budiselić
495251a8cd Update pull_request_template.md 2023-11-20 16:25:55 +01:00
Andi
d03fafcef6 Aggregations return empty result when used with group by (#1531) 2023-11-20 11:52:17 +01:00
6 changed files with 16 additions and 46 deletions

View File

@@ -1,13 +1,9 @@
[master < Epic] PR
- [ ] Check, and update documentation if necessary
PR checklist:
- [ ] Check and update documentation if necessary
- [ ] Write E2E tests
- [ ] Compare the [benchmarking results](https://bench-graph.memgraph.com/) between the master branch and the Epic branch
- [ ] Provide the full content or a guide for the final git message
[master < Task] PR
- [ ] Check, and update documentation if necessary
- [ ] Provide the full content or a guide for the final git message
- [ ] Notify everyone downstream (platform, dx, infra, ...) if there is any breaking change and what to do about it
To keep docs changelog up to date, one more thing to do:
- [ ] Write a release note here, including added/changed clauses

View File

@@ -3464,7 +3464,7 @@ class AggregateCursor : public Cursor {
SCOPED_PROFILE_OP_BY_REF(self_);
if (!pulled_all_input_) {
if (!ProcessAll(&frame, &context) && self_.AreAllAggregationsForCollecting()) return false;
if (!ProcessAll(&frame, &context) && !self_.group_by_.empty()) return false;
pulled_all_input_ = true;
aggregation_it_ = aggregation_.begin();
@@ -3824,12 +3824,6 @@ UniqueCursorPtr Aggregate::MakeCursor(utils::MemoryResource *mem) const {
return MakeUniqueCursorPtr<AggregateCursor>(mem, *this, mem);
}
auto Aggregate::AreAllAggregationsForCollecting() const -> bool {
return std::all_of(aggregations_.begin(), aggregations_.end(), [](const auto &agg) {
return agg.op == Aggregation::Op::COLLECT_LIST || agg.op == Aggregation::Op::COLLECT_MAP;
});
}
Skip::Skip(const std::shared_ptr<LogicalOperator> &input, Expression *expression)
: input_(input), expression_(expression) {}

View File

@@ -1759,8 +1759,6 @@ class Aggregate : public memgraph::query::plan::LogicalOperator {
Aggregate(const std::shared_ptr<LogicalOperator> &input, const std::vector<Element> &aggregations,
const std::vector<Expression *> &group_by, const std::vector<Symbol> &remember);
auto AreAllAggregationsForCollecting() const -> bool;
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
UniqueCursorPtr MakeCursor(utils::MemoryResource *) const override;
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;

View File

@@ -425,6 +425,4 @@ Feature: Aggregations
"""
MATCH (subnet:Subnet) WHERE FALSE WITH subnet, count(subnet.ip) as ips RETURN id(subnet) as id
"""
Then the result should be:
| id |
| null |
Then the result should be empty

View File

@@ -425,6 +425,4 @@ Feature: Aggregations
"""
MATCH (subnet:Subnet) WHERE FALSE WITH subnet, count(subnet.ip) as ips RETURN id(subnet) as id
"""
Then the result should be:
| id |
| null |
Then the result should be empty

View File

@@ -250,30 +250,23 @@ TYPED_TEST(QueryPlanAggregateOps, WithData) {
TYPED_TEST(QueryPlanAggregateOps, WithoutDataWithGroupBy) {
{
auto results = this->AggregationResults(true, false, {Aggregation::Op::COUNT});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Int);
EXPECT_EQ(results[0][0].ValueInt(), 0);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, false, {Aggregation::Op::SUM});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Int);
EXPECT_EQ(results[0][0].ValueInt(), 0);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, false, {Aggregation::Op::AVG});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, false, {Aggregation::Op::MIN});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, false, {Aggregation::Op::MAX});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, false, {Aggregation::Op::COLLECT_LIST});
@@ -666,30 +659,23 @@ TYPED_TEST(QueryPlanAggregateOps, WithDataDistinct) {
TYPED_TEST(QueryPlanAggregateOps, WithoutDataWithDistinctAndWithGroupBy) {
{
auto results = this->AggregationResults(true, true, {Aggregation::Op::COUNT});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Int);
EXPECT_EQ(results[0][0].ValueInt(), 0);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, true, {Aggregation::Op::SUM});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Int);
EXPECT_EQ(results[0][0].ValueInt(), 0);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, true, {Aggregation::Op::AVG});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, true, {Aggregation::Op::MIN});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, true, {Aggregation::Op::MAX});
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null);
EXPECT_EQ(results.size(), 0);
}
{
auto results = this->AggregationResults(true, true, {Aggregation::Op::COLLECT_LIST});