diff options
author | galaxycrab <UgnineSirdis@ydb.tech> | 2023-11-23 11:26:33 +0300 |
---|---|---|
committer | galaxycrab <UgnineSirdis@ydb.tech> | 2023-11-23 12:01:57 +0300 |
commit | 44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300 (patch) | |
tree | cb4d75cd1c6dbc3da0ed927337fd8d1b6ed9da84 /library/cpp/clickhouse/client/columns | |
parent | 0e69bf615395fdd48ecee032faaec81bc468b0b8 (diff) | |
download | ydb-44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300.tar.gz |
YQ Connector:test INNER JOIN
Diffstat (limited to 'library/cpp/clickhouse/client/columns')
24 files changed, 1656 insertions, 0 deletions
diff --git a/library/cpp/clickhouse/client/columns/CMakeLists.darwin-arm64.txt b/library/cpp/clickhouse/client/columns/CMakeLists.darwin-arm64.txt new file mode 100644 index 0000000000..306332e5fa --- /dev/null +++ b/library/cpp/clickhouse/client/columns/CMakeLists.darwin-arm64.txt @@ -0,0 +1,26 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_library(clickhouse-client-columns) +target_link_libraries(clickhouse-client-columns PUBLIC + contrib-libs-cxxsupp + yutil + clickhouse-client-base + clickhouse-client-types +) +target_sources(clickhouse-client-columns PRIVATE + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/array.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/date.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/enum.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/factory.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/nullable.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/numeric.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/string.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/tuple.cpp +) diff --git a/library/cpp/clickhouse/client/columns/CMakeLists.darwin-x86_64.txt b/library/cpp/clickhouse/client/columns/CMakeLists.darwin-x86_64.txt new file mode 100644 index 0000000000..306332e5fa --- /dev/null +++ b/library/cpp/clickhouse/client/columns/CMakeLists.darwin-x86_64.txt @@ -0,0 +1,26 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_library(clickhouse-client-columns) +target_link_libraries(clickhouse-client-columns PUBLIC + contrib-libs-cxxsupp + yutil + clickhouse-client-base + clickhouse-client-types +) +target_sources(clickhouse-client-columns PRIVATE + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/array.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/date.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/enum.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/factory.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/nullable.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/numeric.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/string.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/tuple.cpp +) diff --git a/library/cpp/clickhouse/client/columns/CMakeLists.linux-aarch64.txt b/library/cpp/clickhouse/client/columns/CMakeLists.linux-aarch64.txt new file mode 100644 index 0000000000..90add55098 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/CMakeLists.linux-aarch64.txt @@ -0,0 +1,27 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_library(clickhouse-client-columns) +target_link_libraries(clickhouse-client-columns PUBLIC + contrib-libs-linux-headers + contrib-libs-cxxsupp + yutil + clickhouse-client-base + clickhouse-client-types +) +target_sources(clickhouse-client-columns PRIVATE + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/array.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/date.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/enum.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/factory.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/nullable.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/numeric.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/string.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/tuple.cpp +) diff --git a/library/cpp/clickhouse/client/columns/CMakeLists.linux-x86_64.txt b/library/cpp/clickhouse/client/columns/CMakeLists.linux-x86_64.txt new file mode 100644 index 0000000000..90add55098 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/CMakeLists.linux-x86_64.txt @@ -0,0 +1,27 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_library(clickhouse-client-columns) +target_link_libraries(clickhouse-client-columns PUBLIC + contrib-libs-linux-headers + contrib-libs-cxxsupp + yutil + clickhouse-client-base + clickhouse-client-types +) +target_sources(clickhouse-client-columns PRIVATE + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/array.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/date.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/enum.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/factory.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/nullable.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/numeric.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/string.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/clickhouse/client/columns/tuple.cpp +) diff --git a/library/cpp/clickhouse/client/columns/CMakeLists.txt b/library/cpp/clickhouse/client/columns/CMakeLists.txt new file mode 100644 index 0000000000..1beba2829f --- /dev/null +++ b/library/cpp/clickhouse/client/columns/CMakeLists.txt @@ -0,0 +1,17 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA) + include(CMakeLists.linux-aarch64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + include(CMakeLists.darwin-x86_64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + include(CMakeLists.darwin-arm64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA) + include(CMakeLists.linux-x86_64.txt) +endif() diff --git a/library/cpp/clickhouse/client/columns/array.cpp b/library/cpp/clickhouse/client/columns/array.cpp new file mode 100644 index 0000000000..8a83c36f72 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/array.cpp @@ -0,0 +1,87 @@ +#include "array.h" + +#include <util/generic/yexception.h> + +namespace NClickHouse { + TColumnArray::TColumnArray(TColumnRef data) + : TColumn(TType::CreateArray(data->Type())) + , Data_(data) + , Offsets_(TColumnUInt64::Create()) + { + } + + TColumnArray::TColumnArray(TColumnRef data, TVector<ui64>&& offsets) + : TColumn(TType::CreateArray(data->Type())) + , Data_(data) + , Offsets_(TColumnUInt64::Create(std::move(offsets))) + { + } + + TIntrusivePtr<TColumnArray> TColumnArray::Create(TColumnRef data) { + return new TColumnArray(data); + } + + TIntrusivePtr<TColumnArray> TColumnArray::Create(TColumnRef data, TVector<ui64>&& offsets) { + return new TColumnArray(data, std::move(offsets)); + } + + void TColumnArray::AppendAsColumn(TColumnRef array) { + if (!Data_->Type()->IsEqual(array->Type())) { + ythrow yexception() + << "can't append column of type " << array->Type()->GetName() << " " + << "to column type " << Data_->Type()->GetName(); + } + + if (Offsets_->Size() == 0) { + Offsets_->Append(array->Size()); + } else { + Offsets_->Append((*Offsets_)[Offsets_->Size() - 1] + array->Size()); + } + + Data_->Append(array); + } + + void TColumnArray::Append(TColumnRef column) { + if (auto col = column->As<TColumnArray>()) { + if (!col->Data_->Type()->IsEqual(Data_->Type())) { + return; + } + + for (size_t i = 0; i < col->Size(); ++i) { + AppendAsColumn(col->GetAsColumn(i)); + } + } + } + + TColumnRef TColumnArray::GetAsColumn(size_t n) const { + return Data_->Slice(GetOffset(n), GetSize(n)); + } + + bool TColumnArray::Load(TCodedInputStream* input, size_t rows) { + if (!Offsets_->Load(input, rows)) { + return false; + } + if (!Data_->Load(input, (*Offsets_)[rows - 1])) { + return false; + } + return true; + } + + void TColumnArray::Save(TCodedOutputStream* output) { + Offsets_->Save(output); + Data_->Save(output); + } + + size_t TColumnArray::Size() const { + return Offsets_->Size(); + } + + size_t TColumnArray::GetOffset(size_t n) const { + return (n == 0) ? 0 : (*Offsets_)[n - 1]; + } + + size_t TColumnArray::GetSize(size_t n) const { + return (n == 0) ? (*Offsets_)[n] : ((*Offsets_)[n] - (*Offsets_)[n - 1]); + } + +} diff --git a/library/cpp/clickhouse/client/columns/array.h b/library/cpp/clickhouse/client/columns/array.h new file mode 100644 index 0000000000..1a5e7f429a --- /dev/null +++ b/library/cpp/clickhouse/client/columns/array.h @@ -0,0 +1,55 @@ +#pragma once + +#include "numeric.h" + +namespace NClickHouse { + /** + * Represents column of Array(T). + */ + class TColumnArray: public TColumn { + public: + static TIntrusivePtr<TColumnArray> Create(TColumnRef data); + + static TIntrusivePtr<TColumnArray> Create(TColumnRef data, TVector<ui64>&& offsets); + + /// Converts input column to array and appends + /// as one row to the current column. + void AppendAsColumn(TColumnRef array); + + /// Convets array at pos n to column. + /// Type of element of result column same as type of array element. + TColumnRef GetAsColumn(size_t n) const; + + public: + /// Appends content of given column to the end of current one. + void Append(TColumnRef) override; + + /// Loads column data from input stream. + bool Load(TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + TColumnRef Slice(size_t, size_t) override { + return TColumnRef(); + } + + private: + TColumnArray(TColumnRef data); + + TColumnArray(TColumnRef data, TVector<ui64>&& offsets); + + size_t GetOffset(size_t n) const; + + size_t GetSize(size_t n) const; + + private: + TColumnRef Data_; + TIntrusivePtr<TColumnUInt64> Offsets_; + }; + +} diff --git a/library/cpp/clickhouse/client/columns/column.h b/library/cpp/clickhouse/client/columns/column.h new file mode 100644 index 0000000000..d858338443 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/column.h @@ -0,0 +1,60 @@ +#pragma once + +#include <library/cpp/clickhouse/client/base/coded.h> +#include <library/cpp/clickhouse/client/types/types.h> + +#include <util/generic/ptr.h> + +namespace NClickHouse { + using TColumnRef = TIntrusivePtr<class TColumn>; + + /** + * An abstract base of all columns classes. + */ + class TColumn: public TAtomicRefCount<TColumn> { + public: + virtual ~TColumn() { + } + + /// Downcast pointer to the specific culumn's subtype. + template <typename T> + inline TIntrusivePtr<T> As() { + return TIntrusivePtr<T>(dynamic_cast<T*>(this)); + } + + /// Downcast pointer to the specific culumn's subtype. + template <typename T> + inline TIntrusivePtr<const T> As() const { + return TIntrusivePtr<const T>(dynamic_cast<const T*>(this)); + } + + /// Get type object of the column. + inline TTypeRef Type() const { + return Type_; + } + + /// Appends content of given column to the end of current one. + virtual void Append(TColumnRef column) = 0; + + /// Loads column data from input stream. + virtual bool Load(TCodedInputStream* input, size_t rows) = 0; + + /// Saves column data to output stream. + virtual void Save(TCodedOutputStream* output) = 0; + + /// Returns count of rows in the column. + virtual size_t Size() const = 0; + + /// Makes slice of the current column. + virtual TColumnRef Slice(size_t begin, size_t len) = 0; + + protected: + explicit inline TColumn(TTypeRef type) + : Type_(type) + { + } + + TTypeRef Type_; + }; + +} diff --git a/library/cpp/clickhouse/client/columns/date.cpp b/library/cpp/clickhouse/client/columns/date.cpp new file mode 100644 index 0000000000..242511a7eb --- /dev/null +++ b/library/cpp/clickhouse/client/columns/date.cpp @@ -0,0 +1,126 @@ +#include "date.h" + +namespace NClickHouse { + TIntrusivePtr<TColumnDate> TColumnDate::Create() { + return new TColumnDate(); + } + + TIntrusivePtr<TColumnDate> TColumnDate::Create(const TVector<TInstant>& data) { + return new TColumnDate(data); + } + + TColumnDate::TColumnDate() + : TColumn(TType::CreateDate()) + , Data_(TColumnUInt16::Create()) + { + } + + TColumnDate::TColumnDate(const TVector<TInstant>& data) + : TColumnDate() + { + for (const auto& value : data) { + Append(value); + } + } + + void TColumnDate::Append(const TInstant& value) { + Data_->Append(static_cast<ui16>(value.Days())); + } + + std::time_t TColumnDate::At(size_t n) const { + return Data_->At(n) * 86400; + } + + void TColumnDate::SetAt(size_t n, const TInstant& value) { + Data_->SetAt(n, static_cast<ui16>(value.Days())); + } + + void TColumnDate::Append(TColumnRef column) { + if (auto col = column->As<TColumnDate>()) { + Data_->Append(col->Data_); + } + } + + bool TColumnDate::Load(TCodedInputStream* input, size_t rows) { + return Data_->Load(input, rows); + } + + void TColumnDate::Save(TCodedOutputStream* output) { + Data_->Save(output); + } + + size_t TColumnDate::Size() const { + return Data_->Size(); + } + + TColumnRef TColumnDate::Slice(size_t begin, size_t len) { + auto col = Data_->Slice(begin, len)->As<TColumnUInt16>(); + auto result = TColumnDate::Create(); + + result->Data_->Append(col); + + return result; + } + + TColumnDateTime::TColumnDateTime() + : TColumn(TType::CreateDateTime()) + , Data_(TColumnUInt32::Create()) + { + } + + TColumnDateTime::TColumnDateTime(const TVector<TInstant>& data) + : TColumnDateTime() + { + for (const auto& value : data) { + Append(value); + } + } + + TIntrusivePtr<TColumnDateTime> TColumnDateTime::Create() { + return new TColumnDateTime(); + } + + TIntrusivePtr<TColumnDateTime> TColumnDateTime::Create(const TVector<TInstant>& data) { + return new TColumnDateTime(data); + } + + void TColumnDateTime::Append(const TInstant& value) { + Data_->Append(static_cast<ui32>(value.Seconds())); + } + + std::time_t TColumnDateTime::At(size_t n) const { + return Data_->At(n); + } + + void TColumnDateTime::SetAt(size_t n, const TInstant& value) { + Data_->SetAt(n, static_cast<ui32>(value.Seconds())); + } + + void TColumnDateTime::Append(TColumnRef column) { + if (auto col = column->As<TColumnDateTime>()) { + Data_->Append(col->Data_); + } + } + + bool TColumnDateTime::Load(TCodedInputStream* input, size_t rows) { + return Data_->Load(input, rows); + } + + void TColumnDateTime::Save(TCodedOutputStream* output) { + Data_->Save(output); + } + + size_t TColumnDateTime::Size() const { + return Data_->Size(); + } + + TColumnRef TColumnDateTime::Slice(size_t begin, size_t len) { + auto col = Data_->Slice(begin, len)->As<TColumnUInt32>(); + auto result = TColumnDateTime::Create(); + + result->Data_->Append(col); + + return result; + } + +} diff --git a/library/cpp/clickhouse/client/columns/date.h b/library/cpp/clickhouse/client/columns/date.h new file mode 100644 index 0000000000..003d3a0707 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/date.h @@ -0,0 +1,84 @@ +#pragma once + +#include "numeric.h" + +#include <util/datetime/base.h> + +namespace NClickHouse { + /** */ + class TColumnDate: public TColumn { + public: + static TIntrusivePtr<TColumnDate> Create(); + static TIntrusivePtr<TColumnDate> Create(const TVector<TInstant>& data); + + /// Appends one element to the end of column. + void Append(const TInstant& value); + + /// Returns element at given row number. + std::time_t At(size_t n) const; + + /// Set element at given row number. + void SetAt(size_t n, const TInstant& value); + + public: + /// Appends content of given column to the end of current one. + void Append(TColumnRef column) override; + + /// Loads column data from input stream. + bool Load(TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + TColumnRef Slice(size_t begin, size_t len) override; + + private: + TColumnDate(); + TColumnDate(const TVector<TInstant>& data); + + TIntrusivePtr<TColumnUInt16> Data_; + }; + + /** */ + class TColumnDateTime: public TColumn { + public: + static TIntrusivePtr<TColumnDateTime> Create(); + static TIntrusivePtr<TColumnDateTime> Create(const TVector<TInstant>& data); + + /// Appends one element to the end of column. + void Append(const TInstant& value); + + /// Returns element at given row number. + std::time_t At(size_t n) const; + + /// Set element at given row number. + void SetAt(size_t n, const TInstant& value); + + public: + /// Appends content of given column to the end of current one. + void Append(TColumnRef column) override; + + /// Loads column data from input stream. + bool Load(TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + TColumnRef Slice(size_t begin, size_t len) override; + + private: + TColumnDateTime(); + TColumnDateTime(const TVector<TInstant>& data); + + TIntrusivePtr<TColumnUInt32> Data_; + }; + +} diff --git a/library/cpp/clickhouse/client/columns/enum.cpp b/library/cpp/clickhouse/client/columns/enum.cpp new file mode 100644 index 0000000000..cd96903a8e --- /dev/null +++ b/library/cpp/clickhouse/client/columns/enum.cpp @@ -0,0 +1,157 @@ +#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>; + +} diff --git a/library/cpp/clickhouse/client/columns/enum.h b/library/cpp/clickhouse/client/columns/enum.h new file mode 100644 index 0000000000..90d773bd9f --- /dev/null +++ b/library/cpp/clickhouse/client/columns/enum.h @@ -0,0 +1,57 @@ +#pragma once + +#include "column.h" + +namespace NClickHouse { + template <typename T> + class TColumnEnum: public TColumn { + public: + static TIntrusivePtr<TColumnEnum<T>> Create(const TVector<TEnumItem>& enumItems); + static TIntrusivePtr<TColumnEnum<T>> Create( + const TVector<TEnumItem>& enumItems, + const TVector<T>& values, + bool checkValues = false); + static TIntrusivePtr<TColumnEnum<T>> Create(const TVector<TEnumItem>& enumItems, const TVector<TString>& names); + + /// Appends one element to the end of column. + void Append(const T& value, bool checkValue = false); + void Append(const TString& name); + + /// Returns element at given row number. + const T& At(size_t n) const; + const TString& NameAt(size_t n) const; + + /// Returns element at given row number. + const T& operator[](size_t n) const; + + /// Set element at given row number. + void SetAt(size_t n, const T& value, bool checkValue = false); + void SetNameAt(size_t n, const TString& name); + + public: + /// Appends content of given column to the end of current one. + void Append(TColumnRef column) override; + + /// Loads column data from input stream. + bool Load(TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + TColumnRef Slice(size_t begin, size_t len) override; + + private: + TColumnEnum(TTypeRef type); + TColumnEnum(TTypeRef type, const TVector<T>& data); + + TVector<T> Data_; + }; + + using TColumnEnum8 = TColumnEnum<i8>; + using TColumnEnum16 = TColumnEnum<i16>; + +} diff --git a/library/cpp/clickhouse/client/columns/factory.cpp b/library/cpp/clickhouse/client/columns/factory.cpp new file mode 100644 index 0000000000..a29ee70b8d --- /dev/null +++ b/library/cpp/clickhouse/client/columns/factory.cpp @@ -0,0 +1,118 @@ +#include "factory.h" + +#include "array.h" +#include "date.h" +#include "enum.h" +#include "nullable.h" +#include "numeric.h" +#include "string.h" +#include "tuple.h" + +#include <library/cpp/clickhouse/client/types/type_parser.h> + +namespace NClickHouse { + namespace { + TColumnRef CreateTerminalColumn(const TTypeAst& ast) { + if (ast.Name == "UInt8") + return TColumnUInt8::Create(); + if (ast.Name == "UInt16") + return TColumnUInt16::Create(); + if (ast.Name == "UInt32") + return TColumnUInt32::Create(); + if (ast.Name == "UInt64") + return TColumnUInt64::Create(); + + if (ast.Name == "Int8") + return TColumnInt8::Create(); + if (ast.Name == "Int16") + return TColumnInt16::Create(); + if (ast.Name == "Int32") + return TColumnInt32::Create(); + if (ast.Name == "Int64") + return TColumnInt64::Create(); + + if (ast.Name == "Float32") + return TColumnFloat32::Create(); + if (ast.Name == "Float64") + return TColumnFloat64::Create(); + + if (ast.Name == "String") + return TColumnString::Create(); + if (ast.Name == "FixedString") + return TColumnFixedString::Create(ast.Elements.front().Value); + + if (ast.Name == "DateTime") + return TColumnDateTime::Create(); + if (ast.Name == "Date") + return TColumnDate::Create(); + + return nullptr; + } + + TColumnRef CreateColumnFromAst(const TTypeAst& ast) { + switch (ast.Meta) { + case TTypeAst::Array: { + return TColumnArray::Create( + CreateColumnFromAst(ast.Elements.front())); + } + + case TTypeAst::Nullable: { + return TColumnNullable::Create( + CreateColumnFromAst(ast.Elements.front())); + } + + case TTypeAst::Terminal: { + return CreateTerminalColumn(ast); + } + + case TTypeAst::Tuple: { + TVector<TColumnRef> columns; + + for (const auto& elem : ast.Elements) { + if (auto col = CreateColumnFromAst(elem)) { + columns.push_back(col); + } else { + return nullptr; + } + } + + return TColumnTuple::Create(columns); + } + + case TTypeAst::Enum: { + TVector<TEnumItem> enum_items; + + for (const auto& elem : ast.Elements) { + TString name(elem.Name); + i16 value = elem.Value; + enum_items.push_back({name, value}); + } + + if (ast.Name == "Enum8") { + return TColumnEnum8::Create(enum_items); + } else { + return TColumnEnum16::Create(enum_items); + } + } + + case TTypeAst::Null: + case TTypeAst::Number: + break; + } + + return nullptr; + } + + } + + TColumnRef CreateColumnByType(const TString& type_name) { + TTypeAst ast; + + if (TTypeParser(type_name).Parse(&ast)) { + return CreateColumnFromAst(ast); + } + + return nullptr; + } + +} diff --git a/library/cpp/clickhouse/client/columns/factory.h b/library/cpp/clickhouse/client/columns/factory.h new file mode 100644 index 0000000000..0b2b82ece3 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/factory.h @@ -0,0 +1,7 @@ +#pragma once + +#include "column.h" + +namespace NClickHouse { + TColumnRef CreateColumnByType(const TString& type_name); +} diff --git a/library/cpp/clickhouse/client/columns/nullable.cpp b/library/cpp/clickhouse/client/columns/nullable.cpp new file mode 100644 index 0000000000..1d9dffea27 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/nullable.cpp @@ -0,0 +1,70 @@ +#include "nullable.h" + +#include <util/generic/yexception.h> +#include <util/system/yassert.h> + +namespace NClickHouse { + TColumnNullable::TColumnNullable(TColumnRef nested, TColumnRef nulls) + : TColumn(TType::CreateNullable(nested->Type())) + , Nested_(nested) + , Nulls_(nulls->As<TColumnUInt8>()) + { + if (Nested_->Size() != nulls->Size()) { + ythrow yexception() << "count of elements in nested and nulls should be the same"; + } + } + + TIntrusivePtr<TColumnNullable> TColumnNullable::Create(TColumnRef nested) { + return new TColumnNullable(nested, TColumnUInt8::Create()); + } + + TIntrusivePtr<TColumnNullable> TColumnNullable::Create(TColumnRef nested, TColumnRef nulls) { + return new TColumnNullable(nested, nulls); + } + + bool TColumnNullable::IsNull(size_t n) const { + return Nulls_->At(n) != 0; + } + + TColumnRef TColumnNullable::Nested() const { + return Nested_; + } + + void TColumnNullable::Append(TColumnRef column) { + if (auto col = column->As<TColumnNullable>()) { + if (!col->Nested_->Type()->IsEqual(Nested_->Type())) { + return; + } + + Nested_->Append(col->Nested_); + Nulls_->Append(col->Nulls_); + } + } + + bool TColumnNullable::Load(TCodedInputStream* input, size_t rows) { + if (!Nulls_->Load(input, rows)) { + return false; + } + if (!Nested_->Load(input, rows)) { + return false; + } + return true; + } + + void TColumnNullable::Save(TCodedOutputStream* output) { + Nulls_->Save(output); + Nested_->Save(output); + } + + size_t TColumnNullable::Size() const { + Y_ASSERT(Nested_->Size() == Nulls_->Size()); + return Nulls_->Size(); + } + + TColumnRef TColumnNullable::Slice(size_t begin, size_t len) { + (void)begin; + (void)len; + return TColumnRef(); + } + +} diff --git a/library/cpp/clickhouse/client/columns/nullable.h b/library/cpp/clickhouse/client/columns/nullable.h new file mode 100644 index 0000000000..e0f88e6f75 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/nullable.h @@ -0,0 +1,44 @@ +#pragma once + +#include "column.h" +#include "numeric.h" + +namespace NClickHouse { + /** + * Represents column of Nullable(T). + */ + class TColumnNullable: public TColumn { + public: + static TIntrusivePtr<TColumnNullable> Create(TColumnRef nested); + static TIntrusivePtr<TColumnNullable> Create(TColumnRef nested, TColumnRef nulls); + + /// Returns null flag at given row number. + bool IsNull(size_t n) const; + + /// Returns nested column. + TColumnRef Nested() const; + + public: + /// Appends content of given column to the end of current one. + void Append(TColumnRef column) override; + + /// Loads column data from input stream. + bool Load(TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + TColumnRef Slice(size_t begin, size_t len) override; + + private: + TColumnNullable(TColumnRef nested, TColumnRef nulls); + + TColumnRef Nested_; + TIntrusivePtr<TColumnUInt8> Nulls_; + }; + +} diff --git a/library/cpp/clickhouse/client/columns/numeric.cpp b/library/cpp/clickhouse/client/columns/numeric.cpp new file mode 100644 index 0000000000..68cbe3d4e4 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/numeric.cpp @@ -0,0 +1,103 @@ +#include "numeric.h" + +#include "utils.h" + +namespace NClickHouse { + template <typename T> + TColumnVector<T>::TColumnVector() + : TColumn(TType::CreateSimple<T>()) + { + } + + template <typename T> + TColumnVector<T>::TColumnVector(const TVector<T>& data) + : TColumn(TType::CreateSimple<T>()) + , Data_(data) + { + } + + template <typename T> + TColumnVector<T>::TColumnVector(TVector<T>&& data) + : TColumn(TType::CreateSimple<T>()) + , Data_(std::move(data)) + { + } + + template <typename T> + TIntrusivePtr<TColumnVector<T>> TColumnVector<T>::Create() { + return new TColumnVector<T>(); + } + + template <typename T> + TIntrusivePtr<TColumnVector<T>> TColumnVector<T>::Create(const TVector<T>& data) { + return new TColumnVector<T>(data); + } + + template <typename T> + TIntrusivePtr<TColumnVector<T>> TColumnVector<T>::Create(TVector<T>&& data) { + return new TColumnVector<T>(std::move(data)); + } + + template <typename T> + void TColumnVector<T>::Append(const T& value) { + Data_.push_back(value); + } + + template <typename T> + const T& TColumnVector<T>::At(size_t n) const { + return Data_.at(n); + } + + template <typename T> + const T& TColumnVector<T>::operator[](size_t n) const { + return Data_[n]; + } + + template <typename T> + void TColumnVector<T>::SetAt(size_t n, const T& value) { + Data_.at(n) = value; + } + + template <typename T> + void TColumnVector<T>::Append(TColumnRef column) { + if (auto col = column->As<TColumnVector<T>>()) { + Data_.insert(Data_.end(), col->Data_.begin(), col->Data_.end()); + } + } + + template <typename T> + bool TColumnVector<T>::Load(TCodedInputStream* input, size_t rows) { + Data_.resize(rows); + + return input->ReadRaw(Data_.data(), Data_.size() * sizeof(T)); + } + + template <typename T> + void TColumnVector<T>::Save(TCodedOutputStream* output) { + output->WriteRaw(Data_.data(), Data_.size() * sizeof(T)); + } + + template <typename T> + size_t TColumnVector<T>::Size() const { + return Data_.size(); + } + + template <typename T> + TColumnRef TColumnVector<T>::Slice(size_t begin, size_t len) { + return new TColumnVector<T>(SliceVector(Data_, begin, len)); + } + + template class TColumnVector<i8>; + template class TColumnVector<i16>; + template class TColumnVector<i32>; + template class TColumnVector<i64>; + + template class TColumnVector<ui8>; + template class TColumnVector<ui16>; + template class TColumnVector<ui32>; + template class TColumnVector<ui64>; + + template class TColumnVector<float>; + template class TColumnVector<double>; + +} diff --git a/library/cpp/clickhouse/client/columns/numeric.h b/library/cpp/clickhouse/client/columns/numeric.h new file mode 100644 index 0000000000..11a2ddac00 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/numeric.h @@ -0,0 +1,65 @@ +#pragma once + +#include "column.h" + +namespace NClickHouse { + /** + * Represents various numeric columns. + */ + template <typename T> + class TColumnVector: public TColumn { + public: + static TIntrusivePtr<TColumnVector<T>> Create(); + static TIntrusivePtr<TColumnVector<T>> Create(const TVector<T>& data); + static TIntrusivePtr<TColumnVector<T>> Create(TVector<T>&& data); + + /// Appends one element to the end of column. + void Append(const T& value); + + /// Returns element at given row number. + const T& At(size_t n) const; + + /// Returns element at given row number. + const T& operator[](size_t n) const; + + /// Set element at given row number. + void SetAt(size_t n, const T& value); + + public: + /// Appends content of given column to the end of current one. + void Append(TColumnRef column) override; + + /// Loads column data from input stream. + bool Load(TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + TColumnRef Slice(size_t begin, size_t len) override; + + private: + TColumnVector(); + TColumnVector(const TVector<T>& data); + TColumnVector(TVector<T>&& data); + + TVector<T> Data_; + }; + + using TColumnUInt8 = TColumnVector<ui8>; + using TColumnUInt16 = TColumnVector<ui16>; + using TColumnUInt32 = TColumnVector<ui32>; + using TColumnUInt64 = TColumnVector<ui64>; + + using TColumnInt8 = TColumnVector<i8>; + using TColumnInt16 = TColumnVector<i16>; + using TColumnInt32 = TColumnVector<i32>; + using TColumnInt64 = TColumnVector<i64>; + + using TColumnFloat32 = TColumnVector<float>; + using TColumnFloat64 = TColumnVector<double>; + +} diff --git a/library/cpp/clickhouse/client/columns/string.cpp b/library/cpp/clickhouse/client/columns/string.cpp new file mode 100644 index 0000000000..92053aadc8 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/string.cpp @@ -0,0 +1,241 @@ +#include "string.h" +#include "utils.h" + +#include <library/cpp/clickhouse/client/base/wire_format.h> + +#include <util/memory/tempbuf.h> + +namespace NClickHouse { + TColumnFixedString::TColumnFixedString(size_t n) + : TColumn(TType::CreateString(n)) + , StringSize_(n) + { + } + + TColumnFixedString::TColumnFixedString(size_t n, const TVector<TString>& data) + : TColumnFixedString(n) + { + Data_.reserve(data.size()); + for (const auto& value : data) { + Append(value); + } + } + + TIntrusivePtr<TColumnFixedString> TColumnFixedString::Create(size_t n) { + return new TColumnFixedString(n); + } + + TIntrusivePtr<TColumnFixedString> TColumnFixedString::Create(size_t n, const TVector<TString>& data) { + return new TColumnFixedString(n, data); + } + + void TColumnFixedString::Append(const TString& str) { + Data_.push_back(str); + Data_.back().resize(StringSize_); + } + + const TString& TColumnFixedString::At(size_t n) const { + return Data_.at(n); + } + + const TString& TColumnFixedString::operator[](size_t n) const { + return Data_[n]; + } + + void TColumnFixedString::SetAt(size_t n, const TString& value) { + TString stringResized(value); + stringResized.resize(StringSize_); + Data_.at(n) = stringResized; + } + + void TColumnFixedString::Append(TColumnRef column) { + if (auto col = column->As<TColumnFixedString>()) { + if (StringSize_ == col->StringSize_) { + Data_.insert(Data_.end(), col->Data_.begin(), col->Data_.end()); + } + } + } + + bool TColumnFixedString::Load(TCodedInputStream* input, size_t rows) { + for (size_t i = 0; i < rows; ++i) { + TTempBuf s(StringSize_); + + if (!TWireFormat::ReadBytes(input, s.Data(), StringSize_)) { + return false; + } + + Data_.push_back(TString(s.Data(), StringSize_)); + } + + return true; + } + + void TColumnFixedString::Save(TCodedOutputStream* output) { + for (size_t i = 0; i < Data_.size(); ++i) { + TWireFormat::WriteBytes(output, Data_[i].data(), StringSize_); + } + } + + size_t TColumnFixedString::Size() const { + return Data_.size(); + } + + TColumnRef TColumnFixedString::Slice(size_t begin, size_t len) { + auto result = new TColumnFixedString(StringSize_); + + if (begin < Data_.size()) { + result->Data_ = SliceVector(Data_, begin, len); + } + + return result; + } + + TColumnString::TColumnString() + : TColumn(TType::CreateString()) + { + } + + TColumnString::TColumnString(const TVector<TString>& data) + : TColumn(TType::CreateString()) + , Data_(data) + { + } + + TColumnString::TColumnString(TVector<TString>&& data) + : TColumn(TType::CreateString()) + , Data_(std::move(data)) + { + } + + TIntrusivePtr<TColumnString> TColumnString::Create() { + return new TColumnString(); + } + + TIntrusivePtr<TColumnString> TColumnString::Create(const TVector<TString>& data) { + return new TColumnString(data); + } + + TIntrusivePtr<TColumnString> TColumnString::Create(TVector<TString>&& data) { + return new TColumnString(std::move(data)); + } + + void TColumnString::Append(const TString& str) { + Data_.push_back(str); + } + + const TString& TColumnString::At(size_t n) const { + return Data_.at(n); + } + + const TString& TColumnString::operator[](size_t n) const { + return Data_[n]; + } + + void TColumnString::SetAt(size_t n, const TString& value) { + Data_.at(n) = value; + } + + void TColumnString::Append(TColumnRef column) { + if (auto col = column->As<TColumnString>()) { + Data_.insert(Data_.end(), col->Data_.begin(), col->Data_.end()); + } + } + + bool TColumnString::Load(TCodedInputStream* input, size_t rows) { + for (size_t i = 0; i < rows; ++i) { + TString s; + + if (!TWireFormat::ReadString(input, &s)) { + return false; + } + + Data_.push_back(s); + } + + return true; + } + + void TColumnString::Save(TCodedOutputStream* output) { + for (auto si = Data_.begin(); si != Data_.end(); ++si) { + TWireFormat::WriteString(output, *si); + } + } + + size_t TColumnString::Size() const { + return Data_.size(); + } + + TColumnRef TColumnString::Slice(size_t begin, size_t len) { + return new TColumnString(SliceVector(Data_, begin, len)); + } + + TColumnStringBuf::TColumnStringBuf() + : TColumn(TType::CreateString()) + { + } + + TColumnStringBuf::TColumnStringBuf(const TVector<TStringBuf>& data) + : TColumn(TType::CreateString()) + , Data_(data) + { + } + + TColumnStringBuf::TColumnStringBuf(TVector<TStringBuf>&& data) + : TColumn(TType::CreateString()) + , Data_(std::move(data)) + { + } + + TIntrusivePtr<TColumnStringBuf> TColumnStringBuf::Create() { + return new TColumnStringBuf(); + } + + TIntrusivePtr<TColumnStringBuf> TColumnStringBuf::Create(const TVector<TStringBuf>& data) { + return new TColumnStringBuf(data); + } + + TIntrusivePtr<TColumnStringBuf> TColumnStringBuf::Create(TVector<TStringBuf>&& data) { + return new TColumnStringBuf(std::move(data)); + } + + void TColumnStringBuf::Append(TStringBuf str) { + Data_.push_back(str); + } + + const TStringBuf& TColumnStringBuf::At(size_t n) const { + return Data_.at(n); + } + + const TStringBuf& TColumnStringBuf::operator[](size_t n) const { + return Data_[n]; + } + + void TColumnStringBuf::SetAt(size_t n, TStringBuf value) { + Data_.at(n) = value; + } + + void TColumnStringBuf::Append(TColumnRef column) { + if (auto col = column->As<TColumnStringBuf>()) { + Data_.insert(Data_.end(), col->Data_.begin(), col->Data_.end()); + } + } + + bool TColumnStringBuf::Load(TCodedInputStream*, size_t) { + ythrow yexception() << "load not implemented"; + } + + void TColumnStringBuf::Save(TCodedOutputStream* output) { + for (auto si = Data_.begin(); si != Data_.end(); ++si) { + TWireFormat::WriteStringBuf(output, *si); + } + } + + size_t TColumnStringBuf::Size() const { + return Data_.size(); + } + + TColumnRef TColumnStringBuf::Slice(size_t begin, size_t len) { + return new TColumnStringBuf(SliceVector(Data_, begin, len)); + } + +} diff --git a/library/cpp/clickhouse/client/columns/string.h b/library/cpp/clickhouse/client/columns/string.h new file mode 100644 index 0000000000..19c41fcda3 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/string.h @@ -0,0 +1,142 @@ +#pragma once + +#include "column.h" + +#include <util/generic/string.h> + +namespace NClickHouse { + /** + * Represents column of fixed-length strings. + */ + class TColumnFixedString: public TColumn { + public: + static TIntrusivePtr<TColumnFixedString> Create(size_t n); + static TIntrusivePtr<TColumnFixedString> Create(size_t n, const TVector<TString>& data); + + /// Appends one element to the column. + void Append(const TString& str); + + /// Returns element at given row number. + const TString& At(size_t n) const; + + /// Returns element at given row number. + const TString& operator[](size_t n) const; + + /// Set element at given row number. + void SetAt(size_t n, const TString& value); + + public: + /// Appends content of given column to the end of current one. + void Append(TColumnRef column) override; + + /// Loads column data from input stream. + bool Load(TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + TColumnRef Slice(size_t begin, size_t len) override; + + private: + TColumnFixedString(size_t n); + TColumnFixedString(size_t n, const TVector<TString>& data); + + const size_t StringSize_; + TVector<TString> Data_; + }; + + /** + * Represents column of variable-length strings. + */ + class TColumnString: public TColumn { + public: + static TIntrusivePtr<TColumnString> Create(); + static TIntrusivePtr<TColumnString> Create(const TVector<TString>& data); + static TIntrusivePtr<TColumnString> Create(TVector<TString>&& data); + + /// Appends one element to the column. + void Append(const TString& str); + + /// Returns element at given row number. + const TString& At(size_t n) const; + + /// Returns element at given row number. + const TString& operator[](size_t n) const; + + /// Set element at given row number. + void SetAt(size_t n, const TString& value); + + public: + /// Appends content of given column to the end of current one. + void Append(TColumnRef column) override; + + /// Loads column data from input stream. + bool Load(TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + TColumnRef Slice(size_t begin, size_t len) override; + + private: + TColumnString(); + TColumnString(const TVector<TString>& data); + TColumnString(TVector<TString>&& data); + + TVector<TString> Data_; + }; + + /** +* Represents column of variable-length strings but use TStringBuf instead TString. +*/ + class TColumnStringBuf: public NClickHouse::TColumn { + public: + static TIntrusivePtr<TColumnStringBuf> Create(); + static TIntrusivePtr<TColumnStringBuf> Create(const TVector<TStringBuf>& data); + static TIntrusivePtr<TColumnStringBuf> Create(TVector<TStringBuf>&& data); + + /// Appends one element to the column. + void Append(TStringBuf str); + + /// Returns element at given row number. + const TStringBuf& At(size_t n) const; + + /// Returns element at given row number. + const TStringBuf& operator[](size_t n) const; + + /// Set element at given row number. + void SetAt(size_t n, TStringBuf value); + + public: + /// Appends content of given column to the end of current one. + void Append(NClickHouse::TColumnRef column) override; + + /// Loads column data from input stream. + bool Load(NClickHouse::TCodedInputStream* input, size_t rows) override; + + /// Saves column data to output stream. + void Save(NClickHouse::TCodedOutputStream* output) override; + + /// Returns count of rows in the column. + size_t Size() const override; + + /// Makes slice of the current column. + NClickHouse::TColumnRef Slice(size_t begin, size_t len) override; + + private: + TColumnStringBuf(); + TColumnStringBuf(const TVector<TStringBuf>& data); + TColumnStringBuf(TVector<TStringBuf>&& data); + + TVector<TStringBuf> Data_; + }; + +} diff --git a/library/cpp/clickhouse/client/columns/tuple.cpp b/library/cpp/clickhouse/client/columns/tuple.cpp new file mode 100644 index 0000000000..3d0d00e772 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/tuple.cpp @@ -0,0 +1,42 @@ +#include "tuple.h" + +namespace NClickHouse { + static TVector<TTypeRef> CollectTypes(const TVector<TColumnRef>& columns) { + TVector<TTypeRef> types; + for (const auto& col : columns) { + types.push_back(col->Type()); + } + return types; + } + + TColumnTuple::TColumnTuple(const TVector<TColumnRef>& columns) + : TColumn(TType::CreateTuple(CollectTypes(columns))) + , Columns_(columns) + { + } + + TIntrusivePtr<TColumnTuple> TColumnTuple::Create(const TVector<TColumnRef>& columns) { + return new TColumnTuple(columns); + } + + size_t TColumnTuple::Size() const { + return Columns_.empty() ? 0 : Columns_[0]->Size(); + } + + bool TColumnTuple::Load(TCodedInputStream* input, size_t rows) { + for (auto ci = Columns_.begin(); ci != Columns_.end(); ++ci) { + if (!(*ci)->Load(input, rows)) { + return false; + } + } + + return true; + } + + void TColumnTuple::Save(TCodedOutputStream* output) { + for (auto ci = Columns_.begin(); ci != Columns_.end(); ++ci) { + (*ci)->Save(output); + } + } + +} diff --git a/library/cpp/clickhouse/client/columns/tuple.h b/library/cpp/clickhouse/client/columns/tuple.h new file mode 100644 index 0000000000..d388a7b9a9 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/tuple.h @@ -0,0 +1,37 @@ +#pragma once + +#include "column.h" + +#include <util/generic/vector.h> + +namespace NClickHouse { + /** */ + class TColumnTuple: public TColumn { + public: + static TIntrusivePtr<TColumnTuple> Create(const TVector<TColumnRef>& columns); + + TColumnRef operator[](size_t n) const { + return Columns_[n]; + } + + /// Appends content of given column to the end of current one. + void Append(TColumnRef) override { + } + + size_t Size() const override; + + bool Load(TCodedInputStream* input, size_t rows) override; + + void Save(TCodedOutputStream* output) override; + + TColumnRef Slice(size_t, size_t) override { + return TColumnRef(); + } + + private: + TColumnTuple(const TVector<TColumnRef>& columns); + + TVector<TColumnRef> Columns_; + }; + +} diff --git a/library/cpp/clickhouse/client/columns/utils.h b/library/cpp/clickhouse/client/columns/utils.h new file mode 100644 index 0000000000..fc43828c63 --- /dev/null +++ b/library/cpp/clickhouse/client/columns/utils.h @@ -0,0 +1,19 @@ +#pragma once + +#include <algorithm> +#include <util/generic/vector.h> + +namespace NClickHouse { + template <typename T> + TVector<T> SliceVector(const TVector<T>& vec, size_t begin, size_t len) { + TVector<T> result; + + if (begin < vec.size()) { + len = std::min(len, vec.size() - begin); + result.assign(vec.begin() + begin, vec.begin() + (begin + len)); + } + + return result; + } + +} diff --git a/library/cpp/clickhouse/client/columns/ya.make b/library/cpp/clickhouse/client/columns/ya.make new file mode 100644 index 0000000000..29330f949e --- /dev/null +++ b/library/cpp/clickhouse/client/columns/ya.make @@ -0,0 +1,19 @@ +LIBRARY() + +SRCS( + array.cpp + date.cpp + enum.cpp + factory.cpp + nullable.cpp + numeric.cpp + string.cpp + tuple.cpp +) + +PEERDIR( + library/cpp/clickhouse/client/base + library/cpp/clickhouse/client/types +) + +END() |