ClickHouse/src/Storages/ColumnsDescription.h

271 lines
9.9 KiB
C++
Raw Normal View History

#pragma once
#include <Compression/CompressionFactory.h>
#include <Core/Block.h>
#include <Core/Names.h>
#include <Core/NamesAndTypes.h>
#include <Core/NamesAndAliases.h>
#include <Interpreters/Context_fwd.h>
#include <Storages/ColumnDefault.h>
2023-09-26 17:16:01 +00:00
#include <Storages/StatisticsDescription.h>
#include <Common/Exception.h>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index_container.hpp>
#include <optional>
namespace DB
{
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
}
struct GetColumnsOptions
{
enum Kind : UInt8
{
Ordinary = 1,
Materialized = 2,
Aliases = 4,
Ephemeral = 8,
2023-01-27 16:59:54 +00:00
OrdinaryAndAliases = Ordinary | Aliases,
AllPhysical = Ordinary | Materialized,
2023-01-27 16:59:54 +00:00
AllPhysicalAndAliases = AllPhysical | Aliases,
All = AllPhysical | Aliases | Ephemeral,
};
GetColumnsOptions(Kind kind_) : kind(kind_) {}
GetColumnsOptions & withSubcolumns(bool value = true)
{
with_subcolumns = value;
return *this;
}
GetColumnsOptions & withVirtuals(bool value = true)
{
with_virtuals = value;
return *this;
}
GetColumnsOptions & withExtendedObjects(bool value = true)
{
with_extended_objects = value;
return *this;
}
2022-07-21 19:50:19 +00:00
GetColumnsOptions & withSystemColumns(bool value = true)
{
with_system_columns = value;
return *this;
}
Kind kind;
bool with_subcolumns = false;
bool with_virtuals = false;
bool with_extended_objects = false;
2022-07-21 19:50:19 +00:00
bool with_system_columns = false;
};
/// Description of a single table column (in CREATE TABLE for example).
struct ColumnDescription
{
String name;
DataTypePtr type;
ColumnDefault default_desc;
String comment;
ASTPtr codec;
ASTPtr ttl;
2023-09-26 17:16:01 +00:00
std::optional<StatisticDescription> stat;
ColumnDescription() = default;
ColumnDescription(ColumnDescription &&) = default;
ColumnDescription(const ColumnDescription &) = default;
2020-04-27 13:55:30 +00:00
ColumnDescription(String name_, DataTypePtr type_);
ColumnDescription(String name_, DataTypePtr type_, String comment_);
ColumnDescription(String name_, DataTypePtr type_, ASTPtr codec_, String comment_);
bool operator==(const ColumnDescription & other) const;
bool operator!=(const ColumnDescription & other) const { return !(*this == other); }
void writeText(WriteBuffer & buf) const;
void readText(ReadBuffer & buf);
};
2018-11-12 15:45:35 +00:00
/// Description of multiple table columns (in CREATE TABLE for example).
2023-09-10 03:48:12 +00:00
class ColumnsDescription : public IHints<>
{
public:
ColumnsDescription() = default;
static ColumnsDescription fromNamesAndTypes(NamesAndTypes ordinary);
explicit ColumnsDescription(NamesAndTypesList ordinary);
explicit ColumnsDescription(std::initializer_list<ColumnDescription> ordinary);
explicit ColumnsDescription(NamesAndTypesList ordinary, NamesAndAliases aliases);
void setAliases(NamesAndAliases aliases);
/// `after_column` can be a Nested column name;
2022-05-20 17:48:24 +00:00
void add(ColumnDescription column, const String & after_column = String(), bool first = false, bool add_subcolumns = true);
/// `column_name` can be a Nested column name;
void remove(const String & column_name);
2020-04-03 10:40:46 +00:00
/// Rename column. column_from and column_to cannot be nested columns.
/// TODO add ability to rename nested columns
2020-03-24 17:05:38 +00:00
void rename(const String & column_from, const String & column_to);
/// NOTE Must correspond with Nested::flatten function.
void flattenNested(); /// TODO: remove, insert already flattened Nested columns.
bool operator==(const ColumnsDescription & other) const { return columns == other.columns; }
bool operator!=(const ColumnsDescription & other) const { return !(*this == other); }
auto begin() const { return columns.begin(); }
auto end() const { return columns.end(); }
NamesAndTypesList get(const GetColumnsOptions & options) const;
NamesAndTypesList getByNames(const GetColumnsOptions & options, const Names & names) const;
NamesAndTypesList getOrdinary() const;
NamesAndTypesList getMaterialized() const;
NamesAndTypesList getInsertable() const; /// ordinary + ephemeral
NamesAndTypesList getAliases() const;
NamesAndTypesList getEphemeral() const;
2019-05-22 19:38:43 +00:00
NamesAndTypesList getAllPhysical() const; /// ordinary + materialized.
NamesAndTypesList getAll() const; /// ordinary + materialized + aliases + ephemeral
/// Returns .size0/.null/...
NamesAndTypesList getSubcolumns(const String & name_in_storage) const;
/// Returns column_name.*
NamesAndTypesList getNested(const String & column_name) const;
using ColumnTTLs = std::unordered_map<String, ASTPtr>;
ColumnTTLs getColumnTTLs() const;
void resetColumnTTLs();
bool has(const String & column_name) const;
bool hasNested(const String & column_name) const;
bool hasSubcolumn(const String & column_name) const;
const ColumnDescription & get(const String & column_name) const;
template <typename F>
void modify(const String & column_name, F && f)
{
modify(column_name, String(), false, std::forward<F>(f));
}
template <typename F>
void modify(const String & column_name, const String & after_column, bool first, F && f)
{
auto it = columns.get<1>().find(column_name);
if (it == columns.get<1>().end())
2022-04-01 13:12:54 +00:00
{
throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot find column {} in ColumnsDescription{}",
column_name, getHintsMessage(column_name));
2022-04-01 13:12:54 +00:00
}
removeSubcolumns(it->name);
if (!columns.get<1>().modify(it, std::forward<F>(f)))
throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot modify ColumnDescription for column {}: column name cannot be changed", column_name);
addSubcolumns(it->name, it->type);
modifyColumnOrder(column_name, after_column, first);
}
Names getNamesOfPhysical() const;
2018-03-13 15:00:28 +00:00
bool hasPhysical(const String & column_name) const;
bool hasNotAlias(const String & column_name) const;
2023-05-01 20:51:46 +00:00
bool hasAlias(const String & column_name) const;
bool hasColumnOrSubcolumn(GetColumnsOptions::Kind kind, const String & column_name) const;
bool hasColumnOrNested(GetColumnsOptions::Kind kind, const String & column_name) const;
bool hasOnlyOrdinary() const;
NameAndTypePair getPhysical(const String & column_name) const;
NameAndTypePair getColumnOrSubcolumn(GetColumnsOptions::Kind kind, const String & column_name) const;
NameAndTypePair getColumn(const GetColumnsOptions & options, const String & column_name) const;
std::optional<NameAndTypePair> tryGetPhysical(const String & column_name) const;
std::optional<NameAndTypePair> tryGetColumnOrSubcolumn(GetColumnsOptions::Kind kind, const String & column_name) const;
2021-07-21 14:45:19 +00:00
std::optional<NameAndTypePair> tryGetColumn(const GetColumnsOptions & options, const String & column_name) const;
std::optional<const ColumnDescription> tryGetColumnOrSubcolumnDescription(GetColumnsOptions::Kind kind, const String & column_name) const;
std::optional<const ColumnDescription> tryGetColumnDescription(const GetColumnsOptions & options, const String & column_name) const;
ColumnDefaults getDefaults() const; /// TODO: remove
bool hasDefault(const String & column_name) const;
2020-10-02 12:38:50 +00:00
bool hasDefaults() const;
std::optional<ColumnDefault> getDefault(const String & column_name) const;
2020-08-28 09:07:20 +00:00
/// Does column has non default specified compression codec
bool hasCompressionCodec(const String & column_name) const;
2018-12-21 12:17:30 +00:00
CompressionCodecPtr getCodecOrDefault(const String & column_name, CompressionCodecPtr default_codec) const;
CompressionCodecPtr getCodecOrDefault(const String & column_name) const;
2020-09-21 11:24:10 +00:00
ASTPtr getCodecDescOrDefault(const String & column_name, CompressionCodecPtr default_codec) const;
String toString() const;
static ColumnsDescription parse(const String & str);
2018-10-11 02:57:48 +00:00
size_t size() const
{
return columns.size();
}
2020-07-13 17:27:52 +00:00
bool empty() const
{
return columns.empty();
}
2022-03-30 12:54:33 +00:00
std::vector<String> getAllRegisteredNames() const override;
/// Keep the sequence of columns and allow to lookup by name.
using ColumnsContainer = boost::multi_index_container<
ColumnDescription,
boost::multi_index::indexed_by<
boost::multi_index::sequenced<>,
boost::multi_index::ordered_unique<boost::multi_index::member<ColumnDescription, String, &ColumnDescription::name>>>>;
2019-03-15 18:52:45 +00:00
using SubcolumnsContainter = boost::multi_index_container<
NameAndTypePair,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<boost::multi_index::member<NameAndTypePair, String, &NameAndTypePair::name>>,
boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<NameAndTypePair, String, &NameAndTypePair::getNameInStorage>>>>;
private:
ColumnsContainer columns;
2022-04-26 05:23:01 +00:00
/// Subcolumns are not nested columns.
///
/// Example of subcolumns:
/// - .size0 for Array
/// - .null for Nullable
///
2022-04-26 05:23:01 +00:00
/// While nested columns have form like foo.bar
SubcolumnsContainter subcolumns;
2020-09-18 17:37:08 +00:00
void modifyColumnOrder(const String & column_name, const String & after_column, bool first);
void addSubcolumnsToList(NamesAndTypesList & source_list) const;
2021-01-12 23:20:32 +00:00
void addSubcolumns(const String & name_in_storage, const DataTypePtr & type_in_storage);
void removeSubcolumns(const String & name_in_storage);
};
/// Validate default expressions and corresponding types compatibility, i.e.
/// default expression result can be casted to column_type. Also checks, that we
/// don't have strange constructions in default expression like SELECT query or
/// arrayJoin function.
Block validateColumnsDefaultsAndGetSampleBlock(ASTPtr default_expr_list, const NamesAndTypesList & all_columns, ContextPtr context);
}