ClickHouse/src/Interpreters/StorageID.h

145 lines
4.1 KiB
C++
Raw Normal View History

2019-12-05 11:42:13 +00:00
#pragma once
2021-10-02 07:13:14 +00:00
#include <base/types.h>
2019-12-27 19:30:22 +00:00
#include <Core/UUID.h>
2019-12-05 11:42:13 +00:00
#include <tuple>
2020-03-04 20:29:52 +00:00
#include <Parsers/IAST_fwd.h>
#include <Core/QualifiedTableName.h>
2020-03-13 10:30:55 +00:00
#include <Common/Exception.h>
2019-12-05 11:42:13 +00:00
2020-07-14 19:19:17 +00:00
namespace Poco
{
namespace Util
{
2022-06-28 11:29:07 +00:00
class AbstractConfiguration; // NOLINT(cppcoreguidelines-virtual-class-destructor)
2020-07-14 19:19:17 +00:00
}
}
2019-12-05 11:42:13 +00:00
namespace DB
{
2020-03-13 10:30:55 +00:00
namespace ErrorCodes
{
2020-07-17 13:11:44 +00:00
extern const int UNKNOWN_TABLE;
2020-03-13 10:30:55 +00:00
}
2019-12-10 19:48:16 +00:00
static constexpr char const * TABLE_WITH_UUID_NAME_PLACEHOLDER = "_";
2020-02-17 19:28:25 +00:00
class ASTQueryWithTableAndOutput;
2020-10-26 15:49:00 +00:00
class ASTTableIdentifier;
2020-02-17 19:28:25 +00:00
class Context;
// TODO(ilezhankin): refactor and merge |ASTTableIdentifier|
2019-12-05 11:42:13 +00:00
struct StorageID
{
String database_name;
String table_name;
2020-02-17 19:28:25 +00:00
UUID uuid = UUIDHelpers::Nil;
2019-12-05 11:42:13 +00:00
2020-02-17 19:28:25 +00:00
StorageID(const String & database, const String & table, UUID uuid_ = UUIDHelpers::Nil)
2020-03-13 10:30:55 +00:00
: database_name(database), table_name(table), uuid(uuid_)
2019-12-05 11:42:13 +00:00
{
2019-12-30 18:20:43 +00:00
assertNotEmpty();
}
StorageID(const ASTQueryWithTableAndOutput & query); /// NOLINT
StorageID(const ASTTableIdentifier & table_identifier_node); /// NOLINT
StorageID(const ASTPtr & node); /// NOLINT
2020-03-04 20:29:52 +00:00
explicit StorageID(const QualifiedTableName & qualified_name) : StorageID(qualified_name.database, qualified_name.table) { }
2020-03-06 20:38:19 +00:00
String getDatabaseName() const;
2019-12-30 18:20:43 +00:00
2020-03-13 10:30:55 +00:00
String getTableName() const;
2019-12-05 11:42:13 +00:00
2020-03-06 20:38:19 +00:00
String getFullTableName() const;
2020-07-15 19:25:31 +00:00
String getFullNameNotQuoted() const;
2019-12-05 11:42:13 +00:00
2020-02-17 19:28:25 +00:00
String getNameForLogs() const;
2019-12-30 18:20:43 +00:00
explicit operator bool () const
2020-02-12 18:14:12 +00:00
{
return !empty();
}
2019-12-30 18:20:43 +00:00
bool empty() const
{
return table_name.empty() && !hasUUID();
}
bool hasUUID() const
{
2020-03-13 10:30:55 +00:00
return uuid != UUIDHelpers::Nil;
2019-12-05 11:42:13 +00:00
}
2022-09-09 15:21:37 +00:00
bool hasDatabase() const { return !database_name.empty(); }
2021-06-06 22:55:37 +00:00
bool operator==(const StorageID & rhs) const;
2019-12-10 19:48:16 +00:00
2020-03-13 10:30:55 +00:00
void assertNotEmpty() const
{
2020-07-21 13:53:23 +00:00
// Can be triggered by user input, e.g. SELECT joinGetOrNull('', 'num', 500)
2020-03-13 10:30:55 +00:00
if (empty())
throw Exception(ErrorCodes::UNKNOWN_TABLE, "Both table name and UUID are empty");
2020-03-13 10:30:55 +00:00
if (table_name.empty() && !database_name.empty())
throw Exception(ErrorCodes::UNKNOWN_TABLE, "Table name is empty, but database name is not");
2020-03-13 10:30:55 +00:00
}
2019-12-27 19:30:22 +00:00
2019-12-30 18:20:43 +00:00
/// Avoid implicit construction of empty StorageID. However, it's needed for deferred initialization.
static StorageID createEmpty() { return {}; }
2020-03-11 19:10:55 +00:00
QualifiedTableName getQualifiedName() const { return {database_name, getTableName()}; }
2020-03-04 20:29:52 +00:00
2020-07-14 19:19:17 +00:00
static StorageID fromDictionaryConfig(const Poco::Util::AbstractConfiguration & config,
const String & config_prefix);
2020-07-17 13:11:44 +00:00
/// If dictionary has UUID, then use it as dictionary name in ExternalLoader to allow dictionary renaming.
2021-03-19 12:47:27 +00:00
/// ExternalDictnariesLoader::resolveDictionaryName(...) should be used to access such dictionaries by name.
2021-10-13 20:47:28 +00:00
String getInternalDictionaryName() const { return getShortName(); }
/// Get short, but unique, name.
String getShortName() const;
2020-07-15 19:25:31 +00:00
/// Calculates hash using only the database and table name of a StorageID.
struct DatabaseAndTableNameHash
{
size_t operator()(const StorageID & storage_id) const
{
SipHash hash_state;
hash_state.update(storage_id.database_name.data(), storage_id.database_name.size());
hash_state.update(storage_id.table_name.data(), storage_id.table_name.size());
return hash_state.get64();
}
};
/// Checks if the database and table name of two StorageIDs are equal.
struct DatabaseAndTableNameEqual
{
bool operator()(const StorageID & left, const StorageID & right) const
{
return (left.database_name == right.database_name) && (left.table_name == right.table_name);
}
};
2019-12-30 18:20:43 +00:00
private:
StorageID() = default;
2019-12-05 11:42:13 +00:00
};
}
namespace fmt
{
template <>
struct formatter<DB::StorageID>
{
static constexpr auto parse(format_parse_context & ctx)
{
return ctx.begin();
}
template <typename FormatContext>
auto format(const DB::StorageID & storage_id, FormatContext & ctx)
{
return fmt::format_to(ctx.out(), "{}", storage_id.getNameForLogs());
}
};
}