aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Interpreters/TranslateQualifiedNamesVisitor.h
blob: 73e45fc7ea09eaf52fa4f2c04210cadb39ea699f (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
#pragma once

#include <vector>

#include <Core/Names.h>
#include <Interpreters/DatabaseAndTableWithAlias.h>
#include <Interpreters/InDepthNodeVisitor.h>

namespace DB
{

class ASTIdentifier;
class ASTQualifiedAsterisk;
struct ASTTableJoin;
class ASTSelectQuery;
class ASTExpressionList;
class ASTFunction;

/// Visit one node for names qualification. @sa InDepthNodeVisitor.
class TranslateQualifiedNamesMatcher
{
public:
    using Visitor = InDepthNodeVisitor<TranslateQualifiedNamesMatcher, true>;

    struct Data
    {
        const NameSet source_columns;
        const TablesWithColumns & tables;
        std::unordered_set<String> join_using_columns;
        bool has_columns;

        Data(const NameSet & source_columns_, const TablesWithColumns & tables_, bool has_columns_ = true)
            : source_columns(source_columns_)
            , tables(tables_)
            , has_columns(has_columns_)
        {}

        bool hasColumn(const String & name) const { return source_columns.count(name); }
        bool hasTable() const { return !tables.empty(); }
        bool processAsterisks() const { return hasTable() && has_columns; }
        bool unknownColumn(size_t table_pos, const ASTIdentifier & identifier) const;
        static bool matchColumnName(std::string_view name, const String & column_name, DataTypePtr column_type);
    };

    static void visit(ASTPtr & ast, Data & data);
    static bool needChildVisit(ASTPtr & node, const ASTPtr & child);

private:
    static void visit(ASTIdentifier & identifier, ASTPtr & ast, Data &);
    static void visit(const ASTQualifiedAsterisk & node, const ASTPtr & ast, Data &);
    static void visit(ASTTableJoin & join, const ASTPtr & ast, Data &);
    static void visit(ASTSelectQuery & select, const ASTPtr & ast, Data &);
    static void visit(ASTExpressionList &, const ASTPtr &, Data &);
    static void visit(ASTFunction &, const ASTPtr &, Data &);

    static void extractJoinUsingColumns(ASTPtr ast, Data & data);

};

/// Visits AST for names qualification.
/// It finds columns and translate their names to the normal form. Expand asterisks and qualified asterisks with column names.
using TranslateQualifiedNamesVisitor = TranslateQualifiedNamesMatcher::Visitor;


/// Restore ASTIdentifiers to long form, change table name in case of distributed.
struct RestoreQualifiedNamesMatcher
{
    struct Data
    {
        DatabaseAndTableWithAlias distributed_table;
        DatabaseAndTableWithAlias remote_table;

        void changeTable(ASTIdentifier & identifier) const;
    };

    static bool needChildVisit(ASTPtr & node, const ASTPtr & child);
    static void visit(ASTPtr & ast, Data & data);
    static void visit(ASTIdentifier & identifier, ASTPtr & ast, Data & data);
};

using RestoreQualifiedNamesVisitor = InDepthNodeVisitor<RestoreQualifiedNamesMatcher, true>;

}