| 1 | #pragma once | 
|---|
| 2 |  | 
|---|
| 3 | #include <Core/NamesAndTypes.h> | 
|---|
| 4 | #include <Core/Names.h> | 
|---|
| 5 | #include <Core/Block.h> | 
|---|
| 6 | #include <Common/Exception.h> | 
|---|
| 7 | #include <Storages/ColumnDefault.h> | 
|---|
| 8 | #include <Storages/ColumnCodec.h> | 
|---|
| 9 | #include <optional> | 
|---|
| 10 |  | 
|---|
| 11 | #include <boost/multi_index_container.hpp> | 
|---|
| 12 | #include <boost/multi_index/sequenced_index.hpp> | 
|---|
| 13 | #include <boost/multi_index/ordered_index.hpp> | 
|---|
| 14 | #include <boost/multi_index/member.hpp> | 
|---|
| 15 |  | 
|---|
| 16 |  | 
|---|
| 17 | namespace DB | 
|---|
| 18 | { | 
|---|
| 19 |  | 
|---|
| 20 | namespace ErrorCodes | 
|---|
| 21 | { | 
|---|
| 22 | extern const int LOGICAL_ERROR; | 
|---|
| 23 | } | 
|---|
| 24 |  | 
|---|
| 25 |  | 
|---|
| 26 | /// Description of a single table column (in CREATE TABLE for example). | 
|---|
| 27 | struct ColumnDescription | 
|---|
| 28 | { | 
|---|
| 29 | String name; | 
|---|
| 30 | DataTypePtr type; | 
|---|
| 31 | ColumnDefault default_desc; | 
|---|
| 32 | String comment; | 
|---|
| 33 | CompressionCodecPtr codec; | 
|---|
| 34 | ASTPtr ttl; | 
|---|
| 35 | bool is_virtual = false; | 
|---|
| 36 |  | 
|---|
| 37 | ColumnDescription() = default; | 
|---|
| 38 | ColumnDescription(String name_, DataTypePtr type_, bool is_virtual_); | 
|---|
| 39 |  | 
|---|
| 40 | bool operator==(const ColumnDescription & other) const; | 
|---|
| 41 | bool operator!=(const ColumnDescription & other) const { return !(*this == other); } | 
|---|
| 42 |  | 
|---|
| 43 | void writeText(WriteBuffer & buf) const; | 
|---|
| 44 | void readText(ReadBuffer & buf); | 
|---|
| 45 | }; | 
|---|
| 46 |  | 
|---|
| 47 |  | 
|---|
| 48 | /// Description of multiple table columns (in CREATE TABLE for example). | 
|---|
| 49 | class ColumnsDescription | 
|---|
| 50 | { | 
|---|
| 51 | public: | 
|---|
| 52 | ColumnsDescription() = default; | 
|---|
| 53 | explicit ColumnsDescription(NamesAndTypesList ordinary_, bool all_virtuals = false); | 
|---|
| 54 |  | 
|---|
| 55 | /// `after_column` can be a Nested column name; | 
|---|
| 56 | void add(ColumnDescription column, const String & after_column = String()); | 
|---|
| 57 | /// `column_name` can be a Nested column name; | 
|---|
| 58 | void remove(const String & column_name); | 
|---|
| 59 |  | 
|---|
| 60 | void flattenNested(); /// TODO: remove, insert already flattened Nested columns. | 
|---|
| 61 |  | 
|---|
| 62 | bool operator==(const ColumnsDescription & other) const { return columns == other.columns; } | 
|---|
| 63 | bool operator!=(const ColumnsDescription & other) const { return !(*this == other); } | 
|---|
| 64 |  | 
|---|
| 65 | auto begin() const { return columns.begin(); } | 
|---|
| 66 | auto end() const { return columns.end(); } | 
|---|
| 67 |  | 
|---|
| 68 | NamesAndTypesList getOrdinary() const; | 
|---|
| 69 | NamesAndTypesList getMaterialized() const; | 
|---|
| 70 | NamesAndTypesList getAliases() const; | 
|---|
| 71 | NamesAndTypesList getVirtuals() const; | 
|---|
| 72 | NamesAndTypesList getAllPhysical() const; /// ordinary + materialized. | 
|---|
| 73 | NamesAndTypesList getAll() const; /// ordinary + materialized + aliases + virtuals. | 
|---|
| 74 |  | 
|---|
| 75 | using ColumnTTLs = std::unordered_map<String, ASTPtr>; | 
|---|
| 76 | ColumnTTLs getColumnTTLs() const; | 
|---|
| 77 |  | 
|---|
| 78 | bool has(const String & column_name) const; | 
|---|
| 79 | bool hasNested(const String & column_name) const; | 
|---|
| 80 | const ColumnDescription & get(const String & column_name) const; | 
|---|
| 81 |  | 
|---|
| 82 | template <typename F> | 
|---|
| 83 | void modify(const String & column_name, F && f) | 
|---|
| 84 | { | 
|---|
| 85 | auto it = columns.get<1>().find(column_name); | 
|---|
| 86 | if (it == columns.get<1>().end()) | 
|---|
| 87 | throw Exception( "Cannot find column "+ column_name + " in ColumnsDescription", ErrorCodes::LOGICAL_ERROR); | 
|---|
| 88 | if (!columns.get<1>().modify(it, std::forward<F>(f))) | 
|---|
| 89 | throw Exception( "Cannot modify ColumnDescription for column "+ column_name + ": column name cannot be changed", ErrorCodes::LOGICAL_ERROR); | 
|---|
| 90 | } | 
|---|
| 91 |  | 
|---|
| 92 | Names getNamesOfPhysical() const; | 
|---|
| 93 | bool hasPhysical(const String & column_name) const; | 
|---|
| 94 | NameAndTypePair getPhysical(const String & column_name) const; | 
|---|
| 95 |  | 
|---|
| 96 | ColumnDefaults getDefaults() const; /// TODO: remove | 
|---|
| 97 | bool hasDefault(const String & column_name) const; | 
|---|
| 98 | std::optional<ColumnDefault> getDefault(const String & column_name) const; | 
|---|
| 99 |  | 
|---|
| 100 | CompressionCodecPtr getCodecOrDefault(const String & column_name, CompressionCodecPtr default_codec) const; | 
|---|
| 101 | CompressionCodecPtr getCodecOrDefault(const String & column_name) const; | 
|---|
| 102 |  | 
|---|
| 103 | String toString() const; | 
|---|
| 104 | static ColumnsDescription parse(const String & str); | 
|---|
| 105 |  | 
|---|
| 106 | /// Keep the sequence of columns and allow to lookup by name. | 
|---|
| 107 | using Container = boost::multi_index_container< | 
|---|
| 108 | ColumnDescription, | 
|---|
| 109 | boost::multi_index::indexed_by< | 
|---|
| 110 | boost::multi_index::sequenced<>, | 
|---|
| 111 | boost::multi_index::ordered_unique<boost::multi_index::member<ColumnDescription, String, &ColumnDescription::name>>>>; | 
|---|
| 112 |  | 
|---|
| 113 | private: | 
|---|
| 114 | Container columns; | 
|---|
| 115 | }; | 
|---|
| 116 |  | 
|---|
| 117 | } | 
|---|
| 118 |  | 
|---|