1#include <IO/WriteBufferFromOStream.h>
2#include <IO/WriteBufferFromString.h>
3#include <IO/WriteHelpers.h>
4#include <IO/Operators.h>
5#include <Common/SipHash.h>
6#include <Parsers/IAST.h>
7
8
9namespace DB
10{
11
12namespace ErrorCodes
13{
14 extern const int TOO_BIG_AST;
15 extern const int TOO_DEEP_AST;
16 extern const int BAD_ARGUMENTS;
17}
18
19
20const char * IAST::hilite_keyword = "\033[1m";
21const char * IAST::hilite_identifier = "\033[0;36m";
22const char * IAST::hilite_function = "\033[0;33m";
23const char * IAST::hilite_operator = "\033[1;33m";
24const char * IAST::hilite_alias = "\033[0;32m";
25const char * IAST::hilite_substitution = "\033[1;36m";
26const char * IAST::hilite_none = "\033[0m";
27
28
29size_t IAST::size() const
30{
31 size_t res = 1;
32 for (const auto & child : children)
33 res += child->size();
34
35 return res;
36}
37
38size_t IAST::checkSize(size_t max_size) const
39{
40 size_t res = 1;
41 for (const auto & child : children)
42 res += child->checkSize(max_size);
43
44 if (res > max_size)
45 throw Exception("AST is too big. Maximum: " + toString(max_size), ErrorCodes::TOO_BIG_AST);
46
47 return res;
48}
49
50
51IAST::Hash IAST::getTreeHash() const
52{
53 SipHash hash_state;
54 updateTreeHash(hash_state);
55 IAST::Hash res;
56 hash_state.get128(res.first, res.second);
57 return res;
58}
59
60
61void IAST::updateTreeHash(SipHash & hash_state) const
62{
63 updateTreeHashImpl(hash_state);
64 hash_state.update(children.size());
65 for (const auto & child : children)
66 child->updateTreeHash(hash_state);
67}
68
69
70void IAST::updateTreeHashImpl(SipHash & hash_state) const
71{
72 auto id = getID();
73 hash_state.update(id.data(), id.size());
74}
75
76
77size_t IAST::checkDepthImpl(size_t max_depth, size_t level) const
78{
79 size_t res = level + 1;
80 for (const auto & child : children)
81 {
82 if (level >= max_depth)
83 throw Exception("AST is too deep. Maximum: " + toString(max_depth), ErrorCodes::TOO_DEEP_AST);
84 res = std::max(res, child->checkDepthImpl(max_depth, level + 1));
85 }
86
87 return res;
88}
89
90
91void IAST::cloneChildren()
92{
93 for (auto & child : children)
94 child = child->clone();
95}
96
97
98String IAST::getColumnName() const
99{
100 WriteBufferFromOwnString write_buffer;
101 appendColumnName(write_buffer);
102 return write_buffer.str();
103}
104
105
106void IAST::FormatSettings::writeIdentifier(const String & name) const
107{
108 WriteBufferFromOStream out(ostr, 32);
109
110 switch (identifier_quoting_style)
111 {
112 case IdentifierQuotingStyle::None:
113 {
114 if (always_quote_identifiers)
115 throw Exception("Incompatible arguments: always_quote_identifiers = true && identifier_quoting_style == IdentifierQuotingStyle::None",
116 ErrorCodes::BAD_ARGUMENTS);
117 writeString(name, out);
118 break;
119 }
120 case IdentifierQuotingStyle::Backticks:
121 {
122 if (always_quote_identifiers)
123 writeBackQuotedString(name, out);
124 else
125 writeProbablyBackQuotedString(name, out);
126 break;
127 }
128 case IdentifierQuotingStyle::DoubleQuotes:
129 {
130 if (always_quote_identifiers)
131 writeDoubleQuotedString(name, out);
132 else
133 writeProbablyDoubleQuotedString(name, out);
134 break;
135 }
136 case IdentifierQuotingStyle::BackticksMySQL:
137 {
138 if (always_quote_identifiers)
139 writeBackQuotedStringMySQL(name, out);
140 else
141 writeProbablyBackQuotedStringMySQL(name, out);
142 break;
143 }
144 }
145
146 out.next();
147}
148
149}
150