aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/clickhouse/client/columns
diff options
context:
space:
mode:
authorgalaxycrab <UgnineSirdis@ydb.tech>2023-11-23 11:26:33 +0300
committergalaxycrab <UgnineSirdis@ydb.tech>2023-11-23 12:01:57 +0300
commit44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300 (patch)
treecb4d75cd1c6dbc3da0ed927337fd8d1b6ed9da84 /library/cpp/clickhouse/client/columns
parent0e69bf615395fdd48ecee032faaec81bc468b0b8 (diff)
downloadydb-44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300.tar.gz
YQ Connector:test INNER JOIN
Diffstat (limited to 'library/cpp/clickhouse/client/columns')
-rw-r--r--library/cpp/clickhouse/client/columns/CMakeLists.darwin-arm64.txt26
-rw-r--r--library/cpp/clickhouse/client/columns/CMakeLists.darwin-x86_64.txt26
-rw-r--r--library/cpp/clickhouse/client/columns/CMakeLists.linux-aarch64.txt27
-rw-r--r--library/cpp/clickhouse/client/columns/CMakeLists.linux-x86_64.txt27
-rw-r--r--library/cpp/clickhouse/client/columns/CMakeLists.txt17
-rw-r--r--library/cpp/clickhouse/client/columns/array.cpp87
-rw-r--r--library/cpp/clickhouse/client/columns/array.h55
-rw-r--r--library/cpp/clickhouse/client/columns/column.h60
-rw-r--r--library/cpp/clickhouse/client/columns/date.cpp126
-rw-r--r--library/cpp/clickhouse/client/columns/date.h84
-rw-r--r--library/cpp/clickhouse/client/columns/enum.cpp157
-rw-r--r--library/cpp/clickhouse/client/columns/enum.h57
-rw-r--r--library/cpp/clickhouse/client/columns/factory.cpp118
-rw-r--r--library/cpp/clickhouse/client/columns/factory.h7
-rw-r--r--library/cpp/clickhouse/client/columns/nullable.cpp70
-rw-r--r--library/cpp/clickhouse/client/columns/nullable.h44
-rw-r--r--library/cpp/clickhouse/client/columns/numeric.cpp103
-rw-r--r--library/cpp/clickhouse/client/columns/numeric.h65
-rw-r--r--library/cpp/clickhouse/client/columns/string.cpp241
-rw-r--r--library/cpp/clickhouse/client/columns/string.h142
-rw-r--r--library/cpp/clickhouse/client/columns/tuple.cpp42
-rw-r--r--library/cpp/clickhouse/client/columns/tuple.h37
-rw-r--r--library/cpp/clickhouse/client/columns/utils.h19
-rw-r--r--library/cpp/clickhouse/client/columns/ya.make19
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()