diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index f15d066f8cf2c18eaafdbbf552d02b59b9d1003b..feeefd71a111b5c1413bdc5e1b8e2b72a60fe904 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -430,6 +430,7 @@ namespace ErrorCodes extern const int MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES = 453; extern const int OPENSSL_ERROR = 454; extern const int SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY = 455; + extern const int UNKNOWN_QUERY_PARAMETER = 456; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index ac950a6e626338a6091a0f169bc7a00bd0a6f714..7853e0c0841feeaf9c548899a99f752ce2fc604c 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -41,10 +41,10 @@ #include #include -#include - #include + #include +#include namespace DB @@ -278,19 +278,25 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(const ASTExpres /// add column to postprocessing if there is a default_expression specified if (col_decl.default_expression) { - /** for columns with explicitly-specified type create two expressions: - * 1. default_expression aliased as column name with _tmp suffix - * 2. conversion of expression (1) to explicitly-specified type alias as column name */ + /** For columns with explicitly-specified type create two expressions: + * 1. default_expression aliased as column name with _tmp suffix + * 2. conversion of expression (1) to explicitly-specified type alias as column name + */ if (col_decl.type) { const auto & final_column_name = col_decl.name; const auto tmp_column_name = final_column_name + "_tmp"; const auto data_type_ptr = column_names_and_types.back().type.get(); - default_expr_list->children.emplace_back(setAlias( - makeASTFunction("CAST", std::make_shared(tmp_column_name), - std::make_shared(data_type_ptr->getName())), final_column_name)); - default_expr_list->children.emplace_back(setAlias(col_decl.default_expression->clone(), tmp_column_name)); + + default_expr_list->children.emplace_back( + setAlias(addTypeConversionToAST(std::make_shared(tmp_column_name), data_type_ptr->getName()), + final_column_name)); + + default_expr_list->children.emplace_back( + setAlias( + col_decl.default_expression->clone(), + tmp_column_name)); } else default_expr_list->children.emplace_back(setAlias(col_decl.default_expression->clone(), col_decl.name)); @@ -329,7 +335,7 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(const ASTExpres column.type = name_type_it->type; if (!column.type->equals(*deduced_type)) - default_expr = makeASTFunction("CAST", default_expr, std::make_shared(column.type->getName())); + default_expr = addTypeConversionToAST(std::move(default_expr), column.type->getName()); } else column.type = defaults_sample_block.getByName(column.name).type; diff --git a/dbms/src/Interpreters/QueryNormalizer.cpp b/dbms/src/Interpreters/QueryNormalizer.cpp index 1573202a946b281b0d7761ff5431e4bbf451049c..c35c47179c6fa4f5e0a9b93f47cfc6cc88850e6a 100644 --- a/dbms/src/Interpreters/QueryNormalizer.cpp +++ b/dbms/src/Interpreters/QueryNormalizer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ namespace ErrorCodes { extern const int TOO_DEEP_AST; extern const int CYCLIC_ALIASES; + extern const int UNKNOWN_QUERY_PARAMETER; } @@ -227,14 +229,16 @@ void QueryNormalizer::visit(ASTPtr & ast, Data & data) data.current_alias = my_alias; } - if (auto * node = ast->as()) - visit(*node, ast, data); - if (auto * node = ast->as()) - visit(*node, ast, data); - if (auto * node = ast->as()) - visit(*node, ast, data); - if (auto * node = ast->as()) - visit(*node, ast, data); + if (auto * node_func = ast->as()) + visit(*node_func, ast, data); + else if (auto * node_id = ast->as()) + visit(*node_id, ast, data); + else if (auto * node_tables = ast->as()) + visit(*node_tables, ast, data); + else if (auto * node_select = ast->as()) + visit(*node_select, ast, data); + else if (auto * node_param = ast->as()) + throw Exception("Query parameter " + backQuote(node_param->name) + " was not set", ErrorCodes::UNKNOWN_QUERY_PARAMETER); /// If we replace the root of the subtree, we will be called again for the new root, in case the alias is replaced by an alias. if (ast.get() != initial_ast.get()) diff --git a/dbms/src/Interpreters/addTypeConversionToAST.cpp b/dbms/src/Interpreters/addTypeConversionToAST.cpp index 6640af0ca0df71b541c42ff083c5708032c0bb21..699c3bd27c34bf94929b9ee9118afcdd99ccc72d 100644 --- a/dbms/src/Interpreters/addTypeConversionToAST.cpp +++ b/dbms/src/Interpreters/addTypeConversionToAST.cpp @@ -11,23 +11,16 @@ namespace DB ASTPtr addTypeConversionToAST(ASTPtr && ast, const String & type_name) { - auto func = std::make_shared(); - ASTPtr res = func; + auto func = makeASTFunction("CAST", ast, std::make_shared(type_name)); - if (ASTWithAlias * ast_with_alias = ast->as()) + if (ASTWithAlias * ast_with_alias = dynamic_cast(ast.get())) { func->alias = ast_with_alias->alias; func->prefer_alias_to_column_name = ast_with_alias->prefer_alias_to_column_name; ast_with_alias->alias.clear(); } - func->name = "CAST"; - auto exp_list = std::make_shared(); - func->arguments = exp_list; - func->children.push_back(func->arguments); - exp_list->children.emplace_back(std::move(ast)); - exp_list->children.emplace_back(std::make_shared(type_name)); - return res; + return func; } } diff --git a/dbms/src/Parsers/ASTColumnDeclaration.cpp b/dbms/src/Parsers/ASTColumnDeclaration.cpp index 892be19c6b50f9b255c60ec60700d3da199c8e7f..e718d5c292d45c9e28e200820c90ce0068353f23 100644 --- a/dbms/src/Parsers/ASTColumnDeclaration.cpp +++ b/dbms/src/Parsers/ASTColumnDeclaration.cpp @@ -21,18 +21,18 @@ ASTPtr ASTColumnDeclaration::clone() const res->children.push_back(res->default_expression); } - if (codec) - { - res->codec = codec->clone(); - res->children.push_back(res->codec); - } - if (comment) { res->comment = comment->clone(); res->children.push_back(res->comment); } + if (codec) + { + res->codec = codec->clone(); + res->children.push_back(res->codec); + } + if (ttl) { res->ttl = ttl->clone(); diff --git a/dbms/src/Parsers/ASTColumnDeclaration.h b/dbms/src/Parsers/ASTColumnDeclaration.h index 311ceb4efbc2f42bb29a5f4daa71482eca951910..ad23e0669bcdfbdb2c2a745b15684d6f2f3b9018 100644 --- a/dbms/src/Parsers/ASTColumnDeclaration.h +++ b/dbms/src/Parsers/ASTColumnDeclaration.h @@ -15,8 +15,8 @@ public: ASTPtr type; String default_specifier; ASTPtr default_expression; - ASTPtr codec; ASTPtr comment; + ASTPtr codec; ASTPtr ttl; String getID(char delim) const override { return "ColumnDeclaration" + (delim + name); }