Added support for nullable types in HAVING section in presence of WITH TOTALS [#CLICKHOUSE-3431].

This commit is contained in:
Alexey Milovidov 2017-12-09 16:28:14 +03:00 committed by alexey-milovidov
parent 44bcae8cce
commit b00bb5c348
3 changed files with 22 additions and 1 deletions

View File

@ -3,6 +3,7 @@
#include <Interpreters/AggregateDescription.h> #include <Interpreters/AggregateDescription.h>
#include <Columns/ColumnAggregateFunction.h> #include <Columns/ColumnAggregateFunction.h>
#include <Columns/ColumnsNumber.h> #include <Columns/ColumnsNumber.h>
#include <Columns/ColumnNullable.h>
#include <Common/typeid_cast.h> #include <Common/typeid_cast.h>
namespace DB namespace DB
@ -117,7 +118,11 @@ Block TotalsHavingBlockInputStream::readImpl()
if (auto converted = filter_column_ptr->convertToFullColumnIfConst()) if (auto converted = filter_column_ptr->convertToFullColumnIfConst())
filter_column_ptr = converted; filter_column_ptr = converted;
ColumnUInt8 * filter_column = typeid_cast<ColumnUInt8 *>(&*filter_column_ptr); bool filter_is_nullable = filter_column_ptr->isColumnNullable();
ColumnUInt8 * filter_column = filter_is_nullable
? typeid_cast<ColumnUInt8 *>(static_cast<ColumnNullable *>(filter_column_ptr.get())->getNestedColumn().get())
: typeid_cast<ColumnUInt8 *>(&*filter_column_ptr);
if (!filter_column) if (!filter_column)
throw Exception("Filter column must have type UInt8, found " + throw Exception("Filter column must have type UInt8, found " +
finalized.safeGetByPosition(filter_column_pos).type->getName(), finalized.safeGetByPosition(filter_column_pos).type->getName(),
@ -125,6 +130,14 @@ Block TotalsHavingBlockInputStream::readImpl()
IColumn::Filter & filter = filter_column->getData(); IColumn::Filter & filter = filter_column->getData();
if (filter_column_ptr->isColumnNullable())
{
const NullMap & null_map = static_cast<ColumnNullable *>(filter_column_ptr.get())->getNullMap();
for (size_t i = 0, size = null_map.size(); i < size; ++i)
if (null_map[i])
filter[i] = 0;
}
/// Add values to `totals` (if it was not already done). /// Add values to `totals` (if it was not already done).
if (totals_mode == TotalsMode::BEFORE_HAVING) if (totals_mode == TotalsMode::BEFORE_HAVING)
addToTotals(current_totals, block, nullptr); addToTotals(current_totals, block, nullptr);

View File

@ -0,0 +1,6 @@
1
1
world 40
40

View File

@ -0,0 +1,2 @@
SELECT count() AS x WITH TOTALS HAVING x != toNullable(0);
SELECT k, count() AS c FROM (SELECT number, CASE WHEN number < 10 THEN 'hello' WHEN number < 50 THEN 'world' ELSE 'goodbye' END AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS HAVING nullIf(c, 10) < 50 ORDER BY c;