Skip to content

Commit 1b43c58

Browse files
authored
Merge pull request ClickHouse#62087 from ClickHouse/checkmate
Avoid crashing on column type mismatch in a few dozen places
2 parents 40b5aaa + 4b9819a commit 1b43c58

File tree

75 files changed

+266
-236
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+266
-236
lines changed

src/Columns/ColumnArray.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ ColumnPtr ColumnArray::replicateTuple(const Offsets & replicate_offsets) const
12831283

12841284
size_t ColumnArray::getNumberOfDimensions() const
12851285
{
1286-
const auto * nested_array = checkAndGetColumn<ColumnArray>(*data);
1286+
const auto * nested_array = checkAndGetColumn<ColumnArray>(&*data);
12871287
if (!nested_array)
12881288
return 1;
12891289
return 1 + nested_array->getNumberOfDimensions(); /// Every modern C++ compiler optimizes tail recursion.

src/Columns/ColumnLowCardinality.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ ColumnPtr ColumnLowCardinality::cloneWithDefaultOnNull() const
903903

904904
bool isColumnLowCardinalityNullable(const IColumn & column)
905905
{
906-
if (const auto * lc_column = checkAndGetColumn<ColumnLowCardinality>(column))
906+
if (const auto * lc_column = checkAndGetColumn<ColumnLowCardinality>(&column))
907907
return lc_column->nestedIsNullable();
908908
return false;
909909
}

src/Columns/ColumnUnique.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ size_t ColumnUnique<ColumnType>::uniqueInsertFrom(const IColumn & src, size_t n)
376376
if (is_nullable && src.isNullAt(n))
377377
return getNullValueIndex();
378378

379-
if (const auto * nullable = checkAndGetColumn<ColumnNullable>(src))
379+
if (const auto * nullable = checkAndGetColumn<ColumnNullable>(&src))
380380
return uniqueInsertFrom(nullable->getNestedColumn(), n);
381381

382382
auto ref = src.getDataAt(n);
@@ -569,7 +569,7 @@ MutableColumnPtr ColumnUnique<ColumnType>::uniqueInsertRangeImpl(
569569
return nullptr;
570570
};
571571

572-
if (const auto * nullable_column = checkAndGetColumn<ColumnNullable>(src))
572+
if (const auto * nullable_column = checkAndGetColumn<ColumnNullable>(&src))
573573
{
574574
src_column = typeid_cast<const ColumnType *>(&nullable_column->getNestedColumn());
575575
null_map = &nullable_column->getNullMapData();

src/Columns/FilterDescription.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ ConstantFilterDescription::ConstantFilterDescription(const IColumn & column)
3232

3333
if (!typeid_cast<const ColumnUInt8 *>(column_nested.get()))
3434
{
35-
const ColumnNullable * column_nested_nullable = checkAndGetColumn<ColumnNullable>(*column_nested);
35+
const ColumnNullable * column_nested_nullable = checkAndGetColumn<ColumnNullable>(&*column_nested);
3636
if (!column_nested_nullable || !typeid_cast<const ColumnUInt8 *>(&column_nested_nullable->getNestedColumn()))
3737
{
3838
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER,
@@ -66,7 +66,7 @@ FilterDescription::FilterDescription(const IColumn & column_)
6666
return;
6767
}
6868

69-
if (const auto * nullable_column = checkAndGetColumn<ColumnNullable>(column))
69+
if (const auto * nullable_column = checkAndGetColumn<ColumnNullable>(&column))
7070
{
7171
ColumnPtr nested_column = nullable_column->getNestedColumnPtr();
7272
MutableColumnPtr mutable_holder = IColumn::mutate(std::move(nested_column));

src/Columns/IColumn.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,12 +640,16 @@ template <>
640640
struct IsMutableColumns<> { static const bool value = true; };
641641

642642

643+
/// Throws LOGICAL_ERROR if the type doesn't match.
643644
template <typename Type>
644-
const Type * checkAndGetColumn(const IColumn & column)
645+
const Type & checkAndGetColumn(const IColumn & column)
645646
{
646-
return typeid_cast<const Type *>(&column);
647+
return typeid_cast<const Type &>(column);
647648
}
648649

650+
/// Returns nullptr if the type doesn't match.
651+
/// If you're going to dereference the returned pointer without checking for null, use the
652+
/// `const IColumn &` overload above instead.
649653
template <typename Type>
650654
const Type * checkAndGetColumn(const IColumn * column)
651655
{

src/Columns/MaskOperations.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,10 @@ static MaskInfo extractMaskImpl(
205205
auto column = col->convertToFullColumnIfLowCardinality();
206206

207207
/// Special implementation for Null and Const columns.
208-
if (column->onlyNull() || checkAndGetColumn<ColumnConst>(*column))
208+
if (column->onlyNull() || checkAndGetColumn<ColumnConst>(&*column))
209209
return extractMaskFromConstOrNull<inverted>(mask, column, null_value, nulls);
210210

211-
if (const auto * nullable_column = checkAndGetColumn<ColumnNullable>(*column))
211+
if (const auto * nullable_column = checkAndGetColumn<ColumnNullable>(&*column))
212212
{
213213
const PaddedPODArray<UInt8> & null_map = nullable_column->getNullMapData();
214214
return extractMaskImpl<inverted>(mask, nullable_column->getNestedColumnPtr(), null_value, &null_map, nulls);

src/Common/ColumnsHashing.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ struct HashMethodOneNumber
4444
{
4545
if constexpr (nullable)
4646
{
47-
const auto * null_column = checkAndGetColumn<ColumnNullable>(key_columns[0]);
48-
vec = null_column->getNestedColumnPtr()->getRawData().data();
47+
const auto & null_column = checkAndGetColumn<ColumnNullable>(*key_columns[0]);
48+
vec = null_column.getNestedColumnPtr()->getRawData().data();
4949
}
5050
else
5151
{
@@ -57,8 +57,8 @@ struct HashMethodOneNumber
5757
{
5858
if constexpr (nullable)
5959
{
60-
const auto * null_column = checkAndGetColumn<ColumnNullable>(column);
61-
vec = null_column->getNestedColumnPtr()->getRawData().data();
60+
const auto & null_column = checkAndGetColumn<ColumnNullable>(*column);
61+
vec = null_column.getNestedColumnPtr()->getRawData().data();
6262
}
6363
else
6464
{
@@ -105,7 +105,7 @@ struct HashMethodString
105105
const IColumn * column;
106106
if constexpr (nullable)
107107
{
108-
column = checkAndGetColumn<ColumnNullable>(key_columns[0])->getNestedColumnPtr().get();
108+
column = checkAndGetColumn<ColumnNullable>(*key_columns[0]).getNestedColumnPtr().get();
109109
}
110110
else
111111
{
@@ -153,7 +153,7 @@ struct HashMethodFixedString
153153
const IColumn * column;
154154
if constexpr (nullable)
155155
{
156-
column = checkAndGetColumn<ColumnNullable>(key_columns[0])->getNestedColumnPtr().get();
156+
column = checkAndGetColumn<ColumnNullable>(*key_columns[0]).getNestedColumnPtr().get();
157157
}
158158
else
159159
{

src/Common/ColumnsHashingImpl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ class HashMethodBase
305305
}
306306

307307
if constexpr (nullable)
308-
null_map = &checkAndGetColumn<ColumnNullable>(column)->getNullMapColumn();
308+
null_map = &checkAndGetColumn<ColumnNullable>(*column).getNullMapColumn();
309309
}
310310

311311
template <typename Data, typename KeyHolder>

src/Core/DecimalComparison.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,11 @@ class DecimalComparison
170170

171171
if (c0_is_const && c1_is_const)
172172
{
173-
const ColumnConst * c0_const = checkAndGetColumnConst<ColVecA>(c0.get());
174-
const ColumnConst * c1_const = checkAndGetColumnConst<ColVecB>(c1.get());
173+
const ColumnConst & c0_const = checkAndGetColumnConst<ColVecA>(*c0);
174+
const ColumnConst & c1_const = checkAndGetColumnConst<ColVecB>(*c1);
175175

176-
A a = c0_const->template getValue<A>();
177-
B b = c1_const->template getValue<B>();
176+
A a = c0_const.template getValue<A>();
177+
B b = c1_const.template getValue<B>();
178178
UInt8 res = apply<scale_left, scale_right>(a, b, scale);
179179
return DataTypeUInt8().createColumnConst(c0->size(), toField(res));
180180
}
@@ -184,17 +184,17 @@ class DecimalComparison
184184

185185
if (c0_is_const)
186186
{
187-
const ColumnConst * c0_const = checkAndGetColumnConst<ColVecA>(c0.get());
188-
A a = c0_const->template getValue<A>();
187+
const ColumnConst & c0_const = checkAndGetColumnConst<ColVecA>(*c0);
188+
A a = c0_const.template getValue<A>();
189189
if (const ColVecB * c1_vec = checkAndGetColumn<ColVecB>(c1.get()))
190190
constantVector<scale_left, scale_right>(a, c1_vec->getData(), vec_res, scale);
191191
else
192192
throw Exception(ErrorCodes::LOGICAL_ERROR, "Wrong column in Decimal comparison");
193193
}
194194
else if (c1_is_const)
195195
{
196-
const ColumnConst * c1_const = checkAndGetColumnConst<ColVecB>(c1.get());
197-
B b = c1_const->template getValue<B>();
196+
const ColumnConst & c1_const = checkAndGetColumnConst<ColVecB>(*c1);
197+
B b = c1_const.template getValue<B>();
198198
if (const ColVecA * c0_vec = checkAndGetColumn<ColVecA>(c0.get()))
199199
vectorConstant<scale_left, scale_right>(c0_vec->getData(), b, vec_res, scale);
200200
else

src/DataTypes/ObjectUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ size_t getNumberOfDimensions(const IDataType & type)
4747

4848
size_t getNumberOfDimensions(const IColumn & column)
4949
{
50-
if (const auto * column_array = checkAndGetColumn<ColumnArray>(column))
50+
if (const auto * column_array = checkAndGetColumn<ColumnArray>(&column))
5151
return column_array->getNumberOfDimensions();
5252
return 0;
5353
}

0 commit comments

Comments
 (0)