提交 d1edd926 编写于 作者: M Michael Kolupaev

Merge

上级 1005bbaa
......@@ -271,9 +271,6 @@ public:
/// Получить запрос на CREATE таблицы.
ASTPtr getCreateQuery(const String & database_name, const String & table_name) const;
/// Получить запрос на CREATE таблицы. Только если он есть на диске. Нужно вызывать при заблокированной структуре таблицы.
ASTPtr readCreateQueryFromDisk(const String & database_name, const String & table_name) const;
/// Для методов ниже может быть необходимо захватывать mutex самостоятельно.
Poco::Mutex & getMutex() const { return shared->mutex; }
......
......@@ -100,7 +100,7 @@ class AlterCommands : public std::vector<AlterCommand>
public:
void apply(NamesAndTypesList & columns) const
{
NamesAndTypesList new_columns;
NamesAndTypesList new_columns = columns;
for (const AlterCommand & command : *this)
command.apply(new_columns);
columns = new_columns;
......
......@@ -305,13 +305,35 @@ void Context::detachDatabase(const String & database_name)
}
ASTPtr Context::readCreateQueryFromDisk(const String & database_name, const String & table_name) const
ASTPtr Context::getCreateQuery(const String & database_name, const String & table_name) const
{
StoragePtr table;
String db;
{
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
db = database_name.empty() ? current_database : database_name;
table = getTable(db, table_name);
}
auto table_lock = table->lockStructure(false);
/// Здесь хранится определение таблицы
String metadata_path = shared->path + "metadata/" + escapeForFileName(database_name) + "/" + escapeForFileName(table_name) + ".sql";
String metadata_path = shared->path + "metadata/" + escapeForFileName(db) + "/" + escapeForFileName(table_name) + ".sql";
if (!Poco::File(metadata_path).exists())
return nullptr;
{
try
{
/// Если файл .sql не предусмотрен (например, для таблиц типа ChunkRef), то движок может сам предоставить запрос CREATE.
return table->getCustomCreateQuery(*this);
}
catch (...)
{
throw Exception("Metadata file " + metadata_path + " for table " + db + "." + table_name + " doesn't exist.",
ErrorCodes::TABLE_METADATA_DOESNT_EXIST);
}
}
StringPtr query = new String();
{
......@@ -336,44 +358,13 @@ ASTPtr Context::readCreateQueryFromDisk(const String & database_name, const Stri
ASTCreateQuery & ast_create_query = typeid_cast<ASTCreateQuery &>(*ast);
ast_create_query.attach = false;
ast_create_query.database = database_name;
ast_create_query.database = db;
ast_create_query.query_string = query;
return ast;
}
ASTPtr Context::getCreateQuery(const String & database_name, const String & table_name) const
{
StoragePtr table;
String db;
{
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
db = database_name.empty() ? current_database : database_name;
table = getTable(db, table_name);
}
auto table_lock = table->lockStructure(false);
ASTPtr res = readCreateQueryFromDisk(db, table_name);
if (res)
return res;
try
{
/// Если файл .sql не предусмотрен (например, для таблиц типа ChunkRef), то движок может сам предоставить запрос CREATE.
return table->getCustomCreateQuery(*this);
}
catch (...)
{
throw Exception("Metadata file for table " + db + "." + table_name + " doesn't exist.",
ErrorCodes::TABLE_METADATA_DOESNT_EXIST);
}
}
Settings Context::getSettings() const
{
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
......
......@@ -97,16 +97,37 @@ void InterpreterAlterQuery::updateMetadata(
String metadata_path = path + "metadata/" + database_name_escaped + "/" + table_name_escaped + ".sql";
String metadata_temp_path = metadata_path + ".tmp";
ASTPtr attach_ptr = context.readCreateQueryFromDisk(database_name, table_name);
ASTCreateQuery & attach = typeid_cast<ASTCreateQuery &>(*attach_ptr);
attach.attach = true;
StringPtr query = new String();
{
ReadBufferFromFile in(metadata_path);
WriteBufferFromString out(*query);
copyData(in, out);
}
const char * begin = query->data();
const char * end = begin + query->size();
const char * pos = begin;
ParserCreateQuery parser;
ASTPtr ast;
Expected expected = "";
bool parse_res = parser.parse(pos, end, ast, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
if (!parse_res || (pos != end && *pos != ';'))
throw Exception(getSyntaxErrorMessage(parse_res, begin, end, pos, expected, "in file " + metadata_path),
DB::ErrorCodes::SYNTAX_ERROR);
ast->query_string = query;
ASTCreateQuery & attach = typeid_cast<ASTCreateQuery &>(*ast);
ASTPtr new_columns = InterpreterCreateQuery::formatColumns(columns);
*std::find(attach.children.begin(), attach.children.end(), attach.columns) = new_columns;
attach.columns = new_columns;
{
Poco::FileOutputStream ostr(metadata_temp_path + ".tmp");
Poco::FileOutputStream ostr(metadata_temp_path);
formatAST(attach, ostr, 0, false);
}
......
......@@ -485,7 +485,7 @@ void MergeTreeData::AlterDataPartTransaction::commit()
}
else
{
Poco::File(path + it.first).renameTo(it.second);
Poco::File(path + it.first).renameTo(path + it.second);
}
}
data_part = nullptr;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册