Merge pull request #5755 from 4ertus2/bugs

Fix wrong ColumnConst.isColumnNullable()
This commit is contained in:
alexey-milovidov 2019-07-03 02:06:07 +03:00 committed by GitHub
commit d81ae49f2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
74 changed files with 270 additions and 234 deletions

View File

@ -202,8 +202,8 @@ public:
return false;
}
bool isNullable() const override { return isColumnNullable(*data); }
bool onlyNull() const override { return data->isNullAt(0); }
bool isColumnConst() const override { return true; }
bool isNumeric() const override { return data->isNumeric(); }
bool isFixedAndContiguous() const override { return data->isFixedAndContiguous(); }
bool valuesHaveFixedSize() const override { return data->valuesHaveFixedSize(); }

View File

@ -148,6 +148,7 @@ public:
size_t sizeOfValueIfFixed() const override { return getDictionary().sizeOfValueIfFixed(); }
bool isNumeric() const override { return getDictionary().isNumeric(); }
bool lowCardinality() const override { return true; }
bool isNullable() const override { return isColumnNullable(*dictionary.getColumnUniquePtr()); }
const IColumnUnique & getDictionary() const { return dictionary.getColumnUnique(); }
const ColumnPtr & getDictionaryPtr() const { return dictionary.getColumnUniquePtr(); }

View File

@ -27,7 +27,7 @@ ColumnNullable::ColumnNullable(MutableColumnPtr && nested_column_, MutableColumn
if (!getNestedColumn().canBeInsideNullable())
throw Exception{getNestedColumn().getName() + " cannot be inside Nullable column", ErrorCodes::ILLEGAL_COLUMN};
if (null_map->isColumnConst())
if (isColumnConst(*null_map))
throw Exception{"ColumnNullable cannot have constant null map", ErrorCodes::ILLEGAL_COLUMN};
}
@ -451,13 +451,12 @@ void ColumnNullable::checkConsistency() const
ErrorCodes::SIZES_OF_NESTED_COLUMNS_ARE_INCONSISTENT);
}
ColumnPtr makeNullable(const ColumnPtr & column)
{
if (column->isColumnNullable())
if (isColumnNullable(*column))
return column;
if (column->isColumnConst())
if (isColumnConst(*column))
return ColumnConst::create(makeNullable(static_cast<const ColumnConst &>(*column).getDataColumnPtr()), column->size());
return ColumnNullable::create(column, ColumnUInt8::create(column->size(), 0));

View File

@ -100,7 +100,7 @@ public:
return false;
}
bool isColumnNullable() const override { return true; }
bool isNullable() const override { return true; }
bool isFixedAndContiguous() const override { return false; }
bool valuesHaveFixedSize() const override { return nested_column->valuesHaveFixedSize(); }
size_t sizeOfValueIfFixed() const override { return null_map->sizeOfValueIfFixed() + nested_column->sizeOfValueIfFixed(); }
@ -142,7 +142,6 @@ private:
void applyNullMapImpl(const ColumnUInt8 & map);
};
ColumnPtr makeNullable(const ColumnPtr & column);
}

View File

@ -39,7 +39,7 @@ ColumnTuple::ColumnTuple(MutableColumns && mutable_columns)
columns.reserve(mutable_columns.size());
for (auto & column : mutable_columns)
{
if (column->isColumnConst())
if (isColumnConst(*column))
throw Exception{"ColumnTuple cannot have ColumnConst as its element", ErrorCodes::ILLEGAL_COLUMN};
columns.push_back(std::move(column));
@ -49,7 +49,7 @@ ColumnTuple::ColumnTuple(MutableColumns && mutable_columns)
ColumnTuple::Ptr ColumnTuple::create(const Columns & columns)
{
for (const auto & column : columns)
if (column->isColumnConst())
if (isColumnConst(*column))
throw Exception{"ColumnTuple cannot have ColumnConst as its element", ErrorCodes::ILLEGAL_COLUMN};
auto column_tuple = ColumnTuple::create(MutableColumns());
@ -61,7 +61,7 @@ ColumnTuple::Ptr ColumnTuple::create(const Columns & columns)
ColumnTuple::Ptr ColumnTuple::create(const TupleColumns & columns)
{
for (const auto & column : columns)
if (column->isColumnConst())
if (isColumnConst(*column))
throw Exception{"ColumnTuple cannot have ColumnConst as its element", ErrorCodes::ILLEGAL_COLUMN};
auto column_tuple = ColumnTuple::create(MutableColumns());

View File

@ -193,7 +193,7 @@ ColumnUnique<ColumnType>::ColumnUnique(MutableColumnPtr && holder, bool is_nulla
{
if (column_holder->size() < numSpecialValues())
throw Exception("Too small holder column for ColumnUnique.", ErrorCodes::ILLEGAL_COLUMN);
if (column_holder->isColumnNullable())
if (isColumnNullable(*column_holder))
throw Exception("Holder column for ColumnUnique can't be nullable.", ErrorCodes::ILLEGAL_COLUMN);
index.setColumn(getRawColumnPtr());
@ -273,7 +273,7 @@ size_t ColumnUnique<ColumnType>::uniqueInsertFrom(const IColumn & src, size_t n)
if (is_nullable && src.isNullAt(n))
return getNullValueIndex();
if (auto * nullable = typeid_cast<const ColumnNullable *>(&src))
if (auto * nullable = checkAndGetColumn<ColumnNullable>(src))
return uniqueInsertFrom(nullable->getNestedColumn(), n);
auto ref = src.getDataAt(n);
@ -432,7 +432,7 @@ MutableColumnPtr ColumnUnique<ColumnType>::uniqueInsertRangeImpl(
return nullptr;
};
if (auto nullable_column = typeid_cast<const ColumnNullable *>(&src))
if (auto * nullable_column = checkAndGetColumn<ColumnNullable>(src))
{
src_column = typeid_cast<const ColumnType *>(&nullable_column->getNestedColumn());
null_map = &nullable_column->getNullMapData();

View File

@ -23,14 +23,14 @@ ConstantFilterDescription::ConstantFilterDescription(const IColumn & column)
return;
}
if (column.isColumnConst())
if (isColumnConst(column))
{
const ColumnConst & column_const = static_cast<const ColumnConst &>(column);
ColumnPtr column_nested = column_const.getDataColumnPtr()->convertToFullColumnIfLowCardinality();
if (!typeid_cast<const ColumnUInt8 *>(column_nested.get()))
{
const ColumnNullable * column_nested_nullable = typeid_cast<const ColumnNullable *>(column_nested.get());
const ColumnNullable * column_nested_nullable = checkAndGetColumn<ColumnNullable>(*column_nested);
if (!column_nested_nullable || !typeid_cast<const ColumnUInt8 *>(&column_nested_nullable->getNestedColumn()))
{
throw Exception("Illegal type " + column_nested->getName() + " of column for constant filter. Must be UInt8 or Nullable(UInt8).",
@ -60,7 +60,7 @@ FilterDescription::FilterDescription(const IColumn & column_)
return;
}
if (const ColumnNullable * nullable_column = typeid_cast<const ColumnNullable *>(&column))
if (auto * nullable_column = checkAndGetColumn<ColumnNullable>(column))
{
ColumnPtr nested_column = nullable_column->getNestedColumnPtr();
MutableColumnPtr mutable_holder = (*std::move(nested_column)).mutate();

View File

@ -1,6 +1,8 @@
#include <IO/WriteBufferFromString.h>
#include <IO/Operators.h>
#include <Columns/IColumn.h>
#include <Columns/ColumnNullable.h>
#include <Columns/ColumnConst.h>
namespace DB
@ -22,4 +24,14 @@ String IColumn::dumpStructure() const
return res.str();
}
bool isColumnNullable(const IColumn & column)
{
return checkColumn<ColumnNullable>(column);
}
bool isColumnConst(const IColumn & column)
{
return checkColumn<ColumnConst>(column);
}
}

View File

@ -4,6 +4,7 @@
#include <Common/COW.h>
#include <Common/PODArray.h>
#include <Common/Exception.h>
#include <Common/typeid_cast.h>
#include <common/StringRef.h>
@ -296,12 +297,8 @@ public:
/// Various properties on behaviour of column type.
/// Is this column a container for Nullable values? It's true only for ColumnNullable.
/// Note that ColumnConst(ColumnNullable(...)) is not considered.
virtual bool isColumnNullable() const { return false; }
/// Column stores a constant value. It's true only for ColumnConst wrapper.
virtual bool isColumnConst() const { return false; }
/// True if column contains something nullable inside. It's true for ColumnNullable, can be true or false for ColumnConst, etc.
virtual bool isNullable() const { return false; }
/// It's a special kind of column, that contain single value, but is not a ColumnConst.
virtual bool isDummy() const { return false; }
@ -410,4 +407,35 @@ struct IsMutableColumns<Arg, Args ...>
template <>
struct IsMutableColumns<> { static const bool value = true; };
template <typename Type>
const Type * checkAndGetColumn(const IColumn & column)
{
return typeid_cast<const Type *>(&column);
}
template <typename Type>
const Type * checkAndGetColumn(const IColumn * column)
{
return typeid_cast<const Type *>(column);
}
template <typename Type>
bool checkColumn(const IColumn & column)
{
return checkAndGetColumn<Type>(&column);
}
template <typename Type>
bool checkColumn(const IColumn * column)
{
return checkAndGetColumn<Type>(column);
}
/// True if column's an ColumnConst instance. It's just a syntax sugar for type check.
bool isColumnConst(const IColumn & column);
/// True if column's an ColumnNullable instance. It's just a syntax sugar for type check.
bool isColumnNullable(const IColumn & column);
}

View File

@ -31,7 +31,7 @@ ColumnWithTypeAndName getLeastSuperColumn(std::vector<const ColumnWithTypeAndNam
for (size_t i = 0; i < columns.size(); ++i)
{
types[i] = columns[i]->type;
if (columns[i]->column->isColumnConst())
if (isColumnConst(*columns[i]->column))
++num_const;
}

View File

@ -279,11 +279,10 @@ protected:
for (const auto & col : key_columns)
{
if (col->isColumnNullable())
if (auto * nullable_col = checkAndGetColumn<ColumnNullable>(col))
{
const auto & nullable_col = static_cast<const ColumnNullable &>(*col);
actual_columns.push_back(&nullable_col.getNestedColumn());
null_maps.push_back(&nullable_col.getNullMapColumn());
actual_columns.push_back(&nullable_col->getNestedColumn());
null_maps.push_back(&nullable_col->getNullMapColumn());
}
else
{

View File

@ -474,7 +474,7 @@ static ReturnType checkBlockStructure(const Block & lhs, const Block & rhs, cons
return on_error("Block structure mismatch in " + context_description + " stream: different columns:\n"
+ lhs.dumpStructure() + "\n" + rhs.dumpStructure(), ErrorCodes::BLOCKS_HAVE_DIFFERENT_STRUCTURE);
if (actual.column->isColumnConst() && expected.column->isColumnConst())
if (isColumnConst(*actual.column) && isColumnConst(*expected.column))
{
Field actual_value = static_cast<const ColumnConst &>(*actual.column).getField();
Field expected_value = static_cast<const ColumnConst &>(*expected.column).getField();

View File

@ -167,8 +167,8 @@ private:
if constexpr (_actual)
{
bool c0_is_const = c0->isColumnConst();
bool c1_is_const = c1->isColumnConst();
bool c0_is_const = isColumnConst(*c0);
bool c1_is_const = isColumnConst(*c1);
if (c0_is_const && c1_is_const)
{

View File

@ -187,7 +187,7 @@ MutableColumnPtr AddingDefaultsBlockInputStream::mixColumns(const ColumnWithType
{
if (defaults_mask[i])
{
if (col_defaults.column->isColumnConst())
if (isColumnConst(*col_defaults.column))
column_mixed->insert((*col_defaults.column)[i]);
else
column_mixed->insertFrom(*col_defaults.column, i);

View File

@ -69,9 +69,9 @@ ConvertingBlockInputStream::ConvertingBlockInputStream(
/// Check constants.
if (res_elem.column->isColumnConst())
if (isColumnConst(*res_elem.column))
{
if (!src_elem.column->isColumnConst())
if (!isColumnConst(*src_elem.column))
throw Exception("Cannot convert column " + backQuoteIfNeed(res_elem.name)
+ " because it is non constant in source stream but must be constant in result",
ErrorCodes::BLOCKS_HAVE_DIFFERENT_STRUCTURE);
@ -103,7 +103,7 @@ Block ConvertingBlockInputStream::readImpl()
ColumnPtr converted = castColumnWithDiagnostic(src_elem, res_elem, context);
if (src_elem.column->isColumnConst() && !res_elem.column->isColumnConst())
if (isColumnConst(*src_elem.column) && !isColumnConst(*res_elem.column))
converted = converted->convertToFullColumnIfConst();
res_elem.column = std::move(converted);

View File

@ -112,7 +112,7 @@ ColumnRawPtrs DistinctBlockInputStream::getKeyColumns(const Block & block) const
: block.getByName(columns_names[i]).column;
/// Ignore all constant columns.
if (!column->isColumnConst())
if (!isColumnConst(*column))
column_ptrs.emplace_back(column.get());
}

View File

@ -131,7 +131,7 @@ ColumnRawPtrs DistinctSortedBlockInputStream::getKeyColumns(const Block & block)
: block.getByName(columns_names[i]).column;
/// Ignore all constant columns.
if (!column->isColumnConst())
if (!isColumnConst(*column))
column_ptrs.emplace_back(column.get());
}

View File

@ -112,7 +112,7 @@ Block FilterBlockInputStream::readImpl()
size_t first_non_constant_column = 0;
for (size_t i = 0; i < columns; ++i)
{
if (!res.safeGetByPosition(i).column->isColumnConst())
if (!isColumnConst(*res.safeGetByPosition(i).column))
{
first_non_constant_column = i;
@ -165,7 +165,7 @@ Block FilterBlockInputStream::readImpl()
if (i == first_non_constant_column)
continue;
if (current_column.column->isColumnConst())
if (isColumnConst(*current_column.column))
current_column.column = current_column.column->cut(0, filtered_rows);
else
current_column.column = current_column.column->filter(*filter_and_holder.data, -1);

View File

@ -144,7 +144,7 @@ void IBlockInputStream::updateExtremes(Block & block)
{
const ColumnPtr & src = block.safeGetByPosition(i).column;
if (src->isColumnConst())
if (isColumnConst(*src))
{
/// Equal min and max.
extremes_columns[i] = src->cloneResized(2);
@ -171,7 +171,7 @@ void IBlockInputStream::updateExtremes(Block & block)
{
ColumnPtr & old_extremes = extremes.safeGetByPosition(i).column;
if (old_extremes->isColumnConst())
if (isColumnConst(*old_extremes))
continue;
Field min_value = (*old_extremes)[0];

View File

@ -71,7 +71,7 @@ ColumnRawPtrs LimitByBlockInputStream::getKeyColumns(Block & block) const
auto & column = block.getByName(name).column;
/// Ignore all constant columns.
if (!column->isColumnConst())
if (!isColumnConst(*column))
column_ptrs.emplace_back(column.get());
}

View File

@ -9,7 +9,7 @@ void removeConstantsFromBlock(Block & block)
size_t i = 0;
while (i < columns)
{
if (block.getByPosition(i).column->isColumnConst())
if (isColumnConst(*block.getByPosition(i).column))
{
block.erase(i);
--columns;
@ -26,9 +26,9 @@ void removeConstantsFromSortDescription(const Block & header, SortDescription &
[&](const SortColumnDescription & elem)
{
if (!elem.column_name.empty())
return header.getByName(elem.column_name).column->isColumnConst();
return isColumnConst(*header.getByName(elem.column_name).column);
else
return header.safeGetByPosition(elem.column_number).column->isColumnConst();
return isColumnConst(*header.safeGetByPosition(elem.column_number).column);
}), description.end());
}
@ -41,7 +41,7 @@ void enrichBlockWithConstants(Block & block, const Block & header)
for (size_t i = 0; i < columns; ++i)
{
const auto & col_type_name = header.getByPosition(i);
if (col_type_name.column->isColumnConst())
if (isColumnConst(*col_type_name.column))
block.insert(i, {col_type_name.column->cloneResized(rows), col_type_name.type, col_type_name.name});
}
}

View File

@ -544,7 +544,7 @@ void DataTypeLowCardinality::serializeBinaryBulkWithMultipleStreams(
ErrorCodes::LOGICAL_ERROR);
}
if (auto nullable_keys = typeid_cast<const ColumnNullable *>(keys.get()))
if (auto * nullable_keys = checkAndGetColumn<ColumnNullable>(*keys))
keys = nullable_keys->getNestedColumnPtr();
bool need_additional_keys = !keys->empty();

View File

@ -91,7 +91,7 @@ Block flatten(const Block & block)
const Strings & names = type_tuple->getElementNames();
size_t tuple_size = element_types.size();
bool is_const = elem.column->isColumnConst();
bool is_const = isColumnConst(*elem.column);
const ColumnArray * column_array;
if (is_const)
column_array = typeid_cast<const ColumnArray *>(&static_cast<const ColumnConst &>(*elem.column).getDataColumn());

View File

@ -542,12 +542,12 @@ class FunctionBinaryArithmetic : public IFunction
if (WhichDataType(block.getByPosition(new_arguments[1]).type).isAggregateFunction())
std::swap(new_arguments[0], new_arguments[1]);
if (!block.getByPosition(new_arguments[1]).column->isColumnConst())
if (!isColumnConst(*block.getByPosition(new_arguments[1]).column))
throw Exception{"Illegal column " + block.getByPosition(new_arguments[1]).column->getName()
+ " of argument of aggregation state multiply. Should be integer constant", ErrorCodes::ILLEGAL_COLUMN};
const IColumn & agg_state_column = *block.getByPosition(new_arguments[0]).column;
bool agg_state_is_const = agg_state_column.isColumnConst();
bool agg_state_is_const = isColumnConst(agg_state_column);
const ColumnAggregateFunction & column = typeid_cast<const ColumnAggregateFunction &>(
agg_state_is_const ? static_cast<const ColumnConst &>(agg_state_column).getDataColumn() : agg_state_column);
@ -604,8 +604,8 @@ class FunctionBinaryArithmetic : public IFunction
const IColumn & lhs_column = *block.getByPosition(arguments[0]).column;
const IColumn & rhs_column = *block.getByPosition(arguments[1]).column;
bool lhs_is_const = lhs_column.isColumnConst();
bool rhs_is_const = rhs_column.isColumnConst();
bool lhs_is_const = isColumnConst(lhs_column);
bool rhs_is_const = isColumnConst(rhs_column);
const ColumnAggregateFunction & lhs = typeid_cast<const ColumnAggregateFunction &>(
lhs_is_const ? static_cast<const ColumnConst &>(lhs_column).getDataColumn() : lhs_column);

View File

@ -19,7 +19,7 @@ namespace ErrorCodes
const ColumnConst * checkAndGetColumnConstStringOrFixedString(const IColumn * column)
{
if (!column->isColumnConst())
if (!isColumnConst(*column))
return {};
const ColumnConst * res = static_cast<const ColumnConst *>(column);
@ -64,17 +64,14 @@ static Block createBlockWithNestedColumnsImpl(const Block & block, const std::un
{
res.insert({nullptr, nested_type, col.name});
}
else if (col.column->isColumnNullable())
else if (auto * nullable = checkAndGetColumn<ColumnNullable>(*col.column))
{
const auto & nested_col = static_cast<const ColumnNullable &>(*col.column).getNestedColumnPtr();
const auto & nested_col = nullable->getNestedColumnPtr();
res.insert({nested_col, nested_type, col.name});
}
else if (col.column->isColumnConst())
else if (auto * const_column = checkAndGetColumn<ColumnConst>(*col.column))
{
const auto & nested_col = static_cast<const ColumnNullable &>(
static_cast<const ColumnConst &>(*col.column).getDataColumn()).getNestedColumnPtr();
const auto & nested_col = checkAndGetColumn<ColumnNullable>(const_column->getDataColumn())->getNestedColumnPtr();
res.insert({ ColumnConst::create(nested_col, col.column->size()), nested_type, col.name});
}
else

View File

@ -22,23 +22,10 @@ const Type * checkAndGetDataType(const IDataType * data_type)
return typeid_cast<const Type *>(data_type);
}
template <typename Type>
const Type * checkAndGetColumn(const IColumn * column)
{
return typeid_cast<const Type *>(column);
}
template <typename Type>
bool checkColumn(const IColumn * column)
{
return checkAndGetColumn<Type>(column);
}
template <typename Type>
const ColumnConst * checkAndGetColumnConst(const IColumn * column)
{
if (!column || !column->isColumnConst())
if (!column || !isColumnConst(*column))
return {};
const ColumnConst * res = static_cast<const ColumnConst *>(column);

View File

@ -56,7 +56,7 @@ namespace ErrorCodes
*
* Two bitmap andnot calculation, return cardinality:
* bitmapAndnotCardinality: bitmap,bitmap -> integer
*
*
* Determine if a bitmap contains the given integer:
* bitmapContains: bitmap,integer -> bool
*
@ -432,28 +432,28 @@ private:
Block & block, const ColumnNumbers & arguments, size_t input_rows_count, typename ColumnVector<UInt8>::Container & vec_to)
{
const IColumn * columns[2];
bool isColumnConst[2];
bool is_column_const[2];
const PaddedPODArray<AggregateDataPtr> * container0;
const PaddedPODArray<UInt32> * container1;
for (size_t i = 0; i < 2; ++i)
{
columns[i] = block.getByPosition(arguments[i]).column.get();
isColumnConst[i] = typeid_cast<const ColumnConst*>(columns[i])!=nullptr;
is_column_const[i] = isColumnConst(*columns[i]);
}
if (isColumnConst[0])
if (is_column_const[0])
container0 = &typeid_cast<const ColumnAggregateFunction*>(typeid_cast<const ColumnConst*>(columns[0])->getDataColumnPtr().get())->getData();
else
container0 = &typeid_cast<const ColumnAggregateFunction*>(columns[0])->getData();
if (isColumnConst[1])
if (is_column_const[1])
container1 = &typeid_cast<const ColumnUInt32*>(typeid_cast<const ColumnConst*>(columns[1])->getDataColumnPtr().get())->getData();
else
container1 = &typeid_cast<const ColumnUInt32*>(columns[1])->getData();
for (size_t i = 0; i < input_rows_count; ++i)
{
const AggregateDataPtr dataPtr0 = isColumnConst[0] ? (*container0)[0] : (*container0)[i];
const UInt32 data1 = isColumnConst[1] ? (*container1)[0] : (*container1)[i];
const AggregateDataPtr dataPtr0 = is_column_const[0] ? (*container0)[0] : (*container0)[i];
const UInt32 data1 = is_column_const[1] ? (*container1)[0] : (*container1)[i];
const AggregateFunctionGroupBitmapData<T>& bd0
= *reinterpret_cast<const AggregateFunctionGroupBitmapData<T>*>(dataPtr0);
vec_to[i] = bd0.rbs.rb_contains(data1);
@ -529,18 +529,18 @@ private:
Block & block, const ColumnNumbers & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to)
{
const ColumnAggregateFunction * columns[2];
bool isColumnConst[2];
bool is_column_const[2];
for (size_t i = 0; i < 2; ++i)
{
if (auto argument_column_const = typeid_cast<const ColumnConst*>(block.getByPosition(arguments[i]).column.get()))
if (auto argument_column_const = checkAndGetColumn<ColumnConst>(block.getByPosition(arguments[i]).column.get()))
{
columns[i] = typeid_cast<const ColumnAggregateFunction*>(argument_column_const->getDataColumnPtr().get());
isColumnConst[i] = true;
is_column_const[i] = true;
}
else
{
columns[i] = typeid_cast<const ColumnAggregateFunction*>(block.getByPosition(arguments[i]).column.get());
isColumnConst[i] = false;
is_column_const[i] = false;
}
}
@ -549,8 +549,8 @@ private:
for (size_t i = 0; i < input_rows_count; ++i)
{
const AggregateDataPtr dataPtr0 = isColumnConst[0] ? container0[0] : container0[i];
const AggregateDataPtr dataPtr1 = isColumnConst[1] ? container1[0] : container1[i];
const AggregateDataPtr dataPtr0 = is_column_const[0] ? container0[0] : container0[i];
const AggregateDataPtr dataPtr1 = is_column_const[1] ? container1[0] : container1[i];
const AggregateFunctionGroupBitmapData<T> & bd1
= *reinterpret_cast<const AggregateFunctionGroupBitmapData<T>*>(dataPtr0);
const AggregateFunctionGroupBitmapData<T> & bd2

View File

@ -1032,8 +1032,8 @@ private:
void executeGenericIdenticalTypes(Block & block, size_t result, const IColumn * c0, const IColumn * c1)
{
bool c0_const = c0->isColumnConst();
bool c1_const = c1->isColumnConst();
bool c0_const = isColumnConst(*c0);
bool c1_const = isColumnConst(*c1);
if (c0_const && c1_const)
{

View File

@ -133,7 +133,7 @@ public:
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) override
{
if (block.getByPosition(arguments[1]).column->isColumnConst())
if (isColumnConst(*block.getByPosition(arguments[1]).column))
executeConstBuckets(block, arguments, result);
else
throw Exception(

View File

@ -1894,7 +1894,7 @@ private:
template <typename T>
static const PaddedPODArray<T> & getColumnDataAsPaddedPODArray(const IColumn & column, PaddedPODArray<T> & backup_storage)
{
if (!column.isColumnConst())
if (!isColumnConst(column))
{
if (const auto vector_col = checkAndGetColumn<ColumnVector<T>>(&column))
{

View File

@ -92,7 +92,7 @@ void FunctionModelEvaluate::executeImpl(Block & block, const ColumnNumbers & arg
materialized_columns.push_back(full_column);
columns.back() = full_column.get();
}
if (auto * col_nullable = typeid_cast<const ColumnNullable *>(columns.back()))
if (auto * col_nullable = checkAndGetColumn<ColumnNullable>(*columns.back()))
{
if (!null_map)
null_map = col_nullable->getNullMapColumnPtr();

View File

@ -130,7 +130,7 @@ public:
auto column_result = block.getByPosition(result).type->createColumn();
auto out_untyped = column_result.get();
if (!centroids_array_untyped->isColumnConst())
if (!isColumnConst(*centroids_array_untyped))
throw Exception{"Second argument of function " + getName() + " must be literal array", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
executeImplTyped(in_untyped, out_untyped, centroids_array_untyped);

View File

@ -1041,7 +1041,7 @@ private:
void executeTwoArgs(Block & block, const ColumnNumbers & arguments, const size_t result) const
{
const auto level_col = block.getByPosition(arguments.back()).column.get();
if (!level_col->isColumnConst())
if (!isColumnConst(*level_col))
throw Exception{"Second argument of function " + getName() + " must be an integral constant", ErrorCodes::ILLEGAL_COLUMN};
const auto level = level_col->get64(0);

View File

@ -213,7 +213,7 @@ private:
+ " should be a string specifying key or an integer specifying index, illegal type: " + column.type->getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
if (column.column->isColumnConst())
if (isColumnConst(*column.column))
{
const auto & column_const = static_cast<const ColumnConst &>(*column.column);
if (isString(column.type))

View File

@ -211,7 +211,7 @@ private:
bool has_res = false;
for (int i = static_cast<int>(in.size()) - 1; i >= 0; --i)
{
if (!in[i]->isColumnConst())
if (!isColumnConst(*in[i]))
continue;
Field value = (*in[i])[0];

View File

@ -512,7 +512,7 @@ public:
if (arguments.size() == 2)
{
const IColumn & scale_column = *block.getByPosition(arguments[1]).column;
if (!scale_column.isColumnConst())
if (!isColumnConst(scale_column))
throw Exception("Scale argument for rounding functions must be constant.", ErrorCodes::ILLEGAL_COLUMN);
Field scale_field = static_cast<const ColumnConst &>(scale_column).getField();

View File

@ -814,7 +814,7 @@ public:
const ColumnPtr column_needle = block.getByPosition(arguments[1]).column;
const ColumnPtr column_replacement = block.getByPosition(arguments[2]).column;
if (!column_needle->isColumnConst() || !column_replacement->isColumnConst())
if (!isColumnConst(*column_needle) || !isColumnConst(*column_replacement))
throw Exception("2nd and 3rd arguments of function " + getName() + " must be constants.", ErrorCodes::ILLEGAL_COLUMN);
const IColumn * c1 = block.getByPosition(arguments[1]).column.get();

View File

@ -111,10 +111,10 @@ ColumnPtr wrapInNullable(const ColumnPtr & src, const Block & block, const Colum
if (src->onlyNull())
return src;
else if (src->isColumnNullable())
else if (auto * nullable = checkAndGetColumn<ColumnNullable>(*src))
{
src_not_nullable = static_cast<const ColumnNullable &>(*src).getNestedColumnPtr();
result_null_map_column = static_cast<const ColumnNullable &>(*src).getNullMapColumnPtr();
src_not_nullable = nullable->getNestedColumnPtr();
result_null_map_column = nullable->getNullMapColumnPtr();
}
for (const auto & arg : args)
@ -127,12 +127,12 @@ ColumnPtr wrapInNullable(const ColumnPtr & src, const Block & block, const Colum
if (elem.column->onlyNull())
return block.getByPosition(result).type->createColumnConst(input_rows_count, Null());
if (elem.column->isColumnConst())
if (isColumnConst(*elem.column))
continue;
if (elem.column->isColumnNullable())
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*elem.column))
{
const ColumnPtr & null_map_column = static_cast<const ColumnNullable &>(*elem.column).getNullMapColumnPtr();
const ColumnPtr & null_map_column = nullable->getNullMapColumnPtr();
if (!result_null_map_column)
{
result_null_map_column = null_map_column;
@ -204,7 +204,7 @@ NullPresence getNullPresense(const ColumnsWithTypeAndName & args)
bool allArgumentsAreConstants(const Block & block, const ColumnNumbers & args)
{
for (auto arg : args)
if (!block.getByPosition(arg).column->isColumnConst())
if (!isColumnConst(*block.getByPosition(arg).column))
return false;
return true;
}
@ -217,7 +217,7 @@ bool PreparedFunctionImpl::defaultImplementationForConstantArguments(Block & blo
/// Check that these arguments are really constant.
for (auto arg_num : arguments_to_remain_constants)
if (arg_num < args.size() && !block.getByPosition(args[arg_num]).column->isColumnConst())
if (arg_num < args.size() && !isColumnConst(*block.getByPosition(args[arg_num]).column))
throw Exception("Argument at index " + toString(arg_num) + " for function " + getName() + " must be constant", ErrorCodes::ILLEGAL_COLUMN);
if (args.empty() || !useDefaultImplementationForConstants() || !allArgumentsAreConstants(block, args))
@ -583,7 +583,7 @@ DataTypePtr FunctionBuilderImpl::getReturnType(const ColumnsWithTypeAndName & ar
for (ColumnWithTypeAndName & arg : args_without_low_cardinality)
{
bool is_const = arg.column && arg.column->isColumnConst();
bool is_const = arg.column && isColumnConst(*arg.column);
if (is_const)
arg.column = static_cast<const ColumnConst &>(*arg.column).removeLowCardinality();

View File

@ -100,13 +100,12 @@ void FunctionArrayDistinct::executeImpl(Block & block, const ColumnNumbers & arg
IColumn & res_data = res.getData();
ColumnArray::Offsets & res_offsets = res.getOffsets();
const ColumnNullable * nullable_col = nullptr;
const ColumnNullable * nullable_col = checkAndGetColumn<ColumnNullable>(src_data);
const IColumn * inner_col;
if (src_data.isColumnNullable())
if (nullable_col)
{
nullable_col = static_cast<const ColumnNullable *>(&src_data);
inner_col = &nullable_col->getNestedColumn();
}
else

View File

@ -749,12 +749,12 @@ void FunctionArrayElement::executeImpl(Block & block, const ColumnNumbers & argu
col_array = checkAndGetColumn<ColumnArray>(block.getByPosition(arguments[0]).column.get());
if (col_array)
is_array_of_nullable = col_array->getData().isColumnNullable();
is_array_of_nullable = isColumnNullable(col_array->getData());
else
{
col_const_array = checkAndGetColumnConstData<ColumnArray>(block.getByPosition(arguments[0]).column.get());
if (col_const_array)
is_array_of_nullable = col_const_array->getData().isColumnNullable();
is_array_of_nullable = isColumnNullable(col_const_array->getData());
else
throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName()
+ " of first argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN);
@ -836,7 +836,7 @@ void FunctionArrayElement::perform(Block & block, const ColumnNumbers & argument
if (executeTuple(block, arguments, result, input_rows_count))
{
}
else if (!block.getByPosition(arguments[1]).column->isColumnConst())
else if (!isColumnConst(*block.getByPosition(arguments[1]).column))
{
if (!(executeArgument<UInt8>(block, arguments, result, builder, input_rows_count)
|| executeArgument<UInt16>(block, arguments, result, builder, input_rows_count)

View File

@ -157,14 +157,12 @@ void FunctionArrayEnumerateExtended<Derived>::executeImpl(Block & block, const C
for (size_t i = 0; i < num_arguments; ++i)
{
if (data_columns[i]->isColumnNullable())
if (auto * nullable_col = checkAndGetColumn<ColumnNullable>(*data_columns[i]))
{
const auto & nullable_col = static_cast<const ColumnNullable &>(*data_columns[i]);
if (num_arguments == 1)
data_columns[i] = &nullable_col.getNestedColumn();
data_columns[i] = &nullable_col->getNestedColumn();
null_map = &nullable_col.getNullMapData();
null_map = &nullable_col->getNullMapData();
break;
}
}

View File

@ -47,7 +47,7 @@ ArraysDepths getArraysDepths(const ColumnsWithTypeAndName & arguments)
{
const auto & depth_column = arguments[i].column;
if (depth_column && depth_column->isColumnConst())
if (depth_column && isColumnConst(*depth_column))
{
UInt64 value = static_cast<const ColumnConst &>(*depth_column).getValue<UInt64>();
if (!value)

View File

@ -751,7 +751,7 @@ private:
Array arr = col_array->getValue<Array>();
const auto item_arg = block.getByPosition(arguments[1]).column.get();
if (item_arg->isColumnConst())
if (isColumnConst(*item_arg))
{
typename IndexConv::ResultType current = 0;
const auto & value = (*item_arg)[0];
@ -848,7 +848,7 @@ private:
if (item_arg.onlyNull())
ArrayIndexGenericNullImpl<IndexConv>::vector(col_nested, col_array->getOffsets(),
col_res->getData(), null_map_data);
else if (item_arg.isColumnConst())
else if (isColumnConst(item_arg))
ArrayIndexGenericImpl<IndexConv, true>::vector(col_nested, col_array->getOffsets(),
static_cast<const ColumnConst &>(item_arg).getDataColumn(), col_res->getData(), /// TODO This is wrong.
null_map_data, nullptr);
@ -907,22 +907,20 @@ public:
/// (they are vectors of Fields, which may represent the NULL value),
/// they do not require any preprocessing
/// Check if the 1st function argument is a non-constant array of nullable
/// values.
bool is_nullable;
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(block.getByPosition(arguments[0]).column.get());
const ColumnNullable * nullable = nullptr;
if (col_array)
is_nullable = col_array->getData().isColumnNullable();
else
is_nullable = false;
nullable = checkAndGetColumn<ColumnNullable>(col_array->getData());
/// Check nullability of the 2nd function argument.
bool is_arg_nullable = block.getByPosition(arguments[1]).column->isColumnNullable();
auto & arg_column = block.getByPosition(arguments[1]).column;
if (!is_nullable && !is_arg_nullable)
const ColumnNullable * arg_nullable = nullptr;
arg_nullable = checkAndGetColumn<ColumnNullable>(*arg_column);
if (!nullable && !arg_nullable)
{
/// Simple case: no nullable value is passed.
/// Simple case: no nullable values passeded.
perform(block, arguments, result);
}
else
@ -955,10 +953,9 @@ public:
}
};
if (is_nullable)
if (nullable)
{
const auto & nullable_col = static_cast<const ColumnNullable &>(col_array->getData());
const auto & nested_col = nullable_col.getNestedColumnPtr();
const auto & nested_col = nullable->getNestedColumnPtr();
auto & data = source_block.getByPosition(0);
data.column = ColumnArray::create(nested_col, col_array->getOffsetsPtr());
@ -967,7 +964,7 @@ public:
*static_cast<const DataTypeArray &>(*block.getByPosition(arguments[0]).type).getNestedType()).getNestedType());
auto & null_map = source_block.getByPosition(2);
null_map.column = nullable_col.getNullMapColumnPtr();
null_map.column = nullable->getNullMapColumnPtr();
null_map.type = std::make_shared<DataTypeUInt8>();
}
else
@ -976,17 +973,14 @@ public:
data = block.getByPosition(arguments[0]);
}
if (is_arg_nullable)
if (arg_nullable)
{
const auto & col = block.getByPosition(arguments[1]).column;
const auto & nullable_col = static_cast<const ColumnNullable &>(*col);
auto & arg = source_block.getByPosition(1);
arg.column = nullable_col.getNestedColumnPtr();
arg.column = arg_nullable->getNestedColumnPtr();
arg.type = static_cast<const DataTypeNullable &>(*block.getByPosition(arguments[1]).type).getNestedType();
auto & null_map = source_block.getByPosition(3);
null_map.column = nullable_col.getNullMapColumnPtr();
null_map.column = arg_nullable->getNullMapColumnPtr();
null_map.type = std::make_shared<DataTypeUInt8>();
}
else

View File

@ -124,7 +124,7 @@ public:
auto sink = GatherUtils::createArraySink(typeid_cast<ColumnArray &>(*result_column), size);
if (size_column->isColumnConst())
if (isColumnConst(*size_column))
GatherUtils::resizeConstantSize(*array_source, *value_source, *sink, size_column->getInt(0));
else
GatherUtils::resizeDynamicSize(*array_source, *value_source, *sink, *size_column);

View File

@ -110,7 +110,7 @@ public:
block.getByPosition(result).column = array_column;
return;
}
else if (length_column->isColumnConst())
else if (isColumnConst(*length_column))
GatherUtils::sliceFromLeftConstantOffsetBounded(*source, *sink, 0, length_column->getInt(0));
else
{
@ -118,7 +118,7 @@ public:
GatherUtils::sliceDynamicOffsetBounded(*source, *sink, *const_offset_column, *length_column);
}
}
else if (offset_column->isColumnConst())
else if (isColumnConst(*offset_column))
{
ssize_t offset = offset_column->getUInt(0);
@ -129,7 +129,7 @@ public:
else
GatherUtils::sliceFromRightConstantOffsetUnbounded(*source, *sink, static_cast<size_t>(-offset));
}
else if (length_column->isColumnConst())
else if (isColumnConst(*length_column))
{
ssize_t length = length_column->getInt(0);
if (offset > 0)

View File

@ -154,14 +154,12 @@ void FunctionArrayUniq::executeImpl(Block & block, const ColumnNumbers & argumen
for (size_t i = 0; i < num_arguments; ++i)
{
if (data_columns[i]->isColumnNullable())
if (auto * nullable_col = checkAndGetColumn<ColumnNullable>(*data_columns[i]))
{
const auto & nullable_col = static_cast<const ColumnNullable &>(*data_columns[i]);
if (num_arguments == 1)
data_columns[i] = &nullable_col.getNestedColumn();
data_columns[i] = &nullable_col->getNestedColumn();
null_map = &nullable_col.getNullMapData();
null_map = &nullable_col->getNullMapData();
break;
}
}

View File

@ -392,16 +392,15 @@ void FunctionEmptyArrayToSingle::executeImpl(Block & block, const ColumnNumbers
const IColumn * inner_col;
IColumn * inner_res_col;
bool nullable = src_data.isColumnNullable();
if (nullable)
auto nullable_col = checkAndGetColumn<ColumnNullable>(src_data);
if (nullable_col)
{
auto nullable_col = static_cast<const ColumnNullable *>(&src_data);
inner_col = &nullable_col->getNestedColumn();
src_null_map = &nullable_col->getNullMapData();
auto nullable_res_col = static_cast<ColumnNullable *>(&res_data);
inner_res_col = &nullable_res_col->getNestedColumn();
res_null_map = &nullable_res_col->getNullMapData();
auto & nullable_res_col = static_cast<ColumnNullable &>(res_data);
inner_res_col = &nullable_res_col.getNestedColumn();
res_null_map = &nullable_res_col.getNullMapData();
}
else
{
@ -409,7 +408,7 @@ void FunctionEmptyArrayToSingle::executeImpl(Block & block, const ColumnNumbers
inner_res_col = &res_data;
}
if (nullable)
if (nullable_col)
FunctionEmptyArrayToSingleImpl::executeDispatch<true>(*inner_col, src_offsets, *inner_res_col, res_offsets, src_null_map, res_null_map);
else
FunctionEmptyArrayToSingleImpl::executeDispatch<false>(*inner_col, src_offsets, *inner_res_col, res_offsets, src_null_map, res_null_map);

View File

@ -42,11 +42,8 @@ public:
const ColumnPtr & col = block.getByPosition(arguments[0]).column;
ColumnPtr & res_col = block.getByPosition(result).column;
if (col->isColumnNullable())
{
const ColumnNullable & nullable_col = static_cast<const ColumnNullable &>(*col);
res_col = nullable_col.getNestedColumnPtr();
}
if (auto * nullable_col = checkAndGetColumn<ColumnNullable>(*col))
res_col = nullable_col->getNestedColumnPtr();
else
res_col = col;
}

View File

@ -108,7 +108,7 @@ private:
{
const auto & column = *block.getByPosition(arguments[argument_pos]).column;
if (!column.isColumnConst())
if (!isColumnConst(column))
throw Exception(
which_argument + String(" argument for function ") + getName() + " must be constant.", ErrorCodes::ILLEGAL_COLUMN);

View File

@ -7,6 +7,7 @@
#include <DataTypes/getLeastSupertype.h>
#include <Core/ColumnNumbers.h>
#include <Columns/ColumnNullable.h>
#include <Columns/ColumnLowCardinality.h>
namespace DB
@ -150,8 +151,15 @@ public:
ColumnPtr res = std::move(temp_block.getByPosition(result).column);
/// if last argument is not nullable, result should be also not nullable
if (!block.getByPosition(multi_if_args.back()).column->isColumnNullable() && res->isColumnNullable())
res = static_cast<const ColumnNullable &>(*res).getNestedColumnPtr();
if (!block.getByPosition(multi_if_args.back()).column->isNullable() && res->isNullable())
{
if (auto * column_lc = checkAndGetColumn<ColumnLowCardinality>(*res))
res = checkAndGetColumn<ColumnNullable>(*column_lc->convertToFullColumn())->getNestedColumnPtr();
else if (auto * column_const = checkAndGetColumn<ColumnConst>(*res))
res = checkAndGetColumn<ColumnNullable>(column_const->getDataColumn())->getNestedColumnPtr();
else
res = checkAndGetColumn<ColumnNullable>(*res)->getNestedColumnPtr();
}
block.getByPosition(result).column = std::move(res);
}

View File

@ -605,8 +605,8 @@ private:
MutableColumnPtr result_column = common_type->createColumn();
result_column->reserve(input_rows_count);
bool then_is_const = col_then->isColumnConst();
bool else_is_const = col_else->isColumnConst();
bool then_is_const = isColumnConst(*col_then);
bool else_is_const = isColumnConst(*col_else);
const auto & cond_array = cond_col->getData();
@ -660,7 +660,6 @@ private:
{
const ColumnWithTypeAndName & arg_cond = block.getByPosition(arguments[0]);
bool cond_is_null = arg_cond.column->onlyNull();
bool cond_is_nullable = arg_cond.column->isColumnNullable();
if (cond_is_null)
{
@ -668,11 +667,11 @@ private:
return true;
}
if (cond_is_nullable)
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*arg_cond.column))
{
Block temporary_block
{
{ static_cast<const ColumnNullable &>(*arg_cond.column).getNestedColumnPtr(), removeNullable(arg_cond.type), arg_cond.name },
{ nullable->getNestedColumnPtr(), removeNullable(arg_cond.type), arg_cond.name },
block.getByPosition(arguments[1]),
block.getByPosition(arguments[2]),
block.getByPosition(result)
@ -694,7 +693,7 @@ private:
static ColumnPtr makeNullableColumnIfNot(const ColumnPtr & column)
{
if (column->isColumnNullable())
if (isColumnNullable(*column))
return column;
return ColumnNullable::create(
@ -703,8 +702,8 @@ private:
static ColumnPtr getNestedColumn(const ColumnPtr & column)
{
if (column->isColumnNullable())
return static_cast<const ColumnNullable &>(*column).getNestedColumnPtr();
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*column))
return nullable->getNestedColumnPtr();
return column;
}
@ -715,8 +714,8 @@ private:
const ColumnWithTypeAndName & arg_then = block.getByPosition(arguments[1]);
const ColumnWithTypeAndName & arg_else = block.getByPosition(arguments[2]);
bool then_is_nullable = typeid_cast<const ColumnNullable *>(arg_then.column.get());
bool else_is_nullable = typeid_cast<const ColumnNullable *>(arg_else.column.get());
auto * then_is_nullable = checkAndGetColumn<ColumnNullable>(*arg_then.column);
auto * else_is_nullable = checkAndGetColumn<ColumnNullable>(*arg_else.column);
if (!then_is_nullable && !else_is_nullable)
return false;
@ -731,14 +730,14 @@ private:
arg_cond,
{
then_is_nullable
? static_cast<const ColumnNullable *>(arg_then.column.get())->getNullMapColumnPtr()
? then_is_nullable->getNullMapColumnPtr()
: DataTypeUInt8().createColumnConstWithDefaultValue(input_rows_count),
std::make_shared<DataTypeUInt8>(),
""
},
{
else_is_nullable
? static_cast<const ColumnNullable *>(arg_else.column.get())->getNullMapColumnPtr()
? else_is_nullable->getNullMapColumnPtr()
: DataTypeUInt8().createColumnConstWithDefaultValue(input_rows_count),
std::make_shared<DataTypeUInt8>(),
""
@ -814,7 +813,7 @@ private:
{
if (cond_col)
{
if (arg_else.column->isColumnNullable())
if (isColumnNullable(*arg_else.column))
{
auto arg_else_column = arg_else.column;
auto result_column = (*std::move(arg_else_column)).mutate();
@ -856,7 +855,7 @@ private:
for (size_t i = 0; i < size; ++i)
negated_null_map_data[i] = !null_map_data[i];
if (arg_then.column->isColumnNullable())
if (isColumnNullable(*arg_then.column))
{
auto arg_then_column = arg_then.column;
auto result_column = (*std::move(arg_then_column)).mutate();

View File

@ -38,11 +38,11 @@ public:
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override
{
const ColumnWithTypeAndName & elem = block.getByPosition(arguments[0]);
if (elem.column->isColumnNullable())
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*elem.column))
{
/// Return the negated null map.
auto res_column = ColumnUInt8::create(input_rows_count);
const auto & src_data = static_cast<const ColumnNullable &>(*elem.column).getNullMapData();
const auto & src_data = nullable->getNullMapData();
auto & res_data = static_cast<ColumnUInt8 &>(*res_column).getData();
for (size_t i = 0; i < input_rows_count; ++i)

View File

@ -38,10 +38,10 @@ public:
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t) override
{
const ColumnWithTypeAndName & elem = block.getByPosition(arguments[0]);
if (elem.column->isColumnNullable())
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*elem.column))
{
/// Merely return the embedded null map.
block.getByPosition(result).column = static_cast<const ColumnNullable &>(*elem.column).getNullMapColumnPtr();
block.getByPosition(result).column = nullable->getNullMapColumnPtr();
}
else
{

View File

@ -141,7 +141,7 @@ public:
if (cond_col.column->onlyNull())
continue;
if (cond_col.column->isColumnConst())
if (isColumnConst(*cond_col.column))
{
Field value = typeid_cast<const ColumnConst &>(*cond_col.column).getField();
if (value.isNull())
@ -152,7 +152,7 @@ public:
}
else
{
if (cond_col.column->isColumnNullable())
if (isColumnNullable(*cond_col.column))
instruction.condition_is_nullable = true;
instruction.condition = cond_col.column.get();
@ -171,7 +171,7 @@ public:
instruction.source = converted_columns_holder.back().get();
}
if (instruction.source && instruction.source->isColumnConst())
if (instruction.source && isColumnConst(*instruction.source))
instruction.source_is_constant = true;
instructions.emplace_back(std::move(instruction));

View File

@ -167,7 +167,7 @@ public:
const auto & res_type = block.getByPosition(result).type;
/// When column is constant, its difference is zero.
if (src.column->isColumnConst())
if (isColumnConst(*src.column))
{
block.getByPosition(result).column = res_type->createColumnConstWithDefaultValue(input_rows_count);
return;

View File

@ -69,7 +69,7 @@ public:
{
const IColumn * col = block.getByPosition(arguments[0]).column.get();
if (!col->isColumnConst())
if (!isColumnConst(*col))
throw Exception("The argument of function " + getName() + " must be constant.", ErrorCodes::ILLEGAL_COLUMN);
Float64 seconds = applyVisitor(FieldVisitorConvertToNumber<Float64>(), static_cast<const ColumnConst &>(*col).getField());

View File

@ -155,7 +155,7 @@ public:
const auto in = block.getByPosition(arguments.front()).column.get();
if (in->isColumnConst())
if (isColumnConst(*in))
{
executeConst(block, arguments, result, input_rows_count);
return;
@ -228,7 +228,7 @@ private:
executeImplNumToNum<T>(in->getData(), out->getData());
}
else if (default_untyped->isColumnConst())
else if (isColumnConst(*default_untyped))
{
if (!executeNumToNumWithConstDefault<T, UInt8>(in, out_untyped)
&& !executeNumToNumWithConstDefault<T, UInt16>(in, out_untyped)
@ -281,7 +281,7 @@ private:
throw Exception{"Illegal column " + in->getName() + " of elements of array of second argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN};
}
else if (default_untyped->isColumnConst())
else if (isColumnConst(*default_untyped))
{
if (!executeStringToNumWithConstDefault<UInt8>(in, out_untyped)
&& !executeStringToNumWithConstDefault<UInt16>(in, out_untyped)

View File

@ -1233,7 +1233,7 @@ Block Aggregator::prepareBlockAndFill(
/// Change the size of the columns-constants in the block.
size_t columns = header.columns();
for (size_t i = 0; i < columns; ++i)
if (res.getByPosition(i).column->isColumnConst())
if (isColumnConst(*res.getByPosition(i).column))
res.getByPosition(i).column = res.getByPosition(i).column->cut(0, rows);
return res;

View File

@ -307,8 +307,12 @@ struct AggregationMethodKeysFixed
IColumn * observed_column;
ColumnUInt8 * null_map;
bool column_nullable = false;
if constexpr (has_nullable_keys)
column_nullable = isColumnNullable(*key_columns[i]);
/// If we have a nullable column, get its nested column and its null map.
if (has_nullable_keys && key_columns[i]->isColumnNullable())
if (column_nullable)
{
ColumnNullable & nullable_col = static_cast<ColumnNullable &>(*key_columns[i]);
observed_column = &nullable_col.getNestedColumn();
@ -320,8 +324,8 @@ struct AggregationMethodKeysFixed
null_map = nullptr;
}
bool is_null;
if (has_nullable_keys && key_columns[i]->isColumnNullable())
bool is_null = false;
if (column_nullable)
{
/// The current column is nullable. Check if the value of the
/// corresponding key is nullable. Update the null map accordingly.
@ -331,8 +335,6 @@ struct AggregationMethodKeysFixed
null_map->insertValue(val);
is_null = val == 1;
}
else
is_null = false;
if (has_nullable_keys && is_null)
observed_column->insertDefault();

View File

@ -191,7 +191,7 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings)
{
arguments[i] = sample_block.getPositionByName(argument_names[i]);
ColumnPtr col = sample_block.safeGetByPosition(arguments[i]).column;
if (!col || !col->isColumnConst())
if (!col || !isColumnConst(*col))
all_const = false;
}
@ -215,7 +215,7 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings)
/// If the result is not a constant, just in case, we will consider the result as unknown.
ColumnWithTypeAndName & col = sample_block.safeGetByPosition(result_position);
if (!col.column->isColumnConst())
if (!isColumnConst(*col.column))
{
col.column = nullptr;
}
@ -610,14 +610,14 @@ void ExpressionActions::checkLimits(Block & block) const
{
size_t non_const_columns = 0;
for (size_t i = 0, size = block.columns(); i < size; ++i)
if (block.safeGetByPosition(i).column && !block.safeGetByPosition(i).column->isColumnConst())
if (block.safeGetByPosition(i).column && !isColumnConst(*block.safeGetByPosition(i).column))
++non_const_columns;
if (non_const_columns > settings.max_temporary_non_const_columns)
{
std::stringstream list_of_non_const_columns;
for (size_t i = 0, size = block.columns(); i < size; ++i)
if (block.safeGetByPosition(i).column && !block.safeGetByPosition(i).column->isColumnConst())
if (block.safeGetByPosition(i).column && !isColumnConst(*block.safeGetByPosition(i).column))
list_of_non_const_columns << "\n" << block.safeGetByPosition(i).name;
throw Exception("Too many temporary non-const columns:" + list_of_non_const_columns.str()

View File

@ -186,7 +186,7 @@ void ExpressionAnalyzer::analyzeAggregation()
const auto & col = block.getByName(column_name);
/// Constant expressions have non-null column pointer at this stage.
if (col.column && col.column->isColumnConst())
if (col.column && isColumnConst(*col.column))
{
/// But don't remove last key column if no aggregate functions, otherwise aggregation will not work.
if (!aggregate_descriptions.empty() || size > 1)

View File

@ -85,7 +85,7 @@ namespace
static ColumnData getColumnData(const IColumn * column)
{
ColumnData result;
const bool is_const = column->isColumnConst();
const bool is_const = isColumnConst(*column);
if (is_const)
column = &reinterpret_cast<const ColumnConst *>(column)->getDataColumn();
if (auto * nullable = typeid_cast<const ColumnNullable *>(column))

View File

@ -138,7 +138,7 @@ Join::Type Join::chooseMethod(const ColumnRawPtrs & key_columns, Sizes & key_siz
/// If there is single string key, use hash table of it's values.
if (keys_size == 1
&& (typeid_cast<const ColumnString *>(key_columns[0])
|| (key_columns[0]->isColumnConst() && typeid_cast<const ColumnString *>(&static_cast<const ColumnConst *>(key_columns[0])->getDataColumn()))))
|| (isColumnConst(*key_columns[0]) && typeid_cast<const ColumnString *>(&static_cast<const ColumnConst *>(key_columns[0])->getDataColumn()))))
return Type::key_string;
if (keys_size == 1 && typeid_cast<const ColumnFixedString *>(key_columns[0]))
@ -287,8 +287,8 @@ void Join::setSampleBlock(const Block & block)
}
/// We will join only keys, where all components are not NULL.
if (key_columns[i]->isColumnNullable())
key_columns[i] = &static_cast<const ColumnNullable &>(*key_columns[i]).getNestedColumn();
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*key_columns[i]))
key_columns[i] = &nullable->getNestedColumn();
}
if (strictness == ASTTableJoin::Strictness::Asof)
@ -1408,7 +1408,7 @@ private:
const auto & dst = out_block.getByPosition(key_pos).column;
const auto & src = sample_block_with_keys.getByPosition(i).column;
if (dst->isColumnNullable() != src->isColumnNullable())
if (isColumnNullable(*dst) != isColumnNullable(*src))
nullability_changes.insert(key_pos);
}
@ -1423,8 +1423,8 @@ private:
if (changes_bitmap[i])
{
ColumnPtr column = std::move(columns[i]);
if (column->isColumnNullable())
column = static_cast<const ColumnNullable &>(*column).getNestedColumnPtr();
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*column))
column = nullable->getNestedColumnPtr();
else
column = makeNullable(column);

View File

@ -9,32 +9,30 @@ void extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ColumnPtr & nul
if (key_columns.size() == 1)
{
auto & column = key_columns[0];
if (!column->isColumnNullable())
return;
const ColumnNullable & column_nullable = static_cast<const ColumnNullable &>(*column);
null_map = &column_nullable.getNullMapData();
column = &column_nullable.getNestedColumn();
if (auto * column_nullable = checkAndGetColumn<ColumnNullable>(*column))
{
null_map = &column_nullable->getNullMapData();
column = &column_nullable->getNestedColumn();
}
}
else
{
for (auto & column : key_columns)
{
if (column->isColumnNullable())
if (auto * column_nullable = checkAndGetColumn<ColumnNullable>(*column))
{
const ColumnNullable & column_nullable = static_cast<const ColumnNullable &>(*column);
column = &column_nullable.getNestedColumn();
column = &column_nullable->getNestedColumn();
if (!null_map_holder)
{
null_map_holder = column_nullable.getNullMapColumnPtr();
null_map_holder = column_nullable->getNullMapColumnPtr();
}
else
{
MutableColumnPtr mutable_null_map_holder = (*std::move(null_map_holder)).mutate();
PaddedPODArray<UInt8> & mutable_null_map = static_cast<ColumnUInt8 &>(*mutable_null_map_holder).getData();
const PaddedPODArray<UInt8> & other_null_map = column_nullable.getNullMapData();
const PaddedPODArray<UInt8> & other_null_map = column_nullable->getNullMapData();
for (size_t i = 0, size = mutable_null_map.size(); i < size; ++i)
mutable_null_map[i] |= other_null_map[i];

View File

@ -73,10 +73,9 @@ typename SetVariantsTemplate<Variant>::Type SetVariantsTemplate<Variant>::choose
for (const auto & col : key_columns)
{
if (col->isColumnNullable())
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*col))
{
const ColumnNullable & nullable_col = static_cast<const ColumnNullable &>(*col);
nested_key_columns.push_back(&nullable_col.getNestedColumn());
nested_key_columns.push_back(&nullable->getNestedColumn());
has_nullable_key = true;
}
else
@ -157,7 +156,7 @@ typename SetVariantsTemplate<Variant>::Type SetVariantsTemplate<Variant>::choose
/// If there is single string key, use hash table of it's values.
if (keys_size == 1
&& (typeid_cast<const ColumnString *>(nested_key_columns[0])
|| (nested_key_columns[0]->isColumnConst() && typeid_cast<const ColumnString *>(&static_cast<const ColumnConst *>(nested_key_columns[0])->getDataColumn()))))
|| (isColumnConst(*nested_key_columns[0]) && typeid_cast<const ColumnString *>(&static_cast<const ColumnConst *>(nested_key_columns[0])->getDataColumn()))))
return Type::key_string;
if (keys_size == 1 && typeid_cast<const ColumnFixedString *>(nested_key_columns[0]))

View File

@ -78,11 +78,10 @@ protected:
for (const auto & col : key_columns)
{
if (col->isColumnNullable())
if (auto * nullable = checkAndGetColumn<ColumnNullable>(*col))
{
const auto & nullable_col = static_cast<const ColumnNullable &>(*col);
actual_columns.push_back(&nullable_col.getNestedColumn());
null_maps.push_back(&nullable_col.getNullMapColumn());
actual_columns.push_back(&nullable->getNestedColumn());
null_maps.push_back(&nullable->getNullMapColumn());
}
else
{

View File

@ -30,7 +30,7 @@ IColumn::Selector createBlockSelector(
using UnsignedT = std::make_unsigned_t<T>;
/// const columns contain only one value, therefore we do not need to read it at every iteration
if (column.isColumnConst())
if (isColumnConst(column))
{
const auto data = static_cast<const ColumnConst &>(column).getValue<T>();
const auto shard_num = slots[static_cast<UnsignedT>(data) % total_weight];

View File

@ -50,7 +50,7 @@ std::pair<Field, std::shared_ptr<const IDataType>> evaluateConstantExpression(co
const ColumnWithTypeAndName & result = block_with_constants.getByName(name);
const IColumn & result_column = *result.column;
if (!result_column.isColumnConst())
if (!isColumnConst(result_column))
throw Exception("Element of set in IN, VALUES or LIMIT is not a constant expression: " + name, ErrorCodes::BAD_ARGUMENTS);
return std::make_pair(result_column[0], result.type);

View File

@ -334,7 +334,7 @@ bool KeyCondition::getConstant(const ASTPtr & expr, Block & block_with_constants
out_type = block_with_constants.getByName(column_name).type;
return true;
}
else if (block_with_constants.has(column_name) && block_with_constants.getByName(column_name).column->isColumnConst())
else if (block_with_constants.has(column_name) && isColumnConst(*block_with_constants.getByName(column_name).column))
{
/// An expression which is dependent on constants only
const auto & expr_info = block_with_constants.getByName(column_name);

View File

@ -243,7 +243,7 @@ static void checkKeyExpression(const ExpressionActions & expr, const Block & sam
for (const ColumnWithTypeAndName & element : sample_block)
{
const ColumnPtr & column = element.column;
if (column && (column->isColumnConst() || column->isDummy()))
if (column && (isColumnConst(*column) || column->isDummy()))
throw Exception{key_name + " key cannot contain constants", ErrorCodes::ILLEGAL_COLUMN};
if (element.type->isNullable())

View File

@ -276,7 +276,7 @@ bool MergeTreeIndexConditionSet::mayBeTrueOnGranule(MergeTreeIndexGranulePtr idx
const NullMap * null_map = nullptr;
if (auto * col_nullable = typeid_cast<const ColumnNullable *>(column.get()))
if (auto * col_nullable = checkAndGetColumn<ColumnNullable>(*column))
{
col_uint8 = typeid_cast<const ColumnUInt8 *>(&col_nullable->getNestedColumn());
null_map = &col_nullable->getNullMapData();

View File

@ -303,7 +303,7 @@ bool MergeTreeWhereOptimizer::isConstant(const ASTPtr & expr) const
const auto column_name = expr->getColumnName();
if (expr->as<ASTLiteral>()
|| (block_with_constants.has(column_name) && block_with_constants.getByName(column_name).column->isColumnConst()))
|| (block_with_constants.has(column_name) && isColumnConst(*block_with_constants.getByName(column_name).column)))
return true;
return false;

View File

@ -0,0 +1,11 @@
1 Nullable(UInt8)
2 Nullable(UInt8)
1 Nullable(UInt8)
\N Nullable(Nothing)
1 Nullable(UInt8)
2 Nullable(UInt8)
1 Nullable(UInt8)
\N Nullable(Nothing)
1 LowCardinality(Nullable(UInt8))
2 LowCardinality(Nullable(UInt8))
1 LowCardinality(Nullable(UInt8))

View File

@ -0,0 +1,13 @@
SELECT coalesce(toNullable(1), toNullable(2)) as x, toTypeName(x);
SELECT coalesce(NULL, toNullable(2)) as x, toTypeName(x);
SELECT coalesce(toNullable(1), NULL) as x, toTypeName(x);
SELECT coalesce(NULL, NULL) as x, toTypeName(x);
SELECT coalesce(toNullable(materialize(1)), toNullable(materialize(2))) as x, toTypeName(x);
SELECT coalesce(NULL, toNullable(materialize(2))) as x, toTypeName(x);
SELECT coalesce(toNullable(materialize(1)), NULL) as x, toTypeName(x);
SELECT coalesce(materialize(NULL), materialize(NULL)) as x, toTypeName(x);
SELECT coalesce(toLowCardinality(toNullable(1)), toLowCardinality(toNullable(2))) as x, toTypeName(x);
SELECT coalesce(NULL, toLowCardinality(toNullable(2))) as x, toTypeName(x);
SELECT coalesce(toLowCardinality(toNullable(1)), NULL) as x, toTypeName(x);