mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-03 13:02:00 +00:00
CH local: Treat localhost:port as a remote database
This commit is contained in:
parent
60ca9990e5
commit
383c982715
@ -193,7 +193,17 @@ ClusterPtr DatabaseReplicated::getClusterImpl() const
|
||||
UInt16 default_port = getContext()->getTCPPort();
|
||||
bool secure = db_settings.cluster_secure_connection;
|
||||
|
||||
return std::make_shared<Cluster>(getContext()->getSettingsRef(), shards, username, password, default_port, false, secure);
|
||||
bool treat_local_as_remote = false;
|
||||
bool treat_local_port_as_remote = getContext()->getApplicationType() == Context::ApplicationType::LOCAL;
|
||||
return std::make_shared<Cluster>(
|
||||
getContext()->getSettingsRef(),
|
||||
shards,
|
||||
username,
|
||||
password,
|
||||
default_port,
|
||||
treat_local_as_remote,
|
||||
treat_local_port_as_remote,
|
||||
secure);
|
||||
}
|
||||
|
||||
void DatabaseReplicated::tryConnectToZooKeeperAndInitDatabase(bool force_attach)
|
||||
|
@ -127,13 +127,16 @@ ColumnPtr FunctionHasColumnInTable::executeImpl(const ColumnsWithTypeAndName & a
|
||||
{
|
||||
std::vector<std::vector<String>> host_names = {{ host_name }};
|
||||
|
||||
bool treat_local_as_remote = false;
|
||||
bool treat_local_port_as_remote = getContext()->getApplicationType() == Context::ApplicationType::LOCAL;
|
||||
auto cluster = std::make_shared<Cluster>(
|
||||
getContext()->getSettings(),
|
||||
host_names,
|
||||
!user_name.empty() ? user_name : "default",
|
||||
password,
|
||||
getContext()->getTCPPort(),
|
||||
false);
|
||||
treat_local_as_remote,
|
||||
treat_local_port_as_remote);
|
||||
|
||||
// FIXME this (probably) needs a non-constant access to query context,
|
||||
// because it might initialized a storage. Ideally, the tables required
|
||||
|
@ -115,23 +115,44 @@ Cluster::Address::Address(
|
||||
|
||||
|
||||
Cluster::Address::Address(
|
||||
const String & host_port_,
|
||||
const String & user_,
|
||||
const String & password_,
|
||||
UInt16 clickhouse_port,
|
||||
bool secure_,
|
||||
Int64 priority_,
|
||||
UInt32 shard_index_,
|
||||
UInt32 replica_index_)
|
||||
: user(user_)
|
||||
, password(password_)
|
||||
const String & host_port_,
|
||||
const String & user_,
|
||||
const String & password_,
|
||||
UInt16 clickhouse_port,
|
||||
bool treat_local_port_as_remote,
|
||||
bool secure_,
|
||||
Int64 priority_,
|
||||
UInt32 shard_index_,
|
||||
UInt32 replica_index_)
|
||||
: user(user_), password(password_)
|
||||
{
|
||||
auto parsed_host_port = parseAddress(host_port_, clickhouse_port);
|
||||
bool can_be_local = true;
|
||||
std::pair<std::string, UInt16> parsed_host_port;
|
||||
if (!treat_local_port_as_remote)
|
||||
{
|
||||
parsed_host_port = parseAddress(host_port_, clickhouse_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// For clickhouse-local (treat_local_port_as_remote) try to read the address without passing a default port
|
||||
/// If it works we have a full address that includes a port, which means it won't be local
|
||||
/// since clickhouse-local doesn't listen in any port
|
||||
/// If it doesn't include a port then use the default one and it could be local (if the address is)
|
||||
try
|
||||
{
|
||||
parsed_host_port = parseAddress(host_port_, 0);
|
||||
can_be_local = false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
parsed_host_port = parseAddress(host_port_, clickhouse_port);
|
||||
}
|
||||
}
|
||||
host_name = parsed_host_port.first;
|
||||
port = parsed_host_port.second;
|
||||
secure = secure_ ? Protocol::Secure::Enable : Protocol::Secure::Disable;
|
||||
priority = priority_;
|
||||
is_local = isLocal(clickhouse_port);
|
||||
is_local = can_be_local && isLocal(clickhouse_port);
|
||||
shard_index = shard_index_;
|
||||
replica_index = replica_index_;
|
||||
}
|
||||
@ -482,9 +503,16 @@ Cluster::Cluster(const Poco::Util::AbstractConfiguration & config,
|
||||
}
|
||||
|
||||
|
||||
Cluster::Cluster(const Settings & settings, const std::vector<std::vector<String>> & names,
|
||||
const String & username, const String & password, UInt16 clickhouse_port, bool treat_local_as_remote,
|
||||
bool secure, Int64 priority)
|
||||
Cluster::Cluster(
|
||||
const Settings & settings,
|
||||
const std::vector<std::vector<String>> & names,
|
||||
const String & username,
|
||||
const String & password,
|
||||
UInt16 clickhouse_port,
|
||||
bool treat_local_as_remote,
|
||||
bool treat_local_port_as_remote,
|
||||
bool secure,
|
||||
Int64 priority)
|
||||
{
|
||||
UInt32 current_shard_num = 1;
|
||||
|
||||
@ -492,7 +520,16 @@ Cluster::Cluster(const Settings & settings, const std::vector<std::vector<String
|
||||
{
|
||||
Addresses current;
|
||||
for (const auto & replica : shard)
|
||||
current.emplace_back(replica, username, password, clickhouse_port, secure, priority, current_shard_num, current.size() + 1);
|
||||
current.emplace_back(
|
||||
replica,
|
||||
username,
|
||||
password,
|
||||
clickhouse_port,
|
||||
treat_local_port_as_remote,
|
||||
secure,
|
||||
priority,
|
||||
current_shard_num,
|
||||
current.size() + 1);
|
||||
|
||||
addresses_with_failover.emplace_back(current);
|
||||
|
||||
|
@ -39,14 +39,21 @@ public:
|
||||
|
||||
/// Construct a cluster by the names of shards and replicas.
|
||||
/// Local are treated as well as remote ones if treat_local_as_remote is true.
|
||||
/// Local are also treated as remote if treat_local_port_as_remote is set and the local address includes a port
|
||||
/// 'clickhouse_port' - port that this server instance listen for queries.
|
||||
/// This parameter is needed only to check that some address is local (points to ourself).
|
||||
///
|
||||
/// Used for remote() function.
|
||||
Cluster(const Settings & settings, const std::vector<std::vector<String>> & names,
|
||||
const String & username, const String & password,
|
||||
UInt16 clickhouse_port, bool treat_local_as_remote,
|
||||
bool secure = false, Int64 priority = 1);
|
||||
Cluster(
|
||||
const Settings & settings,
|
||||
const std::vector<std::vector<String>> & names,
|
||||
const String & username,
|
||||
const String & password,
|
||||
UInt16 clickhouse_port,
|
||||
bool treat_local_as_remote,
|
||||
bool treat_local_port_as_remote,
|
||||
bool secure = false,
|
||||
Int64 priority = 1);
|
||||
|
||||
Cluster(const Cluster &)= delete;
|
||||
Cluster & operator=(const Cluster &) = delete;
|
||||
@ -115,6 +122,7 @@ public:
|
||||
const String & user_,
|
||||
const String & password_,
|
||||
UInt16 clickhouse_port,
|
||||
bool treat_local_port_as_remote,
|
||||
bool secure_ = false,
|
||||
Int64 priority_ = 1,
|
||||
UInt32 shard_index_ = 0,
|
||||
|
@ -192,13 +192,16 @@ void TableFunctionRemote::parseArguments(const ASTPtr & ast_function, ContextPtr
|
||||
}
|
||||
}
|
||||
|
||||
bool treat_local_as_remote = false;
|
||||
bool treat_local_port_as_remote = context->getApplicationType() == Context::ApplicationType::LOCAL;
|
||||
cluster = std::make_shared<Cluster>(
|
||||
context->getSettings(),
|
||||
names,
|
||||
username,
|
||||
password,
|
||||
(secure ? (maybe_secure_port ? *maybe_secure_port : DBMS_DEFAULT_SECURE_PORT) : context->getTCPPort()),
|
||||
false,
|
||||
treat_local_as_remote,
|
||||
treat_local_port_as_remote,
|
||||
secure);
|
||||
}
|
||||
|
||||
|
@ -9,5 +9,3 @@
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
|
@ -25,7 +25,3 @@ $CLICKHOUSE_CLIENT -q "SELECT * FROM remote('${CLICKHOUSE_HOST}:${CLICKHOUSE_POR
|
||||
$CLICKHOUSE_CLIENT -q "SELECT * FROM remote(test_shard_localhost, system, one);"
|
||||
$CLICKHOUSE_CLIENT -q "SELECT * FROM remote(test_shard_localhost, system, one, 'default', '');"
|
||||
$CLICKHOUSE_CLIENT -q "SELECT * FROM cluster('test_shard_localhost', system, one);"
|
||||
|
||||
# Actually tcp_port is not used because we query localhost and it is done without IPC into clickhouse-local itself.
|
||||
$CLICKHOUSE_LOCAL --query "SELECT count() FROM remote('127.0.0.1', system.one)"
|
||||
$CLICKHOUSE_LOCAL --query "SELECT count() FROM remote('127.0.0.1', system.one)" -- --tcp_port=59000
|
||||
|
@ -0,0 +1,8 @@
|
||||
Code:81.
|
||||
"test2",0
|
||||
"test2",1
|
||||
"test2",2
|
||||
Code:81.
|
||||
"test4",0
|
||||
"test4",1
|
||||
"test4",2
|
34
tests/queries/0_stateless/01949_clickhouse_local_with_remote_localhost.sh
Executable file
34
tests/queries/0_stateless/01949_clickhouse_local_with_remote_localhost.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CUR_DIR"/../shell_config.sh
|
||||
|
||||
|
||||
${CLICKHOUSE_CLIENT} --query "CREATE TABLE ${CLICKHOUSE_DATABASE}.remote_table (a Int64) ENGINE=TinyLog AS SELECT * FROM system.numbers limit 10;"
|
||||
|
||||
if [ "$CLICKHOUSE_HOST" == "localhost" ]; then
|
||||
# Connecting to 127.0.0.1 will connect to clickhouse-local itself, where the table doesn't exist
|
||||
${CLICKHOUSE_LOCAL} -q "SELECT 'test1', * FROM remote('127.0.0.1', '${CLICKHOUSE_DATABASE}.remote_table') LIMIT 3;" 2>&1 | awk '{print $1 $2}'
|
||||
|
||||
# Now connecting to 127.0.0.1:9000 will connect to the database we are running tests against
|
||||
${CLICKHOUSE_LOCAL} -q "SELECT 'test2', * FROM remote('127.0.0.1:${CLICKHOUSE_PORT_TCP}', '${CLICKHOUSE_DATABASE}.remote_table') LIMIT 3 FORMAT CSV;"
|
||||
|
||||
# Same test now against localhost
|
||||
${CLICKHOUSE_LOCAL} -q "SELECT 'test3', * FROM remote('localhost', '${CLICKHOUSE_DATABASE}.remote_table') LIMIT 3;" 2>&1 | awk '{print $1 $2}'
|
||||
|
||||
${CLICKHOUSE_LOCAL} -q "SELECT 'test4', * FROM remote('localhost:${CLICKHOUSE_PORT_TCP}', '${CLICKHOUSE_DATABASE}.remote_table') LIMIT 3 FORMAT CSV;"
|
||||
else
|
||||
# Can't test without localhost
|
||||
echo Code:81.
|
||||
echo \"test2\",0
|
||||
echo \"test2\",1
|
||||
echo \"test2\",2
|
||||
echo Code:81.
|
||||
echo \"test4\",0
|
||||
echo \"test4\",1
|
||||
echo \"test4\",2
|
||||
fi
|
||||
|
||||
|
||||
${CLICKHOUSE_CLIENT} --query "DROP TABLE ${CLICKHOUSE_DATABASE}.remote_table;"
|
Loading…
Reference in New Issue
Block a user