ClickHouse/dbms/programs/copier/Internals.cpp

146 lines
4.2 KiB
C++
Raw Normal View History

2020-02-19 15:01:08 +00:00
#include "Internals.h"
2020-02-20 09:06:00 +00:00
namespace DB
2020-02-19 20:50:27 +00:00
{
2020-02-25 18:10:48 +00:00
namespace ErrorCodes
{
extern const int BAD_ARGUMENTS;
}
2020-02-19 15:01:08 +00:00
2020-02-19 15:59:47 +00:00
ConfigurationPtr getConfigurationFromXMLString(const std::string & xml_data)
{
2020-02-19 15:01:08 +00:00
std::stringstream ss(xml_data);
Poco::XML::InputSource input_source{ss};
return {new Poco::Util::XMLConfiguration{&input_source}};
}
2020-02-19 15:59:47 +00:00
String getQuotedTable(const String & database, const String & table)
{
if (database.empty())
2020-02-19 15:01:08 +00:00
return backQuoteIfNeed(table);
return backQuoteIfNeed(database) + "." + backQuoteIfNeed(table);
}
2020-02-19 15:59:47 +00:00
String getQuotedTable(const DatabaseAndTableName & db_and_table)
{
2020-02-19 15:01:08 +00:00
return getQuotedTable(db_and_table.first, db_and_table.second);
}
// Creates AST representing 'ENGINE = Distributed(cluster, db, table, [sharding_key])
std::shared_ptr<ASTStorage> createASTStorageDistributed(
2020-02-19 15:45:49 +00:00
const String & cluster_name, const String & database, const String & table,
2020-02-19 15:59:47 +00:00
const ASTPtr & sharding_key_ast)
{
2020-02-19 15:01:08 +00:00
auto args = std::make_shared<ASTExpressionList>();
args->children.emplace_back(std::make_shared<ASTLiteral>(cluster_name));
args->children.emplace_back(std::make_shared<ASTIdentifier>(database));
args->children.emplace_back(std::make_shared<ASTIdentifier>(table));
if (sharding_key_ast)
args->children.emplace_back(sharding_key_ast);
auto engine = std::make_shared<ASTFunction>();
engine->name = "Distributed";
engine->arguments = args;
auto storage = std::make_shared<ASTStorage>();
storage->set(storage->engine, engine);
return storage;
}
2020-02-19 15:59:47 +00:00
BlockInputStreamPtr squashStreamIntoOneBlock(const BlockInputStreamPtr & stream)
{
2020-02-19 15:01:08 +00:00
return std::make_shared<SquashingBlockInputStream>(
stream,
std::numeric_limits<size_t>::max(),
std::numeric_limits<size_t>::max());
}
2020-02-19 15:59:47 +00:00
Block getBlockWithAllStreamData(const BlockInputStreamPtr & stream)
{
2020-02-19 15:01:08 +00:00
return squashStreamIntoOneBlock(stream)->read();
}
2020-02-19 15:59:47 +00:00
bool isExtendedDefinitionStorage(const ASTPtr & storage_ast)
{
2020-02-19 15:45:49 +00:00
const auto & storage = storage_ast->as<ASTStorage &>();
2020-02-19 15:01:08 +00:00
return storage.partition_by || storage.order_by || storage.sample_by;
}
2020-02-19 15:59:47 +00:00
ASTPtr extractPartitionKey(const ASTPtr & storage_ast)
{
2020-02-19 15:01:08 +00:00
String storage_str = queryToString(storage_ast);
2020-02-19 15:45:49 +00:00
const auto & storage = storage_ast->as<ASTStorage &>();
const auto & engine = storage.engine->as<ASTFunction &>();
2020-02-19 15:01:08 +00:00
2020-02-19 15:59:47 +00:00
if (!endsWith(engine.name, "MergeTree"))
{
2020-02-19 15:01:08 +00:00
throw Exception(
"Unsupported engine was specified in " + storage_str + ", only *MergeTree engines are supported",
ErrorCodes::BAD_ARGUMENTS);
}
2020-02-19 15:59:47 +00:00
if (isExtendedDefinitionStorage(storage_ast))
{
2020-02-19 15:01:08 +00:00
if (storage.partition_by)
return storage.partition_by->clone();
2020-02-19 15:45:49 +00:00
static const char * all = "all";
2020-02-19 15:01:08 +00:00
return std::make_shared<ASTLiteral>(Field(all, strlen(all)));
2020-02-19 15:59:47 +00:00
}
else
{
2020-02-19 15:01:08 +00:00
bool is_replicated = startsWith(engine.name, "Replicated");
size_t min_args = is_replicated ? 3 : 1;
if (!engine.arguments)
throw Exception("Expected arguments in " + storage_str, ErrorCodes::BAD_ARGUMENTS);
ASTPtr arguments_ast = engine.arguments->clone();
2020-02-19 15:45:49 +00:00
ASTs & arguments = arguments_ast->children;
2020-02-19 15:01:08 +00:00
if (arguments.size() < min_args)
throw Exception("Expected at least " + toString(min_args) + " arguments in " + storage_str,
ErrorCodes::BAD_ARGUMENTS);
2020-02-19 15:45:49 +00:00
ASTPtr & month_arg = is_replicated ? arguments[2] : arguments[1];
2020-02-19 15:01:08 +00:00
return makeASTFunction("toYYYYMM", month_arg->clone());
}
}
2020-02-19 15:59:47 +00:00
ShardPriority getReplicasPriority(const Cluster::Addresses & replicas, const std::string & local_hostname, UInt8 random)
{
2020-02-19 15:01:08 +00:00
ShardPriority res;
if (replicas.empty())
return res;
res.is_remote = 1;
for (auto & replica : replicas)
{
if (isLocalAddress(DNSResolver::instance().resolveHost(replica.host_name)))
{
res.is_remote = 0;
break;
}
}
res.hostname_difference = std::numeric_limits<size_t>::max();
for (auto & replica : replicas)
{
size_t difference = getHostNameDifference(local_hostname, replica.host_name);
res.hostname_difference = std::min(difference, res.hostname_difference);
}
res.random = random;
return res;
}
}