diff --git a/dbms/include/DB/DataTypes/DataTypeNull.h b/dbms/include/DB/DataTypes/DataTypeNull.h index 52bba507715..e811781a026 100644 --- a/dbms/include/DB/DataTypes/DataTypeNull.h +++ b/dbms/include/DB/DataTypes/DataTypeNull.h @@ -14,8 +14,6 @@ public: public: std::string getName() const override; bool isNull() const override; - bool isNumeric() const override; - bool behavesAsNumber() const override; DataTypePtr clone() const override; void serializeBinary(const IColumn & column, WriteBuffer & ostr, size_t offset = 0, size_t limit = 0) const override; void deserializeBinary(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const override; diff --git a/dbms/include/DB/IO/WriteHelpers.h b/dbms/include/DB/IO/WriteHelpers.h index ec1376c313f..47eff1928d2 100644 --- a/dbms/include/DB/IO/WriteHelpers.h +++ b/dbms/include/DB/IO/WriteHelpers.h @@ -804,4 +804,12 @@ inline String toString(const T & x) return res; } +/// Write a specified number of times a given value into a write buffer. +template +inline void writeBinary(const T & x, size_t count, WriteBuffer & buf) +{ + for (size_t i = 0; i < count; ++i) + writeBinary(x, buf); +} + } diff --git a/dbms/src/DataTypes/DataTypeNull.cpp b/dbms/src/DataTypes/DataTypeNull.cpp index b1d81ceec8b..b196ec566d8 100644 --- a/dbms/src/DataTypes/DataTypeNull.cpp +++ b/dbms/src/DataTypes/DataTypeNull.cpp @@ -26,16 +26,6 @@ bool DataTypeNull::isNull() const return true; } -bool DataTypeNull::isNumeric() const -{ - return true; -} - -bool DataTypeNull::behavesAsNumber() const -{ - return true; -} - DataTypePtr DataTypeNull::clone() const { return std::make_shared(); @@ -45,28 +35,19 @@ void DataTypeNull::serializeBinary(const IColumn & column, WriteBuffer & ostr, s { size_t size = column.size(); - if ((limit == 0) || (offset + limit) > size) + if ((limit == 0) || ((offset + limit) > size)) limit = size - offset; - UInt8 x = 0 ; - for (size_t i = 0; i < limit; ++i) - ostr.write(reinterpret_cast(&x), sizeof(UInt8) * 1); + UInt8 x = 0; + writeBinary(x, limit, ostr); } void DataTypeNull::deserializeBinary(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const { - ColumnNull * col = typeid_cast(&column); - if (col == nullptr) - throw Exception{"Discrepancy between data type and column type", ErrorCodes::LOGICAL_ERROR}; + ColumnNull & null_col = static_cast(column); - ColumnNull & col_ref = *col; - - UInt8 x; - for (size_t i = 0; i < limit; ++i) - { - istr.readBig(reinterpret_cast(&x), sizeof(UInt8) * 1); - col_ref.insertDefault(); - } + istr.ignore(sizeof(UInt8) * limit); + null_col.insertRangeFrom(ColumnNull{0, Null()}, 0, limit); } void DataTypeNull::serializeBinary(const Field & field, WriteBuffer & ostr) const diff --git a/dbms/src/Functions/Conditional/ArgsInfo.cpp b/dbms/src/Functions/Conditional/ArgsInfo.cpp index 4e7a1707784..71a8b29753c 100644 --- a/dbms/src/Functions/Conditional/ArgsInfo.cpp +++ b/dbms/src/Functions/Conditional/ArgsInfo.cpp @@ -203,7 +203,7 @@ bool hasArithmeticBranches(const DataTypes & args) auto check = [&](size_t i) { - return args[i]->behavesAsNumber(); + return args[i]->behavesAsNumber() || args[i]->isNull(); }; for (size_t i = firstThen(); i < else_arg; i = nextThen(i))