#include #include #include #include #include #include #include #include #include #include #include #include namespace DB { template void DataTypeNumberBase::serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings &) const { writeText(assert_cast &>(column).getData()[row_num], ostr); } template void DataTypeNumberBase::deserializeText(IColumn & column, ReadBuffer & istr, const FormatSettings &) const { T x; if constexpr (is_integral_v && is_arithmetic_v) readIntTextUnsafe(x, istr); else readText(x, istr); assert_cast &>(column).getData().push_back(x); } template static inline void writeDenormalNumber(T x, WriteBuffer & ostr) { if constexpr (std::is_floating_point_v) { if (std::signbit(x)) { if (isNaN(x)) writeCString("-nan", ostr); else writeCString("-inf", ostr); } else { if (isNaN(x)) writeCString("nan", ostr); else writeCString("inf", ostr); } } else { /// This function is not called for non floating point numbers. (void)x; } } template void DataTypeNumberBase::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const { auto x = assert_cast &>(column).getData()[row_num]; bool is_finite = isFinite(x); const bool need_quote = (is_integral_v && (sizeof(T) == 8) && settings.json.quote_64bit_integers) || (settings.json.quote_denormals && !is_finite); if (need_quote) writeChar('"', ostr); if (is_finite) writeText(x, ostr); else if (!settings.json.quote_denormals) writeCString("null", ostr); else writeDenormalNumber(x, ostr); if (need_quote) writeChar('"', ostr); } template void DataTypeNumberBase::deserializeTextJSON(IColumn & column, ReadBuffer & istr, const FormatSettings &) const { bool has_quote = false; if (!istr.eof() && *istr.position() == '"') /// We understand the number both in quotes and without. { has_quote = true; ++istr.position(); } FieldType x; /// null if (!has_quote && !istr.eof() && *istr.position() == 'n') { ++istr.position(); assertString("ull", istr); x = NaNOrZero(); } else { static constexpr bool is_uint8 = std::is_same_v; static constexpr bool is_int8 = std::is_same_v; if (is_uint8 || is_int8) { // extra conditions to parse true/false strings into 1/0 if (istr.eof()) throwReadAfterEOF(); if (*istr.position() == 't' || *istr.position() == 'f') { bool tmp = false; readBoolTextWord(tmp, istr); x = tmp; } else readText(x, istr); } else { readText(x, istr); } if (has_quote) assertChar('"', istr); } assert_cast &>(column).getData().push_back(x); } template void DataTypeNumberBase::deserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings &) const { FieldType x; readCSV(x, istr); assert_cast &>(column).getData().push_back(x); } template Field DataTypeNumberBase::getDefault() const { return NearestFieldType(); } template void DataTypeNumberBase::serializeBinary(const Field & field, WriteBuffer & ostr) const { /// ColumnVector::ValueType is a narrower type. For example, UInt8, when the Field type is UInt64 typename ColumnVector::ValueType x = get>(field); writeBinary(x, ostr); } template void DataTypeNumberBase::deserializeBinary(Field & field, ReadBuffer & istr) const { typename ColumnVector::ValueType x; readBinary(x, istr); field = NearestFieldType(x); } template void DataTypeNumberBase::serializeBinary(const IColumn & column, size_t row_num, WriteBuffer & ostr) const { writeBinary(assert_cast &>(column).getData()[row_num], ostr); } template void DataTypeNumberBase::deserializeBinary(IColumn & column, ReadBuffer & istr) const { typename ColumnVector::ValueType x; readBinary(x, istr); assert_cast &>(column).getData().push_back(x); } template void DataTypeNumberBase::serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const { const typename ColumnVector::Container & x = typeid_cast &>(column).getData(); size_t size = x.size(); if (limit == 0 || offset + limit > size) limit = size - offset; if (limit) ostr.write(reinterpret_cast(&x[offset]), sizeof(typename ColumnVector::ValueType) * limit); } template void DataTypeNumberBase::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double /*avg_value_size_hint*/) const { typename ColumnVector::Container & x = typeid_cast &>(column).getData(); size_t initial_size = x.size(); x.resize(initial_size + limit); size_t size = istr.readBig(reinterpret_cast(&x[initial_size]), sizeof(typename ColumnVector::ValueType) * limit); x.resize(initial_size + size / sizeof(typename ColumnVector::ValueType)); } template void DataTypeNumberBase::serializeProtobuf(const IColumn & column, size_t row_num, ProtobufWriter & protobuf, size_t & value_index) const { if (value_index) return; value_index = static_cast(protobuf.writeNumber(assert_cast &>(column).getData()[row_num])); } template void DataTypeNumberBase::deserializeProtobuf(IColumn & column, ProtobufReader & protobuf, bool allow_add_row, bool & row_added) const { row_added = false; T value; if (!protobuf.readNumber(value)) return; auto & container = typeid_cast &>(column).getData(); if (allow_add_row) { container.emplace_back(value); row_added = true; } else container.back() = value; } template MutableColumnPtr DataTypeNumberBase::createColumn() const { return ColumnVector::create(); } template bool DataTypeNumberBase::isValueRepresentedByInteger() const { return is_integral_v; } template bool DataTypeNumberBase::isValueRepresentedByUnsignedInteger() const { return is_integral_v && is_unsigned_v; } /// Explicit template instantiations - to avoid code bloat in headers. template class DataTypeNumberBase; template class DataTypeNumberBase; template class DataTypeNumberBase; template class DataTypeNumberBase; template class DataTypeNumberBase; // used only in UUID template class DataTypeNumberBase; template class DataTypeNumberBase; template class DataTypeNumberBase; template class DataTypeNumberBase; template class DataTypeNumberBase; template class DataTypeNumberBase; }