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
17namespace DB
18{
19
20namespace ErrorCodes
21{
22 extern const int LOGICAL_ERROR;
23}
24
25
26/// Description of a single table column (in CREATE TABLE for example).
27struct 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).
49class ColumnsDescription
50{
51public:
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
113private:
114 Container columns;
115};
116
117}
118