2017-05-23 18:33:48 +00:00
|
|
|
#include <sstream>
|
|
|
|
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Parsers/parseQuery.h>
|
|
|
|
#include <Parsers/ParserCreateQuery.h>
|
|
|
|
#include <Parsers/ASTCreateQuery.h>
|
|
|
|
#include <Parsers/formatAST.h>
|
2017-05-23 18:33:48 +00:00
|
|
|
#include <Interpreters/Context.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Interpreters/InterpreterCreateQuery.h>
|
|
|
|
#include <Storages/StorageFactory.h>
|
|
|
|
#include <Databases/DatabasesCommon.h>
|
2016-03-26 03:03:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2017-10-27 21:18:06 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int EMPTY_LIST_OF_COLUMNS_PASSED;
|
|
|
|
}
|
|
|
|
|
2016-03-26 03:03:50 +00:00
|
|
|
|
|
|
|
String getTableDefinitionFromCreateQuery(const ASTPtr & query)
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
ASTPtr query_clone = query->clone();
|
|
|
|
ASTCreateQuery & create = typeid_cast<ASTCreateQuery &>(*query_clone.get());
|
|
|
|
|
|
|
|
/// We remove everything that is not needed for ATTACH from the query.
|
|
|
|
create.attach = true;
|
|
|
|
create.database.clear();
|
|
|
|
create.if_not_exists = false;
|
|
|
|
create.is_populate = false;
|
|
|
|
|
2017-10-25 19:52:32 +00:00
|
|
|
/// For views it is necessary to save the SELECT query itself, for the rest - on the contrary
|
|
|
|
if (!create.is_view && !create.is_materialized_view)
|
2017-04-01 07:20:54 +00:00
|
|
|
create.select = nullptr;
|
|
|
|
|
2017-10-21 20:08:49 +00:00
|
|
|
/// For "MATERIALIZED VIEW x TO y" it's necessary to save destination table
|
2017-10-27 21:18:06 +00:00
|
|
|
if (!(create.is_materialized_view && !create.storage))
|
2017-10-21 20:08:49 +00:00
|
|
|
{
|
|
|
|
create.as_database.clear();
|
|
|
|
create.as_table.clear();
|
|
|
|
}
|
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
std::ostringstream statement_stream;
|
|
|
|
formatAST(create, statement_stream, 0, false);
|
|
|
|
statement_stream << '\n';
|
|
|
|
return statement_stream.str();
|
2016-03-26 03:03:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::pair<String, StoragePtr> createTableFromDefinition(
|
2017-04-01 07:20:54 +00:00
|
|
|
const String & definition,
|
|
|
|
const String & database_name,
|
|
|
|
const String & database_data_path,
|
|
|
|
Context & context,
|
|
|
|
bool has_force_restore_data_flag,
|
|
|
|
const String & description_for_error_message)
|
2016-03-26 03:03:50 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
ParserCreateQuery parser;
|
|
|
|
ASTPtr ast = parseQuery(parser, definition.data(), definition.data() + definition.size(), description_for_error_message);
|
|
|
|
|
|
|
|
ASTCreateQuery & ast_create_query = typeid_cast<ASTCreateQuery &>(*ast);
|
|
|
|
ast_create_query.attach = true;
|
|
|
|
ast_create_query.database = database_name;
|
|
|
|
|
|
|
|
/// We do not directly use `InterpreterCreateQuery::execute`, because
|
|
|
|
/// - the database has not been created yet;
|
|
|
|
/// - the code is simpler, since the query is already brought to a suitable form.
|
2017-10-21 20:08:49 +00:00
|
|
|
if (!ast_create_query.columns)
|
2017-10-25 00:55:31 +00:00
|
|
|
throw Exception("Missing definition of columns.", ErrorCodes::EMPTY_LIST_OF_COLUMNS_PASSED);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2017-09-17 18:49:43 +00:00
|
|
|
InterpreterCreateQuery::ColumnsInfo columns_info = InterpreterCreateQuery::getColumnsInfo(*ast_create_query.columns, context);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
|
|
return
|
|
|
|
{
|
|
|
|
ast_create_query.table,
|
|
|
|
StorageFactory::instance().get(
|
2017-10-25 19:52:32 +00:00
|
|
|
ast_create_query,
|
|
|
|
database_data_path, ast_create_query.table, database_name, context, context.getGlobalContext(),
|
|
|
|
columns_info.columns, columns_info.materialized_columns, columns_info.alias_columns, columns_info.column_defaults,
|
2017-04-01 07:20:54 +00:00
|
|
|
true, has_force_restore_data_flag)
|
|
|
|
};
|
2016-03-26 03:03:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|