aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Interpreters/StorageID.cpp
blob: b3a504d7ef43061ca00caac481bbf425df1ed0d8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <Interpreters/StorageID.h>
#include <Parsers/ASTQueryWithTableAndOutput.h>
#include <Parsers/ASTIdentifier.h>
#include <Common/quoteString.h>
#include <IO/WriteHelpers.h>
#include <IO/ReadHelpers.h>
#include <Interpreters/DatabaseAndTableWithAlias.h>
#include <Poco/Util/AbstractConfiguration.h>

namespace DB
{

namespace ErrorCodes
{
    extern const int LOGICAL_ERROR;
    extern const int UNKNOWN_DATABASE;
}

StorageID::StorageID(const ASTQueryWithTableAndOutput & query)
{
    database_name = query.getDatabase();
    table_name = query.getTable();
    uuid = query.uuid;
    assertNotEmpty();
}

StorageID::StorageID(const ASTTableIdentifier & table_identifier_node)
{
    DatabaseAndTableWithAlias database_table(table_identifier_node);
    database_name = database_table.database;
    table_name = database_table.table;
    uuid = database_table.uuid;
    assertNotEmpty();
}

StorageID::StorageID(const ASTPtr & node)
{
    if (const auto * identifier = node->as<ASTTableIdentifier>())
        *this = StorageID(*identifier);
    else if (const auto * simple_query = dynamic_cast<const ASTQueryWithTableAndOutput *>(node.get()))
        *this = StorageID(*simple_query);
    else
        throw Exception(ErrorCodes::LOGICAL_ERROR, "Unexpected AST");
}

String StorageID::getTableName() const
{
    assertNotEmpty();
    return table_name;
}

String StorageID::getDatabaseName() const
{
    assertNotEmpty();
    if (database_name.empty())
        throw Exception(ErrorCodes::UNKNOWN_DATABASE, "Database name is empty");
    return database_name;
}

String StorageID::getNameForLogs() const
{
    assertNotEmpty();
    return (database_name.empty() ? "" : backQuoteIfNeed(database_name) + ".") + backQuoteIfNeed(table_name)
           + (hasUUID() ? " (" + toString(uuid) + ")" : "");
}

/// NOTE: This implementation doesn't allow to implement a good "operator <".
/// Because "a != b" must be equivalent to "(a < b) || (b < a)", and we can't make "operator <" to meet that.
bool StorageID::operator==(const StorageID & rhs) const
{
    assertNotEmpty();
    if (hasUUID() && rhs.hasUUID())
        return uuid == rhs.uuid;
    else
        return std::tie(database_name, table_name) == std::tie(rhs.database_name, rhs.table_name);
}

String StorageID::getFullTableName() const
{
    return backQuoteIfNeed(getDatabaseName()) + "." + backQuoteIfNeed(table_name);
}

String StorageID::getFullNameNotQuoted() const
{
    return getDatabaseName() + "." + table_name;
}

StorageID StorageID::fromDictionaryConfig(const Poco::Util::AbstractConfiguration & config,
                                          const String & config_prefix)
{
    StorageID res = StorageID::createEmpty();
    res.database_name = config.getString(config_prefix + ".database", "");
    res.table_name = config.getString(config_prefix + ".name");
    const String uuid_str = config.getString(config_prefix + ".uuid", "");
    if (!uuid_str.empty())
        res.uuid = parseFromString<UUID>(uuid_str);
    return res;
}

String StorageID::getShortName() const
{
    assertNotEmpty();
    if (hasUUID())
        return toString(uuid);
    if (database_name.empty())
        return table_name;
    return database_name + "." + table_name;
}

}