Query:: COUNT(*) added to logical planning and execution
Reviewers: mislav.bradac, buda, teon.banek Reviewed By: mislav.bradac, teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D353
This commit is contained in:
parent
871b81656b
commit
0866fdcb0c
@ -1059,7 +1059,17 @@ void Aggregate::AggregateCursor::Update(
|
|||||||
auto agg_elem_it = self_.aggregations_.begin();
|
auto agg_elem_it = self_.aggregations_.begin();
|
||||||
for (; count_it < agg_value.counts_.end();
|
for (; count_it < agg_value.counts_.end();
|
||||||
count_it++, value_it++, agg_elem_it++) {
|
count_it++, value_it++, agg_elem_it++) {
|
||||||
std::get<0>(*agg_elem_it)->Accept(evaluator);
|
|
||||||
|
// COUNT(*) is the only case where input expression is optional
|
||||||
|
// handle it here
|
||||||
|
auto input_expr_ptr = std::get<0>(*agg_elem_it);
|
||||||
|
if (!input_expr_ptr) {
|
||||||
|
*count_it += 1;
|
||||||
|
*value_it = *count_it;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
input_expr_ptr->Accept(evaluator);
|
||||||
TypedValue input_value = evaluator.PopBack();
|
TypedValue input_value = evaluator.PopBack();
|
||||||
|
|
||||||
// Aggregations skip Null input values.
|
// Aggregations skip Null input values.
|
||||||
|
@ -310,7 +310,11 @@ class ReturnBodyContext : public TreeVisitorBase {
|
|||||||
// Aggregation contains a virtual symbol, where the result will be stored.
|
// Aggregation contains a virtual symbol, where the result will be stored.
|
||||||
const auto &symbol = symbol_table_.at(aggr);
|
const auto &symbol = symbol_table_.at(aggr);
|
||||||
aggregations_.emplace_back(aggr.expression_, aggr.op_, symbol);
|
aggregations_.emplace_back(aggr.expression_, aggr.op_, symbol);
|
||||||
has_aggregation_.back() = true;
|
// aggregation expression_ is opional in COUNT(*) so it's possible the has_aggregation_ stack is empty
|
||||||
|
if (aggr.expression_)
|
||||||
|
has_aggregation_.back() = true;
|
||||||
|
else
|
||||||
|
has_aggregation_.emplace_back(true);
|
||||||
// Possible optimization is to skip remembering symbols inside aggregation.
|
// Possible optimization is to skip remembering symbols inside aggregation.
|
||||||
// If and when implementing this, don't forget that Accumulate needs *all*
|
// If and when implementing this, don't forget that Accumulate needs *all*
|
||||||
// the symbols, including those inside aggregation.
|
// the symbols, including those inside aggregation.
|
||||||
|
@ -152,10 +152,10 @@ TEST(QueryPlan, AggregateOps) {
|
|||||||
// we will take the sum, avg, min, max and count
|
// we will take the sum, avg, min, max and count
|
||||||
// we won't group by anything
|
// we won't group by anything
|
||||||
auto prop = dba->property("prop");
|
auto prop = dba->property("prop");
|
||||||
dba->insert_vertex().PropsSet(prop, 4);
|
dba->insert_vertex().PropsSet(prop, 5);
|
||||||
dba->insert_vertex().PropsSet(prop, 7);
|
dba->insert_vertex().PropsSet(prop, 7);
|
||||||
dba->insert_vertex().PropsSet(prop, 12);
|
dba->insert_vertex().PropsSet(prop, 12);
|
||||||
// a missing property (null) gets ignored by all aggregations
|
// a missing property (null) gets ignored by all aggregations except COUNT(*)
|
||||||
dba->insert_vertex();
|
dba->insert_vertex();
|
||||||
dba->advance_command();
|
dba->advance_command();
|
||||||
|
|
||||||
@ -167,31 +167,36 @@ TEST(QueryPlan, AggregateOps) {
|
|||||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||||
symbol_table[*n_p->expression_] = n.sym_;
|
symbol_table[*n_p->expression_] = n.sym_;
|
||||||
|
|
||||||
|
std::vector<Expression *> aggregation_expressions(6, n_p);
|
||||||
|
aggregation_expressions[0] = nullptr;
|
||||||
auto produce = MakeAggregationProduce(
|
auto produce = MakeAggregationProduce(
|
||||||
n.op_, symbol_table, storage, std::vector<Expression *>(5, n_p),
|
n.op_, symbol_table, storage, aggregation_expressions,
|
||||||
{Aggregation::Op::COUNT, Aggregation::Op::MIN, Aggregation::Op::MAX,
|
{Aggregation::Op::COUNT, Aggregation::Op::COUNT, Aggregation::Op::MIN,
|
||||||
Aggregation::Op::SUM, Aggregation::Op::AVG},
|
Aggregation::Op::MAX, Aggregation::Op::SUM, Aggregation::Op::AVG},
|
||||||
{}, {});
|
{}, {});
|
||||||
|
|
||||||
// checks
|
// checks
|
||||||
auto results = CollectProduce(produce, symbol_table, *dba).GetResults();
|
auto results = CollectProduce(produce, symbol_table, *dba).GetResults();
|
||||||
ASSERT_EQ(results.size(), 1);
|
ASSERT_EQ(results.size(), 1);
|
||||||
ASSERT_EQ(results[0].size(), 5);
|
ASSERT_EQ(results[0].size(), 6);
|
||||||
// count
|
// count(*)
|
||||||
ASSERT_EQ(results[0][0].type(), TypedValue::Type::Int);
|
ASSERT_EQ(results[0][0].type(), TypedValue::Type::Int);
|
||||||
EXPECT_EQ(results[0][0].Value<int64_t>(), 3);
|
EXPECT_EQ(results[0][0].Value<int64_t>(), 4);
|
||||||
// min
|
// count
|
||||||
ASSERT_EQ(results[0][1].type(), TypedValue::Type::Int);
|
ASSERT_EQ(results[0][1].type(), TypedValue::Type::Int);
|
||||||
EXPECT_EQ(results[0][1].Value<int64_t>(), 4);
|
EXPECT_EQ(results[0][1].Value<int64_t>(), 3);
|
||||||
// max
|
// min
|
||||||
ASSERT_EQ(results[0][2].type(), TypedValue::Type::Int);
|
ASSERT_EQ(results[0][2].type(), TypedValue::Type::Int);
|
||||||
EXPECT_EQ(results[0][2].Value<int64_t>(), 12);
|
EXPECT_EQ(results[0][2].Value<int64_t>(), 5);
|
||||||
// sum
|
// max
|
||||||
ASSERT_EQ(results[0][3].type(), TypedValue::Type::Int);
|
ASSERT_EQ(results[0][3].type(), TypedValue::Type::Int);
|
||||||
EXPECT_EQ(results[0][3].Value<int64_t>(), 23);
|
EXPECT_EQ(results[0][3].Value<int64_t>(), 12);
|
||||||
|
// sum
|
||||||
|
ASSERT_EQ(results[0][4].type(), TypedValue::Type::Int);
|
||||||
|
EXPECT_EQ(results[0][4].Value<int64_t>(), 24);
|
||||||
// avg
|
// avg
|
||||||
ASSERT_EQ(results[0][4].type(), TypedValue::Type::Double);
|
ASSERT_EQ(results[0][5].type(), TypedValue::Type::Double);
|
||||||
EXPECT_FLOAT_EQ(results[0][4].Value<double>(), 23 / 3.0);
|
EXPECT_FLOAT_EQ(results[0][5].Value<double>(), 24 / 3.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(QueryPlan, AggregateGroupByValues) {
|
TEST(QueryPlan, AggregateGroupByValues) {
|
||||||
|
Loading…
Reference in New Issue
Block a user