This commit is contained in:
Michael Kolupaev 2014-07-10 15:13:45 +04:00
parent 3288bd5765
commit ff64aeb036
4 changed files with 58 additions and 41 deletions

View File

@ -21,6 +21,11 @@ public:
* (для случая выполнения запроса из существующего файла с метаданными). * (для случая выполнения запроса из существующего файла с метаданными).
*/ */
StoragePtr execute(bool assume_metadata_exists = false); StoragePtr execute(bool assume_metadata_exists = false);
/** AST в список столбцов с типами и обратно. Столбцы типа Nested развернуты в список настоящих столбцов.
*/
static NamesAndTypesList parseColumns(ASTPtr expression_list, const DataTypeFactory & data_type_factory);
static ASTPtr formatColumns(const NamesAndTypesList & columns);
private: private:
ASTPtr query_ptr; ASTPtr query_ptr;

View File

@ -141,7 +141,7 @@ void InterpreterAlterQuery::addColumnToAST(StoragePtr table, ASTs & columns, con
{ {
if (!typeid_cast<DataTypeArray *>(datatype.get())) if (!typeid_cast<DataTypeArray *>(datatype.get()))
{ {
throw Exception("Cannot add column " + add_column.name + ". Because it is not an array. Only arrays could be nested and consist '.' in their names"); throw Exception("Cannot add column " + add_column.name + ". Because it is not an array. Only arrays could be nested and contain '.' in their names");
} }
} }

View File

@ -20,6 +20,7 @@
#include <DB/Interpreters/InterpreterSelectQuery.h> #include <DB/Interpreters/InterpreterSelectQuery.h>
#include <DB/Interpreters/InterpreterCreateQuery.h> #include <DB/Interpreters/InterpreterCreateQuery.h>
#include <DB/DataTypes/DataTypeNested.h>
namespace DB namespace DB
@ -114,15 +115,7 @@ StoragePtr InterpreterCreateQuery::execute(bool assume_metadata_exists)
/// Получаем список столбцов /// Получаем список столбцов
if (create.columns) if (create.columns)
{ {
ASTExpressionList & columns_list = typeid_cast<ASTExpressionList &>(*create.columns); columns = new NamesAndTypesList(parseColumns(create.columns, context.getDataTypeFactory()));
for (ASTs::iterator it = columns_list.children.begin(); it != columns_list.children.end(); ++it)
{
ASTNameTypePair & name_and_type_pair = typeid_cast<ASTNameTypePair &>(**it);
StringRange type_range = name_and_type_pair.type->range;
columns->push_back(NameAndTypePair(
name_and_type_pair.name,
context.getDataTypeFactory().get(String(type_range.first, type_range.second - type_range.first))));
}
} }
else if (!create.as_table.empty()) else if (!create.as_table.empty())
columns = new NamesAndTypesList(as_storage->getColumnsList()); columns = new NamesAndTypesList(as_storage->getColumnsList());
@ -135,34 +128,13 @@ StoragePtr InterpreterCreateQuery::execute(bool assume_metadata_exists)
else else
throw Exception("Incorrect CREATE query: required list of column descriptions or AS section or SELECT.", ErrorCodes::INCORRECT_QUERY); throw Exception("Incorrect CREATE query: required list of column descriptions or AS section or SELECT.", ErrorCodes::INCORRECT_QUERY);
/// Дополняем запрос списком столбцов из другой таблицы, если его не было. /// Даже если в запросе был список столбцов, на всякий случай приведем его к стандартному виду (развернем Nested).
if (!create.columns) ASTPtr new_columns = formatColumns(*columns);
{ if (create.columns)
ASTPtr columns_list_ptr = new ASTExpressionList; *std::find(create.children.begin(), create.children.end(), create.columns) = new_columns;
ASTExpressionList & columns_list = typeid_cast<ASTExpressionList &>(*columns_list_ptr); else
create.children.push_back(new_columns);
for (NamesAndTypesList::const_iterator it = columns->begin(); it != columns->end(); ++it) create.columns = new_columns;
{
ASTPtr name_and_type_pair_ptr = new ASTNameTypePair;
ASTNameTypePair & name_and_type_pair = typeid_cast<ASTNameTypePair &>(*name_and_type_pair_ptr);
name_and_type_pair.name = it->name;
StringPtr type_name = new String(it->type->getName());
ParserIdentifierWithOptionalParameters storage_p;
Expected expected = "";
const char * pos = type_name->data();
const char * end = pos + type_name->size();
if (!storage_p.parse(pos, end, name_and_type_pair.type, expected))
throw Exception("Cannot parse data type.", ErrorCodes::SYNTAX_ERROR);
name_and_type_pair.type->query_string = type_name;
columns_list.children.push_back(name_and_type_pair_ptr);
}
create.columns = columns_list_ptr;
create.children.push_back(create.columns);
}
/// Выбор нужного движка таблицы /// Выбор нужного движка таблицы
if (create.storage) if (create.storage)
@ -238,7 +210,6 @@ StoragePtr InterpreterCreateQuery::execute(bool assume_metadata_exists)
if (create.is_temporary) if (create.is_temporary)
{ {
// res->is_dropped = true;
context.getSessionContext().addExternalTable(table_name, res); context.getSessionContext().addExternalTable(table_name, res);
} }
else else
@ -255,4 +226,47 @@ StoragePtr InterpreterCreateQuery::execute(bool assume_metadata_exists)
return res; return res;
} }
NamesAndTypesList InterpreterCreateQuery::parseColumns(ASTPtr expression_list, const DataTypeFactory & data_type_factory)
{
NamesAndTypesList columns;
ASTExpressionList & columns_list = typeid_cast<ASTExpressionList &>(*expression_list);
for (const ASTPtr & ast : columns_list.children)
{
const ASTNameTypePair & name_and_type_pair = typeid_cast<const ASTNameTypePair &>(*ast);
StringRange type_range = name_and_type_pair.type->range;
columns.push_back(NameAndTypePair(
name_and_type_pair.name,
data_type_factory.get(String(type_range.first, type_range.second - type_range.first))));
}
columns = *DataTypeNested::expandNestedColumns(columns);
return columns;
}
ASTPtr InterpreterCreateQuery::formatColumns(const NamesAndTypesList & columns)
{
ASTPtr columns_list_ptr = new ASTExpressionList;
ASTExpressionList & columns_list = typeid_cast<ASTExpressionList &>(*columns_list_ptr);
for (const NameAndTypePair & it : columns)
{
ASTPtr name_and_type_pair_ptr = new ASTNameTypePair;
ASTNameTypePair & name_and_type_pair = typeid_cast<ASTNameTypePair &>(*name_and_type_pair_ptr);
name_and_type_pair.name = it.name;
StringPtr type_name = new String(it.type->getName());
ParserIdentifierWithOptionalParameters storage_p;
Expected expected = "";
const char * pos = type_name->data();
const char * end = pos + type_name->size();
if (!storage_p.parse(pos, end, name_and_type_pair.type, expected))
throw Exception("Cannot parse data type.", ErrorCodes::SYNTAX_ERROR);
name_and_type_pair.type->query_string = type_name;
columns_list.children.push_back(name_and_type_pair_ptr);
}
return columns_list_ptr;
}
} }

View File

@ -75,8 +75,6 @@ StoragePtr StorageFactory::get(
NamesAndTypesListPtr columns, NamesAndTypesListPtr columns,
bool attach) const bool attach) const
{ {
columns = DataTypeNested::expandNestedColumns(*columns);
if (name == "Log") if (name == "Log")
{ {
return StorageLog::create(data_path, table_name, columns, context.getSettings().max_compress_block_size); return StorageLog::create(data_path, table_name, columns, context.getSettings().max_compress_block_size);