| 1 | #include <Parsers/ASTCreateQuery.h> |
| 2 | #include <Parsers/ASTExpressionList.h> |
| 3 | #include <Parsers/ASTFunction.h> |
| 4 | #include <Parsers/ASTSelectWithUnionQuery.h> |
| 5 | #include <Parsers/ASTSetQuery.h> |
| 6 | #include <Common/quoteString.h> |
| 7 | |
| 8 | |
| 9 | namespace DB |
| 10 | { |
| 11 | |
| 12 | ASTPtr ASTStorage::clone() const |
| 13 | { |
| 14 | auto res = std::make_shared<ASTStorage>(*this); |
| 15 | res->children.clear(); |
| 16 | |
| 17 | if (engine) |
| 18 | res->set(res->engine, engine->clone()); |
| 19 | if (partition_by) |
| 20 | res->set(res->partition_by, partition_by->clone()); |
| 21 | if (primary_key) |
| 22 | res->set(res->primary_key, primary_key->clone()); |
| 23 | if (order_by) |
| 24 | res->set(res->order_by, order_by->clone()); |
| 25 | if (sample_by) |
| 26 | res->set(res->sample_by, sample_by->clone()); |
| 27 | if (ttl_table) |
| 28 | res->set(res->ttl_table, ttl_table->clone()); |
| 29 | |
| 30 | if (settings) |
| 31 | res->set(res->settings, settings->clone()); |
| 32 | |
| 33 | return res; |
| 34 | } |
| 35 | |
| 36 | void ASTStorage::formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const |
| 37 | { |
| 38 | if (engine) |
| 39 | { |
| 40 | s.ostr << (s.hilite ? hilite_keyword : "" ) << s.nl_or_ws << "ENGINE" << (s.hilite ? hilite_none : "" ) << " = " ; |
| 41 | engine->formatImpl(s, state, frame); |
| 42 | } |
| 43 | if (partition_by) |
| 44 | { |
| 45 | s.ostr << (s.hilite ? hilite_keyword : "" ) << s.nl_or_ws << "PARTITION BY " << (s.hilite ? hilite_none : "" ); |
| 46 | partition_by->formatImpl(s, state, frame); |
| 47 | } |
| 48 | if (primary_key) |
| 49 | { |
| 50 | s.ostr << (s.hilite ? hilite_keyword : "" ) << s.nl_or_ws << "PRIMARY KEY " << (s.hilite ? hilite_none : "" ); |
| 51 | primary_key->formatImpl(s, state, frame); |
| 52 | } |
| 53 | if (order_by) |
| 54 | { |
| 55 | s.ostr << (s.hilite ? hilite_keyword : "" ) << s.nl_or_ws << "ORDER BY " << (s.hilite ? hilite_none : "" ); |
| 56 | order_by->formatImpl(s, state, frame); |
| 57 | } |
| 58 | if (sample_by) |
| 59 | { |
| 60 | s.ostr << (s.hilite ? hilite_keyword : "" ) << s.nl_or_ws << "SAMPLE BY " << (s.hilite ? hilite_none : "" ); |
| 61 | sample_by->formatImpl(s, state, frame); |
| 62 | } |
| 63 | if (ttl_table) |
| 64 | { |
| 65 | s.ostr << (s.hilite ? hilite_keyword : "" ) << s.nl_or_ws << "TTL " << (s.hilite ? hilite_none : "" ); |
| 66 | ttl_table->formatImpl(s, state, frame); |
| 67 | } |
| 68 | if (settings) |
| 69 | { |
| 70 | s.ostr << (s.hilite ? hilite_keyword : "" ) << s.nl_or_ws << "SETTINGS " << (s.hilite ? hilite_none : "" ); |
| 71 | settings->formatImpl(s, state, frame); |
| 72 | } |
| 73 | |
| 74 | } |
| 75 | |
| 76 | |
| 77 | class ASTColumnsElement : public IAST |
| 78 | { |
| 79 | public: |
| 80 | String prefix; |
| 81 | IAST * elem; |
| 82 | |
| 83 | String getID(char c) const override { return "ASTColumnsElement for " + elem->getID(c); } |
| 84 | |
| 85 | ASTPtr clone() const override; |
| 86 | |
| 87 | void formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const override; |
| 88 | }; |
| 89 | |
| 90 | ASTPtr ASTColumnsElement::clone() const |
| 91 | { |
| 92 | auto res = std::make_shared<ASTColumnsElement>(); |
| 93 | res->prefix = prefix; |
| 94 | if (elem) |
| 95 | res->set(res->elem, elem->clone()); |
| 96 | return res; |
| 97 | } |
| 98 | |
| 99 | void ASTColumnsElement::formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const |
| 100 | { |
| 101 | if (!elem) |
| 102 | return; |
| 103 | |
| 104 | if (prefix.empty()) |
| 105 | { |
| 106 | elem->formatImpl(s, state, frame); |
| 107 | return; |
| 108 | } |
| 109 | |
| 110 | frame.need_parens = false; |
| 111 | std::string indent_str = s.one_line ? "" : std::string(4 * frame.indent, ' '); |
| 112 | |
| 113 | s.ostr << s.nl_or_ws << indent_str; |
| 114 | s.ostr << (s.hilite ? hilite_keyword : "" ) << prefix << (s.hilite ? hilite_none : "" ); |
| 115 | |
| 116 | FormatSettings nested_settings = s; |
| 117 | nested_settings.one_line = true; |
| 118 | nested_settings.nl_or_ws = ' '; |
| 119 | |
| 120 | elem->formatImpl(nested_settings, state, frame); |
| 121 | } |
| 122 | |
| 123 | |
| 124 | ASTPtr ASTColumns::clone() const |
| 125 | { |
| 126 | auto res = std::make_shared<ASTColumns>(); |
| 127 | |
| 128 | if (columns) |
| 129 | res->set(res->columns, columns->clone()); |
| 130 | if (indices) |
| 131 | res->set(res->indices, indices->clone()); |
| 132 | if (constraints) |
| 133 | res->set(res->constraints, constraints->clone()); |
| 134 | |
| 135 | return res; |
| 136 | } |
| 137 | |
| 138 | void ASTColumns::formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const |
| 139 | { |
| 140 | ASTExpressionList list; |
| 141 | |
| 142 | if (columns) |
| 143 | { |
| 144 | for (const auto & column : columns->children) |
| 145 | { |
| 146 | auto elem = std::make_shared<ASTColumnsElement>(); |
| 147 | elem->prefix = "" ; |
| 148 | elem->set(elem->elem, column->clone()); |
| 149 | list.children.push_back(elem); |
| 150 | } |
| 151 | } |
| 152 | if (indices) |
| 153 | { |
| 154 | for (const auto & index : indices->children) |
| 155 | { |
| 156 | auto elem = std::make_shared<ASTColumnsElement>(); |
| 157 | elem->prefix = "INDEX" ; |
| 158 | elem->set(elem->elem, index->clone()); |
| 159 | list.children.push_back(elem); |
| 160 | } |
| 161 | } |
| 162 | if (constraints) |
| 163 | { |
| 164 | for (const auto & constraint : constraints->children) |
| 165 | { |
| 166 | auto elem = std::make_shared<ASTColumnsElement>(); |
| 167 | elem->prefix = "CONSTRAINT" ; |
| 168 | elem->set(elem->elem, constraint->clone()); |
| 169 | list.children.push_back(elem); |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | if (!list.children.empty()) |
| 174 | list.formatImpl(s, state, frame); |
| 175 | } |
| 176 | |
| 177 | |
| 178 | ASTPtr ASTCreateQuery::clone() const |
| 179 | { |
| 180 | auto res = std::make_shared<ASTCreateQuery>(*this); |
| 181 | res->children.clear(); |
| 182 | |
| 183 | if (columns_list) |
| 184 | res->set(res->columns_list, columns_list->clone()); |
| 185 | if (storage) |
| 186 | res->set(res->storage, storage->clone()); |
| 187 | if (select) |
| 188 | res->set(res->select, select->clone()); |
| 189 | if (tables) |
| 190 | res->set(res->tables, tables->clone()); |
| 191 | if (dictionary) |
| 192 | res->set(res->dictionary, dictionary->clone()); |
| 193 | |
| 194 | cloneOutputOptions(*res); |
| 195 | |
| 196 | return res; |
| 197 | } |
| 198 | |
| 199 | void ASTCreateQuery::formatQueryImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
| 200 | { |
| 201 | frame.need_parens = false; |
| 202 | |
| 203 | if (!database.empty() && table.empty()) |
| 204 | { |
| 205 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) |
| 206 | << (attach ? "ATTACH DATABASE " : "CREATE DATABASE " ) |
| 207 | << (if_not_exists ? "IF NOT EXISTS " : "" ) |
| 208 | << (settings.hilite ? hilite_none : "" ) |
| 209 | << backQuoteIfNeed(database); |
| 210 | formatOnCluster(settings); |
| 211 | |
| 212 | if (storage) |
| 213 | storage->formatImpl(settings, state, frame); |
| 214 | |
| 215 | return; |
| 216 | } |
| 217 | |
| 218 | if (!is_dictionary) |
| 219 | { |
| 220 | std::string what = "TABLE" ; |
| 221 | if (is_view) |
| 222 | what = "VIEW" ; |
| 223 | if (is_materialized_view) |
| 224 | what = "MATERIALIZED VIEW" ; |
| 225 | if (is_live_view) |
| 226 | what = "LIVE VIEW" ; |
| 227 | |
| 228 | settings.ostr |
| 229 | << (settings.hilite ? hilite_keyword : "" ) |
| 230 | << (attach ? "ATTACH " : "CREATE " ) |
| 231 | << (temporary ? "TEMPORARY " : "" ) |
| 232 | << (replace_view ? "OR REPLACE " : "" ) |
| 233 | << what << " " |
| 234 | << (if_not_exists ? "IF NOT EXISTS " : "" ) |
| 235 | << (settings.hilite ? hilite_none : "" ) |
| 236 | << (!database.empty() ? backQuoteIfNeed(database) + "." : "" ) << backQuoteIfNeed(table); |
| 237 | formatOnCluster(settings); |
| 238 | } |
| 239 | else |
| 240 | { |
| 241 | /// Always DICTIONARY |
| 242 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << (attach ? "ATTACH " : "CREATE " ) << "DICTIONARY " |
| 243 | << (if_not_exists ? "IF NOT EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ) |
| 244 | << (!database.empty() ? backQuoteIfNeed(database) + "." : "" ) << backQuoteIfNeed(table); |
| 245 | formatOnCluster(settings); |
| 246 | } |
| 247 | |
| 248 | if (as_table_function) |
| 249 | { |
| 250 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " AS " << (settings.hilite ? hilite_none : "" ); |
| 251 | as_table_function->formatImpl(settings, state, frame); |
| 252 | } |
| 253 | if (!to_table.empty()) |
| 254 | { |
| 255 | settings.ostr |
| 256 | << (settings.hilite ? hilite_keyword : "" ) << " TO " << (settings.hilite ? hilite_none : "" ) |
| 257 | << (!to_database.empty() ? backQuoteIfNeed(to_database) + "." : "" ) << backQuoteIfNeed(to_table); |
| 258 | } |
| 259 | |
| 260 | if (!as_table.empty()) |
| 261 | { |
| 262 | settings.ostr |
| 263 | << (settings.hilite ? hilite_keyword : "" ) << " AS " << (settings.hilite ? hilite_none : "" ) |
| 264 | << (!as_database.empty() ? backQuoteIfNeed(as_database) + "." : "" ) << backQuoteIfNeed(as_table); |
| 265 | } |
| 266 | |
| 267 | if (columns_list) |
| 268 | { |
| 269 | settings.ostr << (settings.one_line ? " (" : "\n(" ); |
| 270 | FormatStateStacked frame_nested = frame; |
| 271 | ++frame_nested.indent; |
| 272 | columns_list->formatImpl(settings, state, frame_nested); |
| 273 | settings.ostr << (settings.one_line ? ")" : "\n)" ); |
| 274 | } |
| 275 | |
| 276 | if (dictionary_attributes_list) |
| 277 | { |
| 278 | settings.ostr << (settings.one_line ? " (" : "\n(" ); |
| 279 | FormatStateStacked frame_nested = frame; |
| 280 | ++frame_nested.indent; |
| 281 | dictionary_attributes_list->formatImpl(settings, state, frame_nested); |
| 282 | settings.ostr << (settings.one_line ? ")" : "\n)" ); |
| 283 | } |
| 284 | |
| 285 | if (storage) |
| 286 | storage->formatImpl(settings, state, frame); |
| 287 | |
| 288 | if (dictionary) |
| 289 | dictionary->formatImpl(settings, state, frame); |
| 290 | |
| 291 | if (is_populate) |
| 292 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " POPULATE" << (settings.hilite ? hilite_none : "" ); |
| 293 | |
| 294 | if (select) |
| 295 | { |
| 296 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " AS" << settings.nl_or_ws << (settings.hilite ? hilite_none : "" ); |
| 297 | select->formatImpl(settings, state, frame); |
| 298 | } |
| 299 | |
| 300 | if (tables) |
| 301 | { |
| 302 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " WITH " << (settings.hilite ? hilite_none : "" ); |
| 303 | tables->formatImpl(settings, state, frame); |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | } |
| 308 | |