mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-18 12:22:12 +00:00
a1b0dede07
* made index parser * added index parsing * some fixes * added index interface and factory * fixed compilation * ptrs * added indexParts * indextypes * index condition * IndexCondition * added indexes in selectexecutor * fix * changed comment * fix * added granularity * comments * fix * fix * added writing indexes * removed indexpart class * fix * added setSkipIndexes * add rw for MergeTreeIndexes * fixes * upd error * fix * fix * reading * test index * fixed nullptr error * fixed * fix * unique names * asts -> exprlist * minmax index * fix * fixed select * fixed merging * fixed mutation * working minmax * removed test index * fixed style * added indexes to checkDataPart * added tests for minmax index * fixed constructor * fix style * fixed includes * fixed setSkipIndexes * added indexes meta to zookeeper * added parsing * removed throw * alter cmds parse * fix * added alter * fix * alters fix * fix alters * fix "after" * fixed alter * alter fix + test * fixes * upd setSkipIndexes * fixed alter bug with drop all indices * fix metadata editing * new test and repl fix * rm test files * fixed repl alter * fix * fix * indices * MTReadStream * upd test for bug * fix * added useful parsers and ast classes * fix * fix comments * replaced columns * fix * fixed parsing * fixed printing * fix err * basic IndicesDescription * go to IndicesDescr * moved indices * go to indicesDescr * fix test minmax_index* * fixed MT alter * fixed bug with replMT indices storing in zk * rename * refactoring * docs ru * docs ru * docs en * refactor * rename tests * fix docs * refactoring * fix * fix * fix * fixed style * unique idx * unique * fix * better minmax calculation * upd * added getBlock * unique_condition * added termForAST * unique * fixed not * uniqueCondition::mayBeTrueOnGranule * fix * fixed bug with double column * is always true * fix * key set * spaces * test * tests * fix * unique * fix * fix * fixed bug with duplicate column * removed unused data * fix * fixes * __bitSwapLastTwo * fix
174 lines
4.9 KiB
C++
174 lines
4.9 KiB
C++
#include <sstream>
|
|
|
|
#include <Common/typeid_cast.h>
|
|
#include <Parsers/parseQuery.h>
|
|
#include <Parsers/ParserCreateQuery.h>
|
|
#include <Parsers/ASTCreateQuery.h>
|
|
#include <Parsers/formatAST.h>
|
|
#include <Interpreters/Context.h>
|
|
#include <Interpreters/InterpreterCreateQuery.h>
|
|
#include <Storages/StorageFactory.h>
|
|
#include <Databases/DatabasesCommon.h>
|
|
|
|
|
|
namespace DB
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
{
|
|
extern const int EMPTY_LIST_OF_COLUMNS_PASSED;
|
|
extern const int TABLE_ALREADY_EXISTS;
|
|
extern const int UNKNOWN_TABLE;
|
|
extern const int LOGICAL_ERROR;
|
|
}
|
|
|
|
|
|
String getTableDefinitionFromCreateQuery(const ASTPtr & query)
|
|
{
|
|
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.as_database.clear();
|
|
create.as_table.clear();
|
|
create.if_not_exists = false;
|
|
create.is_populate = false;
|
|
|
|
/// 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)
|
|
create.select = nullptr;
|
|
|
|
create.format = nullptr;
|
|
create.out_file = nullptr;
|
|
|
|
std::ostringstream statement_stream;
|
|
formatAST(create, statement_stream, false);
|
|
statement_stream << '\n';
|
|
return statement_stream.str();
|
|
}
|
|
|
|
|
|
std::pair<String, StoragePtr> createTableFromDefinition(
|
|
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)
|
|
{
|
|
ParserCreateQuery parser;
|
|
ASTPtr ast = parseQuery(parser, definition.data(), definition.data() + definition.size(), description_for_error_message, 0);
|
|
|
|
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.
|
|
if (!ast_create_query.columns_list || !ast_create_query.columns_list->columns)
|
|
throw Exception("Missing definition of columns.", ErrorCodes::EMPTY_LIST_OF_COLUMNS_PASSED);
|
|
|
|
ColumnsDescription columns = InterpreterCreateQuery::getColumnsDescription(*ast_create_query.columns_list->columns, context);
|
|
|
|
return
|
|
{
|
|
ast_create_query.table,
|
|
StorageFactory::instance().get(
|
|
ast_create_query,
|
|
database_data_path, ast_create_query.table, database_name, context, context.getGlobalContext(),
|
|
columns,
|
|
true, has_force_restore_data_flag)
|
|
};
|
|
}
|
|
|
|
|
|
bool DatabaseWithOwnTablesBase::isTableExist(
|
|
const Context & /*context*/,
|
|
const String & table_name) const
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
return tables.find(table_name) != tables.end();
|
|
}
|
|
|
|
StoragePtr DatabaseWithOwnTablesBase::tryGetTable(
|
|
const Context & /*context*/,
|
|
const String & table_name) const
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
auto it = tables.find(table_name);
|
|
if (it == tables.end())
|
|
return {};
|
|
return it->second;
|
|
}
|
|
|
|
DatabaseIteratorPtr DatabaseWithOwnTablesBase::getIterator(const Context & /*context*/)
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
return std::make_unique<DatabaseSnapshotIterator>(tables);
|
|
}
|
|
|
|
bool DatabaseWithOwnTablesBase::empty(const Context & /*context*/) const
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
return tables.empty();
|
|
}
|
|
|
|
StoragePtr DatabaseWithOwnTablesBase::detachTable(const String & table_name)
|
|
{
|
|
StoragePtr res;
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
auto it = tables.find(table_name);
|
|
if (it == tables.end())
|
|
throw Exception("Table " + name + "." + table_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
|
res = it->second;
|
|
tables.erase(it);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void DatabaseWithOwnTablesBase::attachTable(const String & table_name, const StoragePtr & table)
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
if (!tables.emplace(table_name, table).second)
|
|
throw Exception("Table " + name + "." + table_name + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
|
}
|
|
|
|
void DatabaseWithOwnTablesBase::shutdown()
|
|
{
|
|
/// You can not hold a lock during shutdown.
|
|
/// Because inside `shutdown` function tables can work with database, and mutex is not recursive.
|
|
|
|
Tables tables_snapshot;
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
tables_snapshot = tables;
|
|
}
|
|
|
|
for (const auto & kv : tables_snapshot)
|
|
{
|
|
kv.second->shutdown();
|
|
}
|
|
|
|
std::lock_guard lock(mutex);
|
|
tables.clear();
|
|
}
|
|
|
|
DatabaseWithOwnTablesBase::~DatabaseWithOwnTablesBase()
|
|
{
|
|
try
|
|
{
|
|
shutdown();
|
|
}
|
|
catch (...)
|
|
{
|
|
tryLogCurrentException(__PRETTY_FUNCTION__);
|
|
}
|
|
}
|
|
|
|
}
|