Files
scylladb/cql3/functions/aggregate_fcts.hh
Avi Kivity 78f4ee385f cql3: functions: fix count(col) for non-scalar types
count(col), unlike count(*), does not count rows for which col is NULL.
However, if col's data type is not a scalar (e.g. a collection, tuple,
or user-defined type) it behaves like count(*), counting NULLs too.

The cause is that get_dynamic_aggregate() converts count() to
the count(*) version. It works for scalars because get_dynamic_aggregate()
intentionally fails to match scalar arguments, and functions::get() then
matches the arguments against the pre-declared count functions.

As we can only pre-declare count(scalar) (there's an infinite number
of non-scalar types), we change the approach to be the same as min/max:
we make count() a generic function. In fact count(col) is much better
as a generic function, as it only examines its input to see if it is
NULL.

A unit test is added. It passes with Cassandra as well.

Fixes #14198.

Closes #14199
2023-06-13 14:40:14 +03:00

42 lines
977 B
C++

/*
* Copyright (C) 2014-present ScyllaDB
*
* Modified by ScyllaDB
*/
/*
* SPDX-License-Identifier: (AGPL-3.0-or-later and Apache-2.0)
*/
#pragma once
#include "aggregate_function.hh"
namespace cql3 {
namespace functions {
/// Factory methods for aggregate functions.
namespace aggregate_fcts {
static const sstring COUNT_ROWS_FUNCTION_NAME = "countRows";
/// The function used to count the number of rows of a result set. This function is called when COUNT(*) or COUNT(1)
/// is specified.
shared_ptr<aggregate_function>
make_count_rows_function();
/// The same as `make_max_function()' but with type provided in runtime.
shared_ptr<aggregate_function>
make_max_function(data_type io_type);
/// The same as `make_min_function()' but with type provided in runtime.
shared_ptr<aggregate_function>
make_min_function(data_type io_type);
/// count(col) function for the specified type
shared_ptr<aggregate_function> make_count_function(data_type input_type);
}
}
}