2015-04-11 03:10:23 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-04-10 23:33:54 +00:00
|
|
|
#include <Compression/CompressionFactory.h>
|
2018-03-06 20:18:34 +00:00
|
|
|
#include <Core/Block.h>
|
2021-04-10 23:33:54 +00:00
|
|
|
#include <Core/Names.h>
|
|
|
|
#include <Core/NamesAndTypes.h>
|
2021-06-28 11:42:21 +00:00
|
|
|
#include <Core/NamesAndAliases.h>
|
2021-04-10 23:33:54 +00:00
|
|
|
#include <Interpreters/Context_fwd.h>
|
|
|
|
#include <Storages/ColumnDefault.h>
|
|
|
|
#include <Common/Exception.h>
|
2015-04-11 03:10:23 +00:00
|
|
|
|
2019-05-01 21:43:05 +00:00
|
|
|
#include <boost/multi_index/member.hpp>
|
2021-07-15 03:12:37 +00:00
|
|
|
#include <boost/multi_index/mem_fun.hpp>
|
|
|
|
#include <boost/multi_index/hashed_index.hpp>
|
2021-04-10 23:33:54 +00:00
|
|
|
#include <boost/multi_index/ordered_index.hpp>
|
|
|
|
#include <boost/multi_index/sequenced_index.hpp>
|
|
|
|
#include <boost/multi_index_container.hpp>
|
|
|
|
|
|
|
|
#include <optional>
|
2019-05-01 21:43:05 +00:00
|
|
|
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2019-05-01 21:43:05 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int LOGICAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2021-05-04 23:02:54 +00:00
|
|
|
struct GetColumnsOptions
|
|
|
|
{
|
|
|
|
enum Kind : UInt8
|
|
|
|
{
|
2021-07-20 15:20:21 +00:00
|
|
|
Ordinary = 1,
|
|
|
|
Materialized = 2,
|
2021-05-04 23:02:54 +00:00
|
|
|
Aliases = 4,
|
2022-02-25 10:41:30 +00:00
|
|
|
Ephemeral = 8,
|
2023-01-27 16:59:54 +00:00
|
|
|
OrdinaryAndAliases = Ordinary | Aliases,
|
2021-07-20 15:20:21 +00:00
|
|
|
AllPhysical = Ordinary | Materialized,
|
2023-01-27 16:59:54 +00:00
|
|
|
AllPhysicalAndAliases = AllPhysical | Aliases,
|
2022-02-25 10:41:30 +00:00
|
|
|
All = AllPhysical | Aliases | Ephemeral,
|
2021-05-04 23:02:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-05-04 23:02:54 +00:00
|
|
|
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;
|
2021-05-04 23:02:54 +00:00
|
|
|
};
|
2019-05-01 21:43:05 +00:00
|
|
|
|
|
|
|
/// Description of a single table column (in CREATE TABLE for example).
|
2019-03-14 15:20:51 +00:00
|
|
|
struct ColumnDescription
|
|
|
|
{
|
|
|
|
String name;
|
|
|
|
DataTypePtr type;
|
|
|
|
ColumnDefault default_desc;
|
|
|
|
String comment;
|
2020-08-26 08:45:13 +00:00
|
|
|
ASTPtr codec;
|
2019-04-15 09:30:45 +00:00
|
|
|
ASTPtr ttl;
|
2019-03-14 15:20:51 +00:00
|
|
|
|
|
|
|
ColumnDescription() = default;
|
2020-07-01 14:58:52 +00:00
|
|
|
ColumnDescription(ColumnDescription &&) = default;
|
|
|
|
ColumnDescription(const ColumnDescription &) = default;
|
2020-04-27 13:55:30 +00:00
|
|
|
ColumnDescription(String name_, DataTypePtr type_);
|
2019-03-14 15:20:51 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
2019-05-01 21:43:05 +00:00
|
|
|
|
|
|
|
/// Description of multiple table columns (in CREATE TABLE for example).
|
2022-03-30 13:33:23 +00:00
|
|
|
class ColumnsDescription : public IHints<1, ColumnsDescription>
|
2015-04-11 03:10:23 +00:00
|
|
|
{
|
2019-03-14 15:20:51 +00:00
|
|
|
public:
|
2018-03-10 17:03:57 +00:00
|
|
|
ColumnsDescription() = default;
|
2021-06-28 11:42:21 +00:00
|
|
|
explicit ColumnsDescription(NamesAndTypesList ordinary);
|
|
|
|
|
|
|
|
explicit ColumnsDescription(NamesAndTypesList ordinary, NamesAndAliases aliases);
|
2018-03-10 17:03:57 +00:00
|
|
|
|
2019-03-14 15:20:51 +00:00
|
|
|
/// `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);
|
2019-03-14 15:20:51 +00:00
|
|
|
/// `column_name` can be a Nested column name;
|
|
|
|
void remove(const String & column_name);
|
2018-03-06 20:18:34 +00:00
|
|
|
|
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);
|
|
|
|
|
2020-04-20 23:44:51 +00:00
|
|
|
/// NOTE Must correspond with Nested::flatten function.
|
2019-03-14 15:20:51 +00:00
|
|
|
void flattenNested(); /// TODO: remove, insert already flattened Nested columns.
|
|
|
|
|
|
|
|
bool operator==(const ColumnsDescription & other) const { return columns == other.columns; }
|
2018-03-06 20:18:34 +00:00
|
|
|
bool operator!=(const ColumnsDescription & other) const { return !(*this == other); }
|
|
|
|
|
2019-05-01 21:43:05 +00:00
|
|
|
auto begin() const { return columns.begin(); }
|
|
|
|
auto end() const { return columns.end(); }
|
2018-03-10 17:03:57 +00:00
|
|
|
|
2021-05-04 23:02:54 +00:00
|
|
|
NamesAndTypesList get(const GetColumnsOptions & options) const;
|
2021-07-20 15:20:21 +00:00
|
|
|
NamesAndTypesList getByNames(const GetColumnsOptions & options, const Names & names) const;
|
2021-07-15 03:12:37 +00:00
|
|
|
|
2019-03-14 15:20:51 +00:00
|
|
|
NamesAndTypesList getOrdinary() const;
|
|
|
|
NamesAndTypesList getMaterialized() const;
|
2022-02-13 17:42:59 +00:00
|
|
|
NamesAndTypesList getInsertable() const; /// ordinary + ephemeral
|
2019-05-23 11:15:18 +00:00
|
|
|
NamesAndTypesList getAliases() const;
|
2022-02-07 23:21:10 +00:00
|
|
|
NamesAndTypesList getEphemeral() const;
|
2023-03-07 19:50:42 +00:00
|
|
|
NamesAndTypesList getWithDefaultExpression() const; // columns with default expression, for example set by `CREATE TABLE` statement
|
2019-05-22 19:38:43 +00:00
|
|
|
NamesAndTypesList getAllPhysical() const; /// ordinary + materialized.
|
2022-02-07 23:21:10 +00:00
|
|
|
NamesAndTypesList getAll() const; /// ordinary + materialized + aliases + ephemeral
|
2022-03-31 10:24:05 +00:00
|
|
|
/// Returns .size0/.null/...
|
2021-07-23 16:30:18 +00:00
|
|
|
NamesAndTypesList getSubcolumns(const String & name_in_storage) const;
|
2022-03-31 10:24:05 +00:00
|
|
|
/// Returns column_name.*
|
|
|
|
NamesAndTypesList getNested(const String & column_name) const;
|
2018-03-06 20:18:34 +00:00
|
|
|
|
2019-04-15 09:30:45 +00:00
|
|
|
using ColumnTTLs = std::unordered_map<String, ASTPtr>;
|
|
|
|
ColumnTTLs getColumnTTLs() const;
|
2022-02-28 06:12:17 +00:00
|
|
|
void resetColumnTTLs();
|
2019-04-15 09:30:45 +00:00
|
|
|
|
2019-03-14 15:20:51 +00:00
|
|
|
bool has(const String & column_name) const;
|
|
|
|
bool hasNested(const String & column_name) const;
|
2021-01-21 12:34:11 +00:00
|
|
|
bool hasSubcolumn(const String & column_name) const;
|
2019-03-14 15:20:51 +00:00
|
|
|
const ColumnDescription & get(const String & column_name) const;
|
2018-03-06 20:18:34 +00:00
|
|
|
|
2019-05-01 21:43:05 +00:00
|
|
|
template <typename F>
|
|
|
|
void modify(const String & column_name, F && f)
|
2020-07-01 14:58:52 +00:00
|
|
|
{
|
|
|
|
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)
|
2019-05-01 21:43:05 +00:00
|
|
|
{
|
|
|
|
auto it = columns.get<1>().find(column_name);
|
|
|
|
if (it == columns.get<1>().end())
|
2022-04-01 13:12:54 +00:00
|
|
|
{
|
|
|
|
String exception_message = fmt::format("Cannot find column {} in ColumnsDescription", column_name);
|
|
|
|
appendHintsMessage(exception_message, column_name);
|
2023-01-23 13:16:14 +00:00
|
|
|
throw Exception::createDeprecated(exception_message, ErrorCodes::LOGICAL_ERROR);
|
2022-04-01 13:12:54 +00:00
|
|
|
}
|
2022-02-09 20:47:53 +00:00
|
|
|
|
|
|
|
removeSubcolumns(it->name);
|
2019-05-01 21:43:05 +00:00
|
|
|
if (!columns.get<1>().modify(it, std::forward<F>(f)))
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot modify ColumnDescription for column {}: column name cannot be changed", column_name);
|
2020-07-01 14:58:52 +00:00
|
|
|
|
2022-02-09 20:47:53 +00:00
|
|
|
addSubcolumns(it->name, it->type);
|
2020-07-01 14:58:52 +00:00
|
|
|
modifyColumnOrder(column_name, after_column, first);
|
2019-05-01 21:43:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 15:20:51 +00:00
|
|
|
Names getNamesOfPhysical() const;
|
2021-07-15 17:36:48 +00:00
|
|
|
|
2018-03-13 15:00:28 +00:00
|
|
|
bool hasPhysical(const String & column_name) const;
|
2021-07-20 15:20:21 +00:00
|
|
|
bool hasColumnOrSubcolumn(GetColumnsOptions::Kind kind, const String & column_name) const;
|
2022-03-31 09:50:13 +00:00
|
|
|
bool hasColumnOrNested(GetColumnsOptions::Kind kind, const String & column_name) const;
|
2021-07-15 17:36:48 +00:00
|
|
|
|
2019-03-14 15:20:51 +00:00
|
|
|
NameAndTypePair getPhysical(const String & column_name) const;
|
2021-07-20 15:20:21 +00:00
|
|
|
NameAndTypePair getColumnOrSubcolumn(GetColumnsOptions::Kind kind, const String & column_name) const;
|
2021-07-23 16:30:18 +00:00
|
|
|
NameAndTypePair getColumn(const GetColumnsOptions & options, const String & column_name) const;
|
2021-07-15 17:36:48 +00:00
|
|
|
|
2021-07-15 03:12:37 +00:00
|
|
|
std::optional<NameAndTypePair> tryGetPhysical(const String & column_name) const;
|
2021-07-20 15:20:21 +00:00
|
|
|
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;
|
|
|
|
|
2022-05-16 14:19:44 +00:00
|
|
|
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;
|
|
|
|
|
2019-03-14 15:20:51 +00:00
|
|
|
ColumnDefaults getDefaults() const; /// TODO: remove
|
|
|
|
bool hasDefault(const String & column_name) const;
|
2020-10-02 12:38:50 +00:00
|
|
|
bool hasDefaults() const;
|
2019-03-14 15:20:51 +00:00
|
|
|
std::optional<ColumnDefault> getDefault(const String & column_name) const;
|
2015-04-11 03:10:23 +00:00
|
|
|
|
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;
|
2019-01-21 14:00:06 +00:00
|
|
|
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;
|
2019-01-21 14:00:06 +00:00
|
|
|
|
2019-03-14 15:20:51 +00:00
|
|
|
String toString() const;
|
2015-05-28 03:49:28 +00:00
|
|
|
static ColumnsDescription parse(const String & str);
|
2018-10-11 02:57:48 +00:00
|
|
|
|
2019-10-11 17:06:21 +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;
|
|
|
|
|
2019-05-01 21:43:05 +00:00
|
|
|
/// Keep the sequence of columns and allow to lookup by name.
|
2021-07-15 03:12:37 +00:00
|
|
|
using ColumnsContainer = boost::multi_index_container<
|
2019-05-01 21:43:05 +00:00
|
|
|
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
|
|
|
|
2021-07-15 03:12:37 +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>>>>;
|
2020-07-01 14:58:52 +00:00
|
|
|
|
2021-07-15 03:12:37 +00:00
|
|
|
private:
|
|
|
|
ColumnsContainer columns;
|
2022-04-26 05:23:01 +00:00
|
|
|
|
|
|
|
/// Subcolumns are not nested columns.
|
2022-03-31 10:21:01 +00:00
|
|
|
///
|
|
|
|
/// 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
|
2021-07-15 03:12:37 +00:00
|
|
|
SubcolumnsContainter subcolumns;
|
2020-09-18 17:37:08 +00:00
|
|
|
|
2020-07-01 14:58:52 +00:00
|
|
|
void modifyColumnOrder(const String & column_name, const String & after_column, bool first);
|
2021-07-15 03:12:37 +00:00
|
|
|
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);
|
2021-07-15 03:12:37 +00:00
|
|
|
void removeSubcolumns(const String & name_in_storage);
|
2015-04-11 03:10:23 +00:00
|
|
|
};
|
|
|
|
|
2020-03-03 10:02:43 +00:00
|
|
|
/// 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.
|
2021-04-10 23:33:54 +00:00
|
|
|
Block validateColumnsDefaultsAndGetSampleBlock(ASTPtr default_expr_list, const NamesAndTypesList & all_columns, ContextPtr context);
|
2015-04-11 03:10:23 +00:00
|
|
|
}
|