aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Interpreters/RequiredSourceColumnsData.cpp
blob: f5004a63dda5a217c6cc30714a219f901dc8803f (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
#include <Common/typeid_cast.h>
#include <Interpreters/RequiredSourceColumnsData.h>
#include <Interpreters/IdentifierSemantic.h>
#include <DataTypes/NestedUtils.h>
#include <Parsers/ASTIdentifier.h>

namespace DB
{

bool RequiredSourceColumnsData::addColumnAliasIfAny(const IAST & ast)
{
    String alias = ast.tryGetAlias();
    if (alias.empty())
        return false;

    if (required_names.contains(alias))
        masked_columns.insert(alias);

    complex_aliases.insert(alias);
    return true;
}

void RequiredSourceColumnsData::addColumnIdentifier(const ASTIdentifier & node)
{
    if (!IdentifierSemantic::getColumnName(node))
        return;

    /// There should be no complex cases after query normalization. Names to aliases: one-to-many.
    String alias = node.tryGetAlias();
    required_names[node.name()].addInclusion(alias);
}

bool RequiredSourceColumnsData::addArrayJoinAliasIfAny(const IAST & ast)
{
    String alias = ast.tryGetAlias();
    if (alias.empty())
        return false;

    array_join_columns.insert(alias);
    return true;
}

void RequiredSourceColumnsData::addArrayJoinIdentifier(const ASTIdentifier & node)
{
    array_join_columns.insert(node.name());
}

size_t RequiredSourceColumnsData::nameInclusion(const String & name) const
{
    auto it = required_names.find(name);
    if (it != required_names.end())
        return it->second.appears;
    return 0;
}

NameSet RequiredSourceColumnsData::requiredColumns() const
{
    NameSet required;
    for (const auto & pr : required_names)
    {
        const auto & name = pr.first;
        String table_name = Nested::extractTableName(name);

        /// Tech debt. There's its own logic for ARRAY JOIN columns.
        if (array_join_columns.contains(name) || array_join_columns.contains(table_name))
            continue;

        if (!complex_aliases.contains(name) || masked_columns.contains(name))
            required.insert(name);
    }
    return required;
}

std::ostream & operator << (std::ostream & os, const RequiredSourceColumnsData & cols)
{
    os << "required_names: ";
    for (const auto & pr : cols.required_names)
    {
        os << "'" << pr.first << "'";
        for (const auto & alias : pr.second.aliases)
            os << "/'" << alias << "'";
        os << ", ";
    }
    os << "complex_aliases: ";
    for (const auto & x : cols.complex_aliases)
        os << "'" << x << "', ";
    os << "masked_columns: ";
    for (const auto & x : cols.masked_columns)
        os << "'" << x << "', ";
    os << "array_join_columns: ";
    for (const auto & x : cols.array_join_columns)
        os << "'" << x << "', ";
    return os;
}

}