2012-08-17 19:53:11 +00:00
|
|
|
|
#include <Poco/File.h>
|
2013-12-07 16:51:29 +00:00
|
|
|
|
#include <Poco/Net/NetworkInterface.h>
|
2012-08-17 19:53:11 +00:00
|
|
|
|
|
|
|
|
|
#include <DB/Common/escapeForFileName.h>
|
|
|
|
|
#include <DB/IO/ReadBufferFromFile.h>
|
|
|
|
|
#include <DB/IO/WriteBufferFromString.h>
|
|
|
|
|
#include <DB/IO/copyData.h>
|
|
|
|
|
#include <DB/Parsers/ASTCreateQuery.h>
|
|
|
|
|
#include <DB/Parsers/ParserCreateQuery.h>
|
2012-08-02 17:33:31 +00:00
|
|
|
|
#include <DB/Interpreters/Context.h>
|
2013-12-07 16:51:29 +00:00
|
|
|
|
#include <DB/Client/ConnectionPoolWithFailover.h>
|
2012-08-02 17:33:31 +00:00
|
|
|
|
|
2014-08-22 01:01:28 +00:00
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
String Context::getPath() const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return shared->path;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-07 17:19:23 +00:00
|
|
|
|
String Context::getTemporaryPath() const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return shared->tmp_path;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
|
|
|
|
|
void Context::setPath(const String & path)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
shared->path = path;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-07 17:19:23 +00:00
|
|
|
|
void Context::setTemporaryPath(const String & path)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
shared->tmp_path = path;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
|
2014-02-13 07:17:22 +00:00
|
|
|
|
void Context::setUsersConfig(ConfigurationPtr config)
|
2013-08-10 07:46:45 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
2014-02-13 07:17:22 +00:00
|
|
|
|
shared->users_config = config;
|
|
|
|
|
shared->users.loadFromConfig(*shared->users_config);
|
|
|
|
|
shared->quotas.loadFromConfig(*shared->users_config);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ConfigurationPtr Context::getUsersConfig()
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return shared->users_config;
|
2013-08-10 07:46:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-08-12 00:36:18 +00:00
|
|
|
|
void Context::setUser(const String & name, const String & password, const Poco::Net::IPAddress & address, const String & quota_key)
|
2013-08-10 07:46:45 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
const User & user_props = shared->users.get(name, password, address);
|
|
|
|
|
setSetting("profile", user_props.profile);
|
2013-11-03 00:24:46 +00:00
|
|
|
|
setQuota(user_props.quota, quota_key, name, address);
|
2013-08-10 07:46:45 +00:00
|
|
|
|
|
|
|
|
|
user = name;
|
2013-11-03 05:32:42 +00:00
|
|
|
|
ip_address = address;
|
2013-08-10 07:46:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-11-03 00:24:46 +00:00
|
|
|
|
void Context::setQuota(const String & name, const String & quota_key, const String & user_name, const Poco::Net::IPAddress & address)
|
2013-08-12 00:36:18 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
2014-02-13 07:17:22 +00:00
|
|
|
|
quota = shared->quotas.get(name, quota_key, user_name, address);
|
2013-08-12 00:36:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QuotaForIntervals & Context::getQuota()
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return *quota;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-13 14:39:48 +00:00
|
|
|
|
void Context::addDependency(const DatabaseAndTableName & from, const DatabaseAndTableName & where)
|
2013-11-08 17:43:03 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
shared->view_dependencies[from].insert(where);
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-13 14:39:48 +00:00
|
|
|
|
void Context::removeDependency(const DatabaseAndTableName & from, const DatabaseAndTableName & where)
|
2013-11-08 17:43:03 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
shared->view_dependencies[from].erase(where);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-23 20:32:00 +00:00
|
|
|
|
Dependencies Context::getDependencies(const String & database_name, const String & table_name) const
|
2013-11-08 17:43:03 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
2014-12-23 20:32:00 +00:00
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
ViewDependencies::const_iterator iter = shared->view_dependencies.find(DatabaseAndTableName(db, table_name));
|
2013-11-08 17:43:03 +00:00
|
|
|
|
if (iter == shared->view_dependencies.end())
|
2014-12-23 20:32:00 +00:00
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
return Dependencies(iter->second.begin(), iter->second.end());
|
2013-11-08 17:43:03 +00:00
|
|
|
|
}
|
2013-08-12 00:36:18 +00:00
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
bool Context::isTableExist(const String & database_name, const String & table_name) const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
Databases::const_iterator it;
|
|
|
|
|
return shared->databases.end() != (it = shared->databases.find(db))
|
|
|
|
|
&& it->second.end() != it->second.find(table_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Context::isDatabaseExist(const String & database_name) const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
return shared->databases.end() != shared->databases.find(db);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Context::assertTableExists(const String & database_name, const String & table_name) const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
Databases::const_iterator it;
|
|
|
|
|
if (shared->databases.end() == (it = shared->databases.find(db)))
|
|
|
|
|
throw Exception("Database " + db + " doesn't exist", ErrorCodes::UNKNOWN_DATABASE);
|
|
|
|
|
|
|
|
|
|
if (it->second.end() == it->second.find(table_name))
|
|
|
|
|
throw Exception("Table " + db + "." + table_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Context::assertTableDoesntExist(const String & database_name, const String & table_name) const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
Databases::const_iterator it;
|
|
|
|
|
if (shared->databases.end() != (it = shared->databases.find(db))
|
|
|
|
|
&& it->second.end() != it->second.find(table_name))
|
|
|
|
|
throw Exception("Table " + db + "." + table_name + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Context::assertDatabaseExists(const String & database_name) const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
if (shared->databases.end() == shared->databases.find(db))
|
|
|
|
|
throw Exception("Database " + db + " doesn't exist", ErrorCodes::UNKNOWN_DATABASE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Context::assertDatabaseDoesntExist(const String & database_name) const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
if (shared->databases.end() != shared->databases.find(db))
|
|
|
|
|
throw Exception("Database " + db + " already exists.", ErrorCodes::DATABASE_ALREADY_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-03-13 15:00:06 +00:00
|
|
|
|
Tables Context::getExternalTables() const
|
|
|
|
|
{
|
2014-03-14 15:42:30 +00:00
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
2014-03-13 15:00:06 +00:00
|
|
|
|
Tables res = external_tables;
|
|
|
|
|
if (session_context && session_context != this)
|
|
|
|
|
{
|
|
|
|
|
Tables buf = session_context->getExternalTables();
|
|
|
|
|
res.insert(buf.begin(), buf.end());
|
|
|
|
|
}
|
|
|
|
|
else if (global_context && global_context != this)
|
|
|
|
|
{
|
|
|
|
|
Tables buf = global_context->getExternalTables();
|
|
|
|
|
res.insert(buf.begin(), buf.end());
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StoragePtr Context::tryGetExternalTable(const String & table_name) const
|
2014-03-04 15:31:56 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
Tables::const_iterator jt;
|
2014-03-13 15:00:06 +00:00
|
|
|
|
if (external_tables.end() == (jt = external_tables.find(table_name)))
|
2014-03-04 15:31:56 +00:00
|
|
|
|
return StoragePtr();
|
|
|
|
|
|
|
|
|
|
return jt->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
StoragePtr Context::getTable(const String & database_name, const String & table_name) const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
2014-03-04 15:31:56 +00:00
|
|
|
|
Databases::const_iterator it;
|
|
|
|
|
Tables::const_iterator jt;
|
|
|
|
|
|
|
|
|
|
if (database_name.empty())
|
|
|
|
|
{
|
|
|
|
|
StoragePtr res;
|
2014-05-12 00:45:50 +00:00
|
|
|
|
if ((res = tryGetExternalTable(table_name)))
|
2014-03-04 15:31:56 +00:00
|
|
|
|
return res;
|
2014-03-13 15:00:06 +00:00
|
|
|
|
if (session_context && (res = session_context->tryGetExternalTable(table_name)))
|
2014-03-04 15:31:56 +00:00
|
|
|
|
return res;
|
2014-03-13 15:00:06 +00:00
|
|
|
|
if (global_context && (res = global_context->tryGetExternalTable(table_name)))
|
2014-03-04 15:31:56 +00:00
|
|
|
|
return res;
|
|
|
|
|
}
|
2012-08-02 17:33:31 +00:00
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
if (shared->databases.end() == (it = shared->databases.find(db)))
|
|
|
|
|
throw Exception("Database " + db + " doesn't exist", ErrorCodes::UNKNOWN_DATABASE);
|
|
|
|
|
|
|
|
|
|
if (it->second.end() == (jt = it->second.find(table_name)))
|
|
|
|
|
throw Exception("Table " + db + "." + table_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
|
|
|
|
|
|
|
|
|
return jt->second;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-04 15:31:56 +00:00
|
|
|
|
|
2013-05-06 10:31:35 +00:00
|
|
|
|
StoragePtr Context::tryGetTable(const String & database_name, const String & table_name) const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
2014-03-12 13:14:16 +00:00
|
|
|
|
|
2014-03-06 14:02:20 +00:00
|
|
|
|
if (database_name.empty())
|
|
|
|
|
{
|
|
|
|
|
StoragePtr res;
|
2014-05-12 00:45:50 +00:00
|
|
|
|
if ((res = tryGetExternalTable(table_name)))
|
2014-03-06 14:02:20 +00:00
|
|
|
|
return res;
|
2014-03-13 15:00:06 +00:00
|
|
|
|
if (session_context && (res = session_context->tryGetExternalTable(table_name)))
|
2014-03-06 14:02:20 +00:00
|
|
|
|
return res;
|
2014-03-13 15:00:06 +00:00
|
|
|
|
if (global_context && (res = global_context->tryGetExternalTable(table_name)))
|
2014-03-06 14:02:20 +00:00
|
|
|
|
return res;
|
|
|
|
|
}
|
2013-05-06 10:31:35 +00:00
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2013-05-06 10:31:35 +00:00
|
|
|
|
Databases::const_iterator it;
|
|
|
|
|
if (shared->databases.end() == (it = shared->databases.find(db)))
|
|
|
|
|
return StoragePtr();
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2013-05-06 10:31:35 +00:00
|
|
|
|
Tables::const_iterator jt;
|
|
|
|
|
if (it->second.end() == (jt = it->second.find(table_name)))
|
|
|
|
|
return StoragePtr();
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2013-05-06 10:31:35 +00:00
|
|
|
|
return jt->second;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
|
2014-03-13 15:00:06 +00:00
|
|
|
|
void Context::addExternalTable(const String & table_name, StoragePtr storage)
|
2014-03-04 15:31:56 +00:00
|
|
|
|
{
|
2014-03-13 15:00:06 +00:00
|
|
|
|
if (external_tables.end() != external_tables.find(table_name))
|
2014-03-04 15:31:56 +00:00
|
|
|
|
throw Exception("Temporary table " + table_name + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
2014-03-13 15:00:06 +00:00
|
|
|
|
external_tables[table_name] = storage;
|
2014-03-04 15:31:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
void Context::addTable(const String & database_name, const String & table_name, StoragePtr table)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
2014-03-20 10:59:45 +00:00
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
assertDatabaseExists(db);
|
|
|
|
|
assertTableDoesntExist(db, table_name);
|
|
|
|
|
shared->databases[db][table_name] = table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Context::addDatabase(const String & database_name)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
assertDatabaseDoesntExist(db);
|
|
|
|
|
shared->databases[db];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-09-30 01:29:19 +00:00
|
|
|
|
StoragePtr Context::detachTable(const String & database_name, const String & table_name)
|
2012-08-02 17:33:31 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
assertTableExists(db, table_name);
|
2013-09-30 01:29:19 +00:00
|
|
|
|
Tables::iterator it = shared->databases[db].find(table_name);
|
|
|
|
|
StoragePtr res = it->second;
|
|
|
|
|
shared->databases[db].erase(it);
|
|
|
|
|
return res;
|
2012-08-02 17:33:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Context::detachDatabase(const String & database_name)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
String db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
|
|
|
|
|
assertDatabaseExists(db);
|
2014-03-20 10:59:45 +00:00
|
|
|
|
shared->databases.erase(db);
|
2012-08-02 17:33:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-17 19:53:11 +00:00
|
|
|
|
ASTPtr Context::getCreateQuery(const String & database_name, const String & table_name) const
|
|
|
|
|
{
|
2014-03-20 10:59:45 +00:00
|
|
|
|
StoragePtr table;
|
|
|
|
|
String db;
|
2012-08-17 19:53:11 +00:00
|
|
|
|
|
2014-03-20 10:59:45 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
db = database_name.empty() ? current_database : database_name;
|
|
|
|
|
table = getTable(db, table_name);
|
|
|
|
|
}
|
2012-08-17 19:53:11 +00:00
|
|
|
|
|
2014-03-20 10:59:45 +00:00
|
|
|
|
auto table_lock = table->lockStructure(false);
|
2012-08-17 19:53:11 +00:00
|
|
|
|
|
|
|
|
|
/// Здесь хранится определение таблицы
|
|
|
|
|
String metadata_path = shared->path + "metadata/" + escapeForFileName(db) + "/" + escapeForFileName(table_name) + ".sql";
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2012-08-17 19:53:11 +00:00
|
|
|
|
if (!Poco::File(metadata_path).exists())
|
2013-06-17 07:01:31 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
/// Если файл .sql не предусмотрен (например, для таблиц типа ChunkRef), то движок может сам предоставить запрос CREATE.
|
2014-03-20 10:59:45 +00:00
|
|
|
|
return table->getCustomCreateQuery(*this);
|
2013-06-17 07:01:31 +00:00
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
throw Exception("Metadata file " + metadata_path + " for table " + db + "." + table_name + " doesn't exist.",
|
|
|
|
|
ErrorCodes::TABLE_METADATA_DOESNT_EXIST);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-17 19:53:11 +00:00
|
|
|
|
|
2013-02-11 11:22:15 +00:00
|
|
|
|
StringPtr query = new String();
|
2012-08-17 19:53:11 +00:00
|
|
|
|
{
|
|
|
|
|
ReadBufferFromFile in(metadata_path);
|
2013-02-11 11:22:15 +00:00
|
|
|
|
WriteBufferFromString out(*query);
|
2012-08-17 19:53:11 +00:00
|
|
|
|
copyData(in, out);
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-11 11:22:15 +00:00
|
|
|
|
const char * begin = query->data();
|
|
|
|
|
const char * end = begin + query->size();
|
2012-08-17 19:53:11 +00:00
|
|
|
|
const char * pos = begin;
|
|
|
|
|
|
|
|
|
|
ParserCreateQuery parser;
|
|
|
|
|
ASTPtr ast;
|
2014-06-12 00:48:56 +00:00
|
|
|
|
Expected expected = "";
|
2012-08-17 19:53:11 +00:00
|
|
|
|
bool parse_res = parser.parse(pos, end, ast, expected);
|
|
|
|
|
|
|
|
|
|
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
|
|
|
|
|
if (!parse_res || (pos != end && *pos != ';'))
|
2014-04-13 08:52:50 +00:00
|
|
|
|
throw Exception(getSyntaxErrorMessage(parse_res, begin, end, pos, expected, "in file " + metadata_path),
|
2012-08-17 19:53:11 +00:00
|
|
|
|
DB::ErrorCodes::SYNTAX_ERROR);
|
|
|
|
|
|
2014-06-26 00:58:14 +00:00
|
|
|
|
ASTCreateQuery & ast_create_query = typeid_cast<ASTCreateQuery &>(*ast);
|
2012-08-17 19:53:11 +00:00
|
|
|
|
ast_create_query.attach = false;
|
|
|
|
|
ast_create_query.database = db;
|
2013-02-11 11:22:15 +00:00
|
|
|
|
ast_create_query.query_string = query;
|
2012-08-17 19:53:11 +00:00
|
|
|
|
|
|
|
|
|
return ast;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
Settings Context::getSettings() const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return settings;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-05-05 20:07:11 +00:00
|
|
|
|
Limits Context::getLimits() const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return settings.limits;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
void Context::setSettings(const Settings & settings_)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
settings = settings_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-02 19:03:32 +00:00
|
|
|
|
void Context::setSetting(const String & name, const Field & value)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
2014-02-13 07:17:22 +00:00
|
|
|
|
if (name == "profile")
|
|
|
|
|
settings.setProfile(value.safeGet<String>(), *shared->users_config);
|
|
|
|
|
else
|
|
|
|
|
settings.set(name, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Context::setSetting(const String & name, const std::string & value)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
if (name == "profile")
|
|
|
|
|
settings.setProfile(value, *shared->users_config);
|
|
|
|
|
else
|
|
|
|
|
settings.set(name, value);
|
2012-08-02 19:03:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
String Context::getCurrentDatabase() const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return current_database;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-02-12 17:31:02 +00:00
|
|
|
|
String Context::getCurrentQueryId() const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return current_query_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
void Context::setCurrentDatabase(const String & name)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
assertDatabaseExists(name);
|
|
|
|
|
current_database = name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-02-12 17:31:02 +00:00
|
|
|
|
void Context::setCurrentQueryId(const String & query_id)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
current_query_id = query_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-06-29 18:03:57 +00:00
|
|
|
|
String Context::getDefaultFormat() const
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
return default_format.empty() ? "TabSeparated" : default_format;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Context::setDefaultFormat(const String & name)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
default_format = name;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-11 15:59:01 +00:00
|
|
|
|
const Macros& Context::getMacros() const
|
|
|
|
|
{
|
|
|
|
|
return shared->macros;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Context::setMacros(Macros && macros)
|
|
|
|
|
{
|
|
|
|
|
/// Полагаемся, что это присваивание происходит один раз при старте сервера. Если это не так, нужно использовать мьютекс.
|
|
|
|
|
shared->macros = macros;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-29 18:03:57 +00:00
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
Context & Context::getSessionContext()
|
|
|
|
|
{
|
|
|
|
|
if (!session_context)
|
|
|
|
|
throw Exception("There is no session", ErrorCodes::THERE_IS_NO_SESSION);
|
|
|
|
|
return *session_context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Context & Context::getGlobalContext()
|
|
|
|
|
{
|
|
|
|
|
if (!global_context)
|
|
|
|
|
throw Exception("Logical error: there is no global context", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
return *global_context;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-19 20:15:15 +00:00
|
|
|
|
|
2012-12-21 19:48:47 +00:00
|
|
|
|
const Dictionaries & Context::getDictionaries() const
|
2012-12-19 20:15:15 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2012-12-19 20:15:15 +00:00
|
|
|
|
if (!shared->dictionaries)
|
|
|
|
|
shared->dictionaries = new Dictionaries;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
|
2012-12-19 20:15:15 +00:00
|
|
|
|
return *shared->dictionaries;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-16 14:55:14 +00:00
|
|
|
|
|
|
|
|
|
void Context::setProgressCallback(ProgressCallback callback)
|
|
|
|
|
{
|
|
|
|
|
/// Колбек устанавливается на сессию или на запрос. В сессии одновременно обрабатывается только один запрос. Поэтому блокировка не нужна.
|
|
|
|
|
progress_callback = callback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProgressCallback Context::getProgressCallback() const
|
|
|
|
|
{
|
|
|
|
|
return progress_callback;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-03 20:21:28 +00:00
|
|
|
|
|
2013-11-03 05:32:42 +00:00
|
|
|
|
void Context::setProcessListElement(ProcessList::Element * elem)
|
|
|
|
|
{
|
|
|
|
|
/// Устанавливается на сессию или на запрос. В сессии одновременно обрабатывается только один запрос. Поэтому блокировка не нужна.
|
|
|
|
|
process_list_elem = elem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProcessList::Element * Context::getProcessListElement()
|
|
|
|
|
{
|
|
|
|
|
return process_list_elem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-03-28 14:36:24 +00:00
|
|
|
|
void Context::setUncompressedCache(size_t max_size_in_bytes)
|
2013-09-08 05:53:10 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
if (shared->uncompressed_cache)
|
|
|
|
|
throw Exception("Uncompressed cache has been already created.", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
|
2014-03-28 14:36:24 +00:00
|
|
|
|
shared->uncompressed_cache = new UncompressedCache(max_size_in_bytes);
|
2013-09-08 05:53:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UncompressedCachePtr Context::getUncompressedCache() const
|
|
|
|
|
{
|
|
|
|
|
/// Исходим из допущения, что функция setUncompressedCache, если вызывалась, то раньше. Иначе поставьте mutex.
|
|
|
|
|
return shared->uncompressed_cache;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-11 13:30:42 +00:00
|
|
|
|
void Context::setMarkCache(size_t cache_size_in_bytes)
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
if (shared->mark_cache)
|
|
|
|
|
throw Exception("Uncompressed cache has been already created.", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
|
|
|
|
|
shared->mark_cache = new MarkCache(cache_size_in_bytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MarkCachePtr Context::getMarkCache() const
|
|
|
|
|
{
|
2014-04-05 19:54:00 +00:00
|
|
|
|
/// Исходим из допущения, что функция setMarksCache, если вызывалась, то раньше. Иначе поставьте mutex.
|
2014-02-11 13:30:42 +00:00
|
|
|
|
return shared->mark_cache;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-02 12:30:38 +00:00
|
|
|
|
BackgroundProcessingPool & Context::getBackgroundPool()
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
if (!shared->background_pool)
|
|
|
|
|
shared->background_pool = new BackgroundProcessingPool(settings.background_pool_size);
|
|
|
|
|
return *shared->background_pool;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-05 19:54:00 +00:00
|
|
|
|
void Context::resetCaches() const
|
|
|
|
|
{
|
|
|
|
|
/// Исходим из допущения, что функции setUncompressedCache, setMarkCache, если вызывались, то раньше (при старте сервера). Иначе поставьте mutex.
|
|
|
|
|
|
|
|
|
|
if (shared->uncompressed_cache)
|
|
|
|
|
shared->uncompressed_cache->reset();
|
|
|
|
|
|
|
|
|
|
if (shared->mark_cache)
|
|
|
|
|
shared->mark_cache->reset();
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-13 10:10:26 +00:00
|
|
|
|
void Context::setZooKeeper(zkutil::ZooKeeperPtr zookeeper)
|
2014-03-21 19:17:59 +00:00
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
|
|
|
|
if (shared->zookeeper)
|
|
|
|
|
throw Exception("ZooKeeper client has already been set.", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
|
|
|
|
|
shared->zookeeper = zookeeper;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-13 10:10:26 +00:00
|
|
|
|
zkutil::ZooKeeperPtr Context::getZooKeeper() const
|
2014-03-21 19:17:59 +00:00
|
|
|
|
{
|
2014-04-25 13:55:15 +00:00
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
|
2014-05-13 11:24:04 +00:00
|
|
|
|
if (shared->zookeeper && shared->zookeeper->expired())
|
2014-04-25 13:55:15 +00:00
|
|
|
|
shared->zookeeper = shared->zookeeper->startNewSession();
|
|
|
|
|
|
|
|
|
|
return shared->zookeeper;
|
2014-03-21 19:17:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-11-19 20:40:51 +00:00
|
|
|
|
void Context::setInterserverIOAddress(const String & host, UInt16 port)
|
2014-03-21 19:49:27 +00:00
|
|
|
|
{
|
|
|
|
|
shared->interserver_io_host = host;
|
|
|
|
|
shared->interserver_io_port = port;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-11-19 20:40:51 +00:00
|
|
|
|
std::pair<String, UInt16> Context::getInterserverIOAddress() const
|
2014-03-21 19:49:27 +00:00
|
|
|
|
{
|
2014-11-19 20:40:51 +00:00
|
|
|
|
if (shared->interserver_io_host.empty() || shared->interserver_io_port == 0)
|
|
|
|
|
throw Exception("Parameter 'interserver_http_port' required for replication is not specified in configuration file.",
|
|
|
|
|
ErrorCodes::NO_ELEMENTS_IN_CONFIG);
|
|
|
|
|
|
|
|
|
|
return { shared->interserver_io_host, shared->interserver_io_port };
|
2014-03-21 19:49:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-12-10 17:06:57 +00:00
|
|
|
|
void Context::initClusters()
|
2013-12-07 16:51:29 +00:00
|
|
|
|
{
|
2013-12-10 17:06:57 +00:00
|
|
|
|
Poco::ScopedLock<Poco::Mutex> lock(shared->mutex);
|
|
|
|
|
if (!shared->clusters)
|
|
|
|
|
shared->clusters = new Clusters(settings, shared->data_type_factory);
|
|
|
|
|
}
|
2013-12-07 16:51:29 +00:00
|
|
|
|
|
2013-12-10 17:06:57 +00:00
|
|
|
|
Cluster & Context::getCluster(const std::string & cluster_name)
|
|
|
|
|
{
|
|
|
|
|
if (!shared->clusters)
|
|
|
|
|
throw Poco::Exception("Clusters have not been initialized yet.");
|
|
|
|
|
|
2014-02-22 21:50:27 +00:00
|
|
|
|
Clusters::Impl::iterator it = shared->clusters->impl.find(cluster_name);
|
|
|
|
|
if (it != shared->clusters->impl.end())
|
2013-12-07 16:51:29 +00:00
|
|
|
|
return it->second;
|
|
|
|
|
else
|
|
|
|
|
throw Poco::Exception("Failed to find cluster with name = " + cluster_name);
|
|
|
|
|
}
|
2015-01-10 02:30:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Compiler & Context::getCompiler()
|
|
|
|
|
{
|
|
|
|
|
return shared->compiler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-08-02 17:33:31 +00:00
|
|
|
|
}
|