#include "enum.h" #include "utils.h" #include <util/string/printf.h> namespace NClickHouse { template <typename T> TColumnEnum<T>::TColumnEnum(TTypeRef type) : TColumn(type) { } template <typename T> TColumnEnum<T>::TColumnEnum(TTypeRef type, const TVector<T>& data) : TColumn(type) , Data_(data) { } template <> TIntrusivePtr<TColumnEnum<i8>> TColumnEnum<i8>::Create(const TVector<TEnumItem>& enumItems) { TTypeRef type = TType::CreateEnum8(enumItems); return new TColumnEnum<i8>(type); } template <> TIntrusivePtr<TColumnEnum<i8>> TColumnEnum<i8>::Create( const TVector<TEnumItem>& enumItems, const TVector<i8>& values, bool checkValues) { TTypeRef type = TType::CreateEnum8(enumItems); if (checkValues) { for (i8 value : values) { Y_ENSURE(type->HasEnumValue(value), Sprintf("Enum type doesn't have value %d", value)); } } return new TColumnEnum<i8>(type, values); } template <> TIntrusivePtr<TColumnEnum<i8>> TColumnEnum<i8>::Create( const TVector<TEnumItem>& enumItems, const TVector<TString>& names) { TTypeRef type = TType::CreateEnum8(enumItems); TVector<i8> values; values.reserve(names.size()); for (const TString& name : names) { values.push_back(type->GetEnumValue(name)); } return new TColumnEnum<i8>(type, values); } template <> TIntrusivePtr<TColumnEnum<i16>> TColumnEnum<i16>::Create(const TVector<TEnumItem>& enumItems) { TTypeRef type = TType::CreateEnum16(enumItems); return new TColumnEnum<i16>(type); } template <> TIntrusivePtr<TColumnEnum<i16>> TColumnEnum<i16>::Create( const TVector<TEnumItem>& enumItems, const TVector<i16>& values, bool checkValues) { TTypeRef type = TType::CreateEnum16(enumItems); if (checkValues) { for (i16 value : values) { Y_ENSURE(type->HasEnumValue(value), Sprintf("Enum type doesn't have value %d", value)); } } return new TColumnEnum<i16>(type, values); } template <> TIntrusivePtr<TColumnEnum<i16>> TColumnEnum<i16>::Create( const TVector<TEnumItem>& enumItems, const TVector<TString>& names) { TTypeRef type = TType::CreateEnum16(enumItems); TVector<i16> values; values.reserve(names.size()); for (const TString& name : names) { values.push_back(type->GetEnumValue(name)); } return new TColumnEnum<i16>(type, values); } template <typename T> void TColumnEnum<T>::Append(const T& value, bool checkValue) { if (checkValue) { Y_ENSURE(Type_->HasEnumValue(value), Sprintf("Enum type doesn't have value %d", value)); } Data_.push_back(value); } template <typename T> void TColumnEnum<T>::Append(const TString& name) { Data_.push_back(Type_->GetEnumValue(name)); } template <typename T> const T& TColumnEnum<T>::At(size_t n) const { return Data_.at(n); } template <typename T> const TString& TColumnEnum<T>::NameAt(size_t n) const { return Type_->GetEnumName(Data_.at(n)); } template <typename T> const T& TColumnEnum<T>::operator[](size_t n) const { return Data_[n]; } template <typename T> void TColumnEnum<T>::SetAt(size_t n, const T& value, bool checkValue) { if (checkValue) { Y_ENSURE(Type_->HasEnumValue(value), Sprintf("Enum type doesn't have value %d", value)); } Data_.at(n) = value; } template <typename T> void TColumnEnum<T>::SetNameAt(size_t n, const TString& name) { Data_.at(n) = Type_->GetEnumValue(name); } template <typename T> void TColumnEnum<T>::Append(TColumnRef column) { if (auto col = column->As<TColumnEnum<T>>()) { Data_.insert(Data_.end(), col->Data_.begin(), col->Data_.end()); } } template <typename T> bool TColumnEnum<T>::Load(TCodedInputStream* input, size_t rows) { Data_.resize(rows); return input->ReadRaw(Data_.data(), Data_.size() * sizeof(T)); } template <typename T> void TColumnEnum<T>::Save(TCodedOutputStream* output) { output->WriteRaw(Data_.data(), Data_.size() * sizeof(T)); } template <typename T> size_t TColumnEnum<T>::Size() const { return Data_.size(); } template <typename T> TColumnRef TColumnEnum<T>::Slice(size_t begin, size_t len) { return new TColumnEnum<T>(Type_, SliceVector(Data_, begin, len)); } template class TColumnEnum<i8>; template class TColumnEnum<i16>; }