aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Parsers/ASTExplainQuery.h
blob: 701bde8cebdd182bbca77990056c95f386a3abb2 (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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#pragma once

#include <Parsers/ASTQueryWithOutput.h>


namespace DB
{

namespace ErrorCodes
{
    extern const int BAD_ARGUMENTS;
}

/// AST, EXPLAIN or other query with meaning of explanation query instead of execution
class ASTExplainQuery : public ASTQueryWithOutput
{
public:
    enum ExplainKind
    {
        ParsedAST, /// 'EXPLAIN AST SELECT ...'
        AnalyzedSyntax, /// 'EXPLAIN SYNTAX SELECT ...'
        QueryTree, /// 'EXPLAIN QUERY TREE SELECT ...'
        QueryPlan, /// 'EXPLAIN SELECT ...'
        QueryPipeline, /// 'EXPLAIN PIPELINE ...'
        QueryEstimates, /// 'EXPLAIN ESTIMATE ...'
        TableOverride, /// 'EXPLAIN TABLE OVERRIDE ...'
        CurrentTransaction, /// 'EXPLAIN CURRENT TRANSACTION'
    };

    static String toString(ExplainKind kind)
    {
        switch (kind)
        {
            case ParsedAST: return "EXPLAIN AST";
            case AnalyzedSyntax: return "EXPLAIN SYNTAX";
            case QueryTree: return "EXPLAIN QUERY TREE";
            case QueryPlan: return "EXPLAIN";
            case QueryPipeline: return "EXPLAIN PIPELINE";
            case QueryEstimates: return "EXPLAIN ESTIMATE";
            case TableOverride: return "EXPLAIN TABLE OVERRIDE";
            case CurrentTransaction: return "EXPLAIN CURRENT TRANSACTION";
        }

        UNREACHABLE();
    }

    static ExplainKind fromString(const String & str)
    {
        if (str == "EXPLAIN AST")
            return ParsedAST;
        if (str == "EXPLAIN SYNTAX")
            return AnalyzedSyntax;
        if (str == "EXPLAIN QUERY TREE")
            return QueryTree;
        if (str == "EXPLAIN" || str == "EXPLAIN PLAN")
            return QueryPlan;
        if (str == "EXPLAIN PIPELINE")
            return QueryPipeline;
        if (str == "EXPLAIN ESTIMATE")
            return QueryEstimates;
        if (str == "EXPLAIN TABLE OVERRIDE")
            return TableOverride;
        if (str == "EXPLAIN CURRENT TRANSACTION")
            return CurrentTransaction;

        throw Exception(ErrorCodes::BAD_ARGUMENTS, "Unknown explain kind '{}'", str);
    }

    explicit ASTExplainQuery(ExplainKind kind_) : kind(kind_) {}

    String getID(char delim) const override { return "Explain" + (delim + toString(kind)); }
    ExplainKind getKind() const { return kind; }
    ASTPtr clone() const override
    {
        auto res = std::make_shared<ASTExplainQuery>(*this);
        res->children.clear();
        if (!children.empty())
            res->children.push_back(children[0]->clone());
        cloneOutputOptions(*res);
        return res;
    }

    void setExplainKind(ExplainKind kind_) { kind = kind_; }

    void setExplainedQuery(ASTPtr query_)
    {
        children.emplace_back(query_);
        query = std::move(query_);
    }

    void setSettings(ASTPtr settings_)
    {
        children.emplace_back(settings_);
        ast_settings = std::move(settings_);
    }

    void setTableFunction(ASTPtr table_function_)
    {
        children.emplace_back(table_function_);
        table_function = std::move(table_function_);
    }

    void setTableOverride(ASTPtr table_override_)
    {
        children.emplace_back(table_override_);
        table_override = std::move(table_override_);
    }

    const ASTPtr & getExplainedQuery() const { return query; }
    const ASTPtr & getSettings() const { return ast_settings; }
    const ASTPtr & getTableFunction() const { return table_function; }
    const ASTPtr & getTableOverride() const { return table_override; }

    QueryKind getQueryKind() const override { return QueryKind::Explain; }

protected:
    void formatQueryImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override
    {
        settings.ostr << (settings.hilite ? hilite_keyword : "") << toString(kind) << (settings.hilite ? hilite_none : "");

        if (ast_settings)
        {
            settings.ostr << ' ';
            ast_settings->formatImpl(settings, state, frame);
        }

        if (query)
        {
            settings.ostr << settings.nl_or_ws;
            query->formatImpl(settings, state, frame);
        }
        if (table_function)
        {
            settings.ostr << settings.nl_or_ws;
            table_function->formatImpl(settings, state, frame);
        }
        if (table_override)
        {
            settings.ostr << settings.nl_or_ws;
            table_override->formatImpl(settings, state, frame);
        }
    }

private:
    ExplainKind kind;

    ASTPtr query;
    ASTPtr ast_settings;

    /// Used by EXPLAIN TABLE OVERRIDE
    ASTPtr table_function;
    ASTPtr table_override;
};

}