提交 864dacd1 编写于 作者: A Alexey Milovidov

Merging

上级 f98d0a10
......@@ -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;
......
......@@ -41,10 +41,10 @@
#include <Databases/DatabaseFactory.h>
#include <Databases/IDatabase.h>
#include <Common/ZooKeeper/ZooKeeper.h>
#include <Compression/CompressionFactory.h>
#include <Interpreters/InterpreterDropQuery.h>
#include <Interpreters/addTypeConversionToAST.h>
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<ASTIdentifier>(tmp_column_name),
std::make_shared<ASTLiteral>(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<ASTIdentifier>(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<ASTLiteral>(column.type->getName()));
default_expr = addTypeConversionToAST(std::move(default_expr), column.type->getName());
}
else
column.type = defaults_sample_block.getByName(column.name).type;
......
......@@ -8,6 +8,7 @@
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTQueryParameter.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Common/StringUtils/StringUtils.h>
#include <Common/typeid_cast.h>
......@@ -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<ASTFunction>())
visit(*node, ast, data);
if (auto * node = ast->as<ASTIdentifier>())
visit(*node, ast, data);
if (auto * node = ast->as<ASTTablesInSelectQueryElement>())
visit(*node, ast, data);
if (auto * node = ast->as<ASTSelectQuery>())
visit(*node, ast, data);
if (auto * node_func = ast->as<ASTFunction>())
visit(*node_func, ast, data);
else if (auto * node_id = ast->as<ASTIdentifier>())
visit(*node_id, ast, data);
else if (auto * node_tables = ast->as<ASTTablesInSelectQueryElement>())
visit(*node_tables, ast, data);
else if (auto * node_select = ast->as<ASTSelectQuery>())
visit(*node_select, ast, data);
else if (auto * node_param = ast->as<ASTQueryParameter>())
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())
......
......@@ -11,23 +11,16 @@ namespace DB
ASTPtr addTypeConversionToAST(ASTPtr && ast, const String & type_name)
{
auto func = std::make_shared<ASTFunction>();
ASTPtr res = func;
auto func = makeASTFunction("CAST", ast, std::make_shared<ASTLiteral>(type_name));
if (ASTWithAlias * ast_with_alias = ast->as<ASTWithAlias>())
if (ASTWithAlias * ast_with_alias = dynamic_cast<ASTWithAlias *>(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<ASTExpressionList>();
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<ASTLiteral>(type_name));
return res;
return func;
}
}
......@@ -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();
......
......@@ -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); }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册