Skip to content

Commit f79a402

Browse files
committed
Add sanity checks for function return types
1 parent dc057b6 commit f79a402

9 files changed

Lines changed: 28 additions & 0 deletions

File tree

src/Columns/ColumnFunction.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,13 @@ ColumnWithTypeAndName ColumnFunction::reduce() const
308308
ProfileEvents::increment(ProfileEvents::CompiledFunctionExecute);
309309

310310
res.column = function->execute(columns, res.type, elements_size);
311+
if (res.column->getDataType() != res.type->getColumnType())
312+
throw Exception(
313+
ErrorCodes::LOGICAL_ERROR,
314+
"Unexpected return type from {}. Expected {}. Got {}",
315+
function->getName(),
316+
res.type->getColumnType(),
317+
res.column->getDataType());
311318
if (recursively_convert_result_to_full_column_if_low_cardinality)
312319
{
313320
res.column = recursiveRemoveLowCardinality(res.column);

src/DataTypes/DataTypeDate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class DataTypeDate final : public DataTypeNumberBase<UInt16>
1212
static constexpr auto family_name = "Date";
1313

1414
TypeIndex getTypeId() const override { return TypeIndex::Date; }
15+
TypeIndex getColumnType() const override { return TypeIndex::UInt16; }
1516
const char * getFamilyName() const override { return family_name; }
1617

1718
bool canBeUsedAsVersion() const override { return true; }

src/DataTypes/DataTypeDate32.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class DataTypeDate32 final : public DataTypeNumberBase<Int32>
1212
static constexpr auto family_name = "Date32";
1313

1414
TypeIndex getTypeId() const override { return TypeIndex::Date32; }
15+
TypeIndex getColumnType() const override { return TypeIndex::Int32; }
1516
const char * getFamilyName() const override { return family_name; }
1617

1718
Field getDefault() const override

src/DataTypes/DataTypeDateTime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class DataTypeDateTime final : public DataTypeNumberBase<UInt32>, public Timezon
4040
const char * getFamilyName() const override { return family_name; }
4141
String doGetName() const override;
4242
TypeIndex getTypeId() const override { return TypeIndex::DateTime; }
43+
TypeIndex getColumnType() const override { return TypeIndex::UInt32; }
4344

4445
bool canBeUsedAsVersion() const override { return true; }
4546
bool canBeInsideNullable() const override { return true; }

src/DataTypes/DataTypeEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class DataTypeEnum final : public IDataTypeEnum, public EnumValues<Type>
5454
const char * getFamilyName() const override;
5555

5656
TypeIndex getTypeId() const override { return type_id; }
57+
TypeIndex getColumnType() const override { return sizeof(FieldType) == 1 ? TypeIndex::Int8 : TypeIndex::Int16; }
5758

5859
FieldType readValue(ReadBuffer & istr) const
5960
{

src/DataTypes/DataTypeInterval.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class DataTypeInterval final : public DataTypeNumberBase<Int64>
2828
std::string doGetName() const override { return fmt::format("Interval{}", kind.toString()); }
2929
const char * getFamilyName() const override { return "Interval"; }
3030
TypeIndex getTypeId() const override { return TypeIndex::Interval; }
31+
TypeIndex getColumnType() const override { return TypeIndex::Int64; }
3132

3233
bool equals(const IDataType & rhs) const override;
3334

src/DataTypes/IDataType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ class IDataType : private boost::noncopyable, public std::enable_shared_from_thi
8686

8787
/// Data type id. It's used for runtime type checks.
8888
virtual TypeIndex getTypeId() const = 0;
89+
/// Storage type (e.g. Int64 for Interval)
90+
virtual TypeIndex getColumnType() const { return getTypeId(); }
8991

9092
bool hasSubcolumn(std::string_view subcolumn_name) const;
9193

src/Interpreters/ActionsDAG.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,13 @@ const ActionsDAG::Node & ActionsDAG::addFunctionImpl(
282282
{
283283
size_t num_rows = arguments.empty() ? 0 : arguments.front().column->size();
284284
column = node.function->execute(arguments, node.result_type, num_rows, true);
285+
if (column->getDataType() != node.result_type->getColumnType())
286+
throw Exception(
287+
ErrorCodes::LOGICAL_ERROR,
288+
"Unexpected return type from {}. Expected {}. Got {}",
289+
node.function->getName(),
290+
node.result_type->getColumnType(),
291+
column->getDataType());
285292
}
286293
else
287294
{

src/Interpreters/ExpressionActions.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,13 @@ static void executeAction(const ExpressionActions::Action & action, ExecutionCon
611611
ProfileEvents::increment(ProfileEvents::CompiledFunctionExecute);
612612

613613
res_column.column = action.node->function->execute(arguments, res_column.type, num_rows, dry_run);
614+
if (res_column.column->getDataType() != res_column.type->getColumnType())
615+
throw Exception(
616+
ErrorCodes::LOGICAL_ERROR,
617+
"Unexpected return type from {}. Expected {}. Got {}",
618+
action.node->function->getName(),
619+
res_column.type->getColumnType(),
620+
res_column.column->getDataType());
614621
}
615622
break;
616623
}

0 commit comments

Comments
 (0)