mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-03 04:52:10 +00:00
Merge remote-tracking branch 'origin/master' into pr-lost-decimal-conversion
This commit is contained in:
commit
6c451dddcd
@ -261,9 +261,12 @@ function timeout_with_logging() {
|
||||
|
||||
timeout -s TERM --preserve-status "${@}" || exit_code="${?}"
|
||||
|
||||
echo "Checking if it is a timeout. The code 124 will indicate a timeout."
|
||||
if [[ "${exit_code}" -eq "124" ]]
|
||||
then
|
||||
echo "The command 'timeout ${*}' has been killed by timeout"
|
||||
echo "The command 'timeout ${*}' has been killed by timeout."
|
||||
else
|
||||
echo "No, it isn't a timeout."
|
||||
fi
|
||||
|
||||
return $exit_code
|
||||
|
@ -251,9 +251,12 @@ function timeout_with_logging() {
|
||||
|
||||
timeout -s TERM --preserve-status "${@}" || exit_code="${?}"
|
||||
|
||||
echo "Checking if it is a timeout. The code 124 will indicate a timeout."
|
||||
if [[ "${exit_code}" -eq "124" ]]
|
||||
then
|
||||
echo "The command 'timeout ${*}' has been killed by timeout"
|
||||
echo "The command 'timeout ${*}' has been killed by timeout."
|
||||
else
|
||||
echo "No, it isn't a timeout."
|
||||
fi
|
||||
|
||||
return $exit_code
|
||||
|
@ -247,12 +247,22 @@ function run_tests()
|
||||
|
||||
try_run_with_retry 10 clickhouse-client -q "insert into system.zookeeper (name, path, value) values ('auxiliary_zookeeper2', '/test/chroot/', '')"
|
||||
|
||||
TIMEOUT=$((MAX_RUN_TIME - 800 > 8400 ? 8400 : MAX_RUN_TIME - 800))
|
||||
START_TIME=${SECONDS}
|
||||
set +e
|
||||
timeout -k 60m -s TERM --preserve-status 140m clickhouse-test --testname --shard --zookeeper --check-zookeeper-session --hung-check --print-time \
|
||||
--no-drop-if-fail --test-runs "$NUM_TRIES" "${ADDITIONAL_OPTIONS[@]}" 2>&1 \
|
||||
timeout --preserve-status --signal TERM --kill-after 60m ${TIMEOUT}s \
|
||||
clickhouse-test --testname --shard --zookeeper --check-zookeeper-session --hung-check --print-time \
|
||||
--no-drop-if-fail --test-runs "$NUM_TRIES" "${ADDITIONAL_OPTIONS[@]}" 2>&1 \
|
||||
| ts '%Y-%m-%d %H:%M:%S' \
|
||||
| tee -a test_output/test_result.txt
|
||||
set -e
|
||||
DURATION=$((START_TIME - SECONDS))
|
||||
|
||||
echo "Elapsed ${DURATION} seconds."
|
||||
if [[ $DURATION -ge $TIMEOUT ]]
|
||||
then
|
||||
echo "It looks like the command is terminated by the timeout, which is ${TIMEOUT} seconds."
|
||||
fi
|
||||
}
|
||||
|
||||
export -f run_tests
|
||||
@ -264,7 +274,7 @@ if [ "$NUM_TRIES" -gt "1" ]; then
|
||||
# We don't run tests with Ordinary database in PRs, only in master.
|
||||
# So run new/changed tests with Ordinary at least once in flaky check.
|
||||
timeout_with_logging "$TIMEOUT" bash -c 'NUM_TRIES=1; USE_DATABASE_ORDINARY=1; run_tests' \
|
||||
| sed 's/All tests have finished//' | sed 's/No tests were run//' ||:
|
||||
| sed 's/All tests have finished/Redacted: a message about tests finish is deleted/' | sed 's/No tests were run/Redacted: a message about no tests run is deleted/' ||:
|
||||
fi
|
||||
|
||||
timeout_with_logging "$TIMEOUT" bash -c run_tests ||:
|
||||
|
@ -45,9 +45,12 @@ function timeout_with_logging() {
|
||||
|
||||
timeout -s TERM --preserve-status "${@}" || exit_code="${?}"
|
||||
|
||||
echo "Checking if it is a timeout. The code 124 will indicate a timeout."
|
||||
if [[ "${exit_code}" -eq "124" ]]
|
||||
then
|
||||
echo "The command 'timeout ${*}' has been killed by timeout"
|
||||
echo "The command 'timeout ${*}' has been killed by timeout."
|
||||
else
|
||||
echo "No, it isn't a timeout."
|
||||
fi
|
||||
|
||||
return $exit_code
|
||||
|
@ -68,10 +68,13 @@ QueryTreeNodePtr findEqualsFunction(const QueryTreeNodes & nodes)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Checks if the node is combination of isNull and notEquals functions of two the same arguments
|
||||
/// Checks if the node is combination of isNull and notEquals functions of two the same arguments:
|
||||
/// [ (a <> b AND) ] (a IS NULL) AND (b IS NULL)
|
||||
bool matchIsNullOfTwoArgs(const QueryTreeNodes & nodes, QueryTreeNodePtr & lhs, QueryTreeNodePtr & rhs)
|
||||
{
|
||||
QueryTreeNodePtrWithHashSet all_arguments;
|
||||
QueryTreeNodePtrWithHashSet is_null_arguments;
|
||||
|
||||
for (const auto & node : nodes)
|
||||
{
|
||||
const auto * func_node = node->as<FunctionNode>();
|
||||
@ -80,7 +83,11 @@ bool matchIsNullOfTwoArgs(const QueryTreeNodes & nodes, QueryTreeNodePtr & lhs,
|
||||
|
||||
const auto & arguments = func_node->getArguments().getNodes();
|
||||
if (func_node->getFunctionName() == "isNull" && arguments.size() == 1)
|
||||
{
|
||||
all_arguments.insert(QueryTreeNodePtrWithHash(arguments[0]));
|
||||
is_null_arguments.insert(QueryTreeNodePtrWithHash(arguments[0]));
|
||||
}
|
||||
|
||||
else if (func_node->getFunctionName() == "notEquals" && arguments.size() == 2)
|
||||
{
|
||||
if (arguments[0]->isEqual(*arguments[1]))
|
||||
@ -95,7 +102,7 @@ bool matchIsNullOfTwoArgs(const QueryTreeNodes & nodes, QueryTreeNodePtr & lhs,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (all_arguments.size() != 2)
|
||||
if (all_arguments.size() != 2 || is_null_arguments.size() != 2)
|
||||
return false;
|
||||
|
||||
lhs = all_arguments.begin()->node;
|
||||
|
@ -1740,7 +1740,7 @@ QueryAnalyzer::QueryTreeNodesWithNames QueryAnalyzer::resolveQualifiedMatcher(Qu
|
||||
const auto * tuple_data_type = typeid_cast<const DataTypeTuple *>(result_type.get());
|
||||
if (!tuple_data_type)
|
||||
throw Exception(ErrorCodes::UNSUPPORTED_METHOD,
|
||||
"Qualified matcher {} find non compound expression {} with type {}. Expected tuple or array of tuples. In scope {}",
|
||||
"Qualified matcher {} found a non-compound expression {} with type {}. Expected a tuple or an array of tuples. In scope {}",
|
||||
matcher_node->formatASTForErrorMessage(),
|
||||
expression_query_tree_node->formatASTForErrorMessage(),
|
||||
expression_query_tree_node->getResultType()->getName(),
|
||||
|
@ -226,6 +226,9 @@ add_object_library(clickhouse_storages_windowview Storages/WindowView)
|
||||
add_object_library(clickhouse_storages_s3queue Storages/ObjectStorageQueue)
|
||||
add_object_library(clickhouse_storages_materializedview Storages/MaterializedView)
|
||||
add_object_library(clickhouse_client Client)
|
||||
# Always compile this file with the highest possible level of optimizations, even in Debug builds.
|
||||
# https://github.com/ClickHouse/ClickHouse/issues/65745
|
||||
set_source_files_properties(Client/ClientBaseOptimizedParts.cpp PROPERTIES COMPILE_FLAGS "-O3")
|
||||
add_object_library(clickhouse_bridge BridgeHelper)
|
||||
add_object_library(clickhouse_server Server)
|
||||
add_object_library(clickhouse_server_http Server/HTTP)
|
||||
|
@ -108,7 +108,6 @@ namespace ErrorCodes
|
||||
extern const int UNEXPECTED_PACKET_FROM_SERVER;
|
||||
extern const int INVALID_USAGE_OF_INPUT;
|
||||
extern const int CANNOT_SET_SIGNAL_HANDLER;
|
||||
extern const int UNRECOGNIZED_ARGUMENTS;
|
||||
extern const int LOGICAL_ERROR;
|
||||
extern const int CANNOT_OPEN_FILE;
|
||||
extern const int FILE_ALREADY_EXISTS;
|
||||
@ -2848,168 +2847,6 @@ void ClientBase::showClientVersion()
|
||||
output_stream << VERSION_NAME << " " + getName() + " version " << VERSION_STRING << VERSION_OFFICIAL << "." << std::endl;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/// Define transparent hash to we can use
|
||||
/// std::string_view with the containers
|
||||
struct TransparentStringHash
|
||||
{
|
||||
using is_transparent = void;
|
||||
size_t operator()(std::string_view txt) const
|
||||
{
|
||||
return std::hash<std::string_view>{}(txt);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This functor is used to parse command line arguments and replace dashes with underscores,
|
||||
* allowing options to be specified using either dashes or underscores.
|
||||
*/
|
||||
class OptionsAliasParser
|
||||
{
|
||||
public:
|
||||
explicit OptionsAliasParser(const boost::program_options::options_description& options)
|
||||
{
|
||||
options_names.reserve(options.options().size());
|
||||
for (const auto& option : options.options())
|
||||
options_names.insert(option->long_name());
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses arguments by replacing dashes with underscores, and matches the resulting name with known options
|
||||
* Implements boost::program_options::ext_parser logic
|
||||
*/
|
||||
std::pair<std::string, std::string> operator()(const std::string & token) const
|
||||
{
|
||||
if (!token.starts_with("--"))
|
||||
return {};
|
||||
std::string arg = token.substr(2);
|
||||
|
||||
// divide token by '=' to separate key and value if options style=long_allow_adjacent
|
||||
auto pos_eq = arg.find('=');
|
||||
std::string key = arg.substr(0, pos_eq);
|
||||
|
||||
if (options_names.contains(key))
|
||||
// option does not require any changes, because it is already correct
|
||||
return {};
|
||||
|
||||
std::replace(key.begin(), key.end(), '-', '_');
|
||||
if (!options_names.contains(key))
|
||||
// after replacing '-' with '_' argument is still unknown
|
||||
return {};
|
||||
|
||||
std::string value;
|
||||
if (pos_eq != std::string::npos && pos_eq < arg.size())
|
||||
value = arg.substr(pos_eq + 1);
|
||||
|
||||
return {key, value};
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_set<std::string> options_names;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// Enable optimizations even in debug builds because otherwise options parsing becomes extremely slow affecting .sh tests
|
||||
#if defined(__clang__)
|
||||
#pragma clang optimize on
|
||||
#endif
|
||||
void ClientBase::parseAndCheckOptions(OptionsDescription & options_description, po::variables_map & options, Arguments & arguments)
|
||||
{
|
||||
if (allow_repeated_settings)
|
||||
addProgramOptionsAsMultitokens(cmd_settings, options_description.main_description.value());
|
||||
else
|
||||
addProgramOptions(cmd_settings, options_description.main_description.value());
|
||||
|
||||
if (allow_merge_tree_settings)
|
||||
{
|
||||
/// Add merge tree settings manually, because names of some settings
|
||||
/// may clash. Query settings have higher priority and we just
|
||||
/// skip ambiguous merge tree settings.
|
||||
auto & main_options = options_description.main_description.value();
|
||||
|
||||
std::unordered_set<std::string, TransparentStringHash, std::equal_to<>> main_option_names;
|
||||
for (const auto & option : main_options.options())
|
||||
main_option_names.insert(option->long_name());
|
||||
|
||||
for (const auto & setting : cmd_merge_tree_settings.all())
|
||||
{
|
||||
const auto add_setting = [&](const std::string_view name)
|
||||
{
|
||||
if (auto it = main_option_names.find(name); it != main_option_names.end())
|
||||
return;
|
||||
|
||||
if (allow_repeated_settings)
|
||||
addProgramOptionAsMultitoken(cmd_merge_tree_settings, main_options, name, setting);
|
||||
else
|
||||
addProgramOption(cmd_merge_tree_settings, main_options, name, setting);
|
||||
};
|
||||
|
||||
const auto & setting_name = setting.getName();
|
||||
|
||||
add_setting(setting_name);
|
||||
|
||||
const auto & settings_to_aliases = MergeTreeSettings::Traits::settingsToAliases();
|
||||
if (auto it = settings_to_aliases.find(setting_name); it != settings_to_aliases.end())
|
||||
{
|
||||
for (const auto alias : it->second)
|
||||
{
|
||||
add_setting(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse main commandline options.
|
||||
auto parser = po::command_line_parser(arguments)
|
||||
.options(options_description.main_description.value())
|
||||
.extra_parser(OptionsAliasParser(options_description.main_description.value()))
|
||||
.allow_unregistered();
|
||||
po::parsed_options parsed = parser.run();
|
||||
|
||||
/// Check unrecognized options without positional options.
|
||||
auto unrecognized_options = po::collect_unrecognized(parsed.options, po::collect_unrecognized_mode::exclude_positional);
|
||||
if (!unrecognized_options.empty())
|
||||
{
|
||||
auto hints = this->getHints(unrecognized_options[0]);
|
||||
if (!hints.empty())
|
||||
throw Exception(ErrorCodes::UNRECOGNIZED_ARGUMENTS, "Unrecognized option '{}'. Maybe you meant {}",
|
||||
unrecognized_options[0], toString(hints));
|
||||
|
||||
throw Exception(ErrorCodes::UNRECOGNIZED_ARGUMENTS, "Unrecognized option '{}'", unrecognized_options[0]);
|
||||
}
|
||||
|
||||
/// Check positional options.
|
||||
for (const auto & op : parsed.options)
|
||||
{
|
||||
if (!op.unregistered && op.string_key.empty() && !op.original_tokens[0].starts_with("--")
|
||||
&& !op.original_tokens[0].empty() && !op.value.empty())
|
||||
{
|
||||
/// Two special cases for better usability:
|
||||
/// - if the option contains a whitespace, it might be a query: clickhouse "SELECT 1"
|
||||
/// These are relevant for interactive usage - user-friendly, but questionable in general.
|
||||
/// In case of ambiguity or for scripts, prefer using proper options.
|
||||
|
||||
const auto & token = op.original_tokens[0];
|
||||
po::variable_value value(boost::any(op.value), false);
|
||||
|
||||
const char * option;
|
||||
if (token.contains(' '))
|
||||
option = "query";
|
||||
else
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Positional option `{}` is not supported.", token);
|
||||
|
||||
if (!options.emplace(option, value).second)
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Positional option `{}` is not supported.", token);
|
||||
}
|
||||
}
|
||||
|
||||
po::store(parsed, options);
|
||||
}
|
||||
|
||||
|
||||
void ClientBase::init(int argc, char ** argv)
|
||||
{
|
||||
namespace po = boost::program_options;
|
||||
|
176
src/Client/ClientBaseOptimizedParts.cpp
Normal file
176
src/Client/ClientBaseOptimizedParts.cpp
Normal file
@ -0,0 +1,176 @@
|
||||
#include <Client/ClientBase.h>
|
||||
#include <Core/BaseSettingsProgramOptions.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/**
|
||||
* Program options parsing is very slow in debug builds and it affects .sh tests
|
||||
* causing them to timeout sporadically.
|
||||
* It seems impossible to enable optimizations for a single function (only to disable them), so
|
||||
* instead we extract the code to a separate source file and compile it with different options.
|
||||
*/
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int BAD_ARGUMENTS;
|
||||
extern const int UNRECOGNIZED_ARGUMENTS;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/// Define transparent hash to we can use
|
||||
/// std::string_view with the containers
|
||||
struct TransparentStringHash
|
||||
{
|
||||
using is_transparent = void;
|
||||
size_t operator()(std::string_view txt) const
|
||||
{
|
||||
return std::hash<std::string_view>{}(txt);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This functor is used to parse command line arguments and replace dashes with underscores,
|
||||
* allowing options to be specified using either dashes or underscores.
|
||||
*/
|
||||
class OptionsAliasParser
|
||||
{
|
||||
public:
|
||||
explicit OptionsAliasParser(const boost::program_options::options_description& options)
|
||||
{
|
||||
options_names.reserve(options.options().size());
|
||||
for (const auto& option : options.options())
|
||||
options_names.insert(option->long_name());
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses arguments by replacing dashes with underscores, and matches the resulting name with known options
|
||||
* Implements boost::program_options::ext_parser logic
|
||||
*/
|
||||
std::pair<std::string, std::string> operator()(const std::string & token) const
|
||||
{
|
||||
if (!token.starts_with("--"))
|
||||
return {};
|
||||
std::string arg = token.substr(2);
|
||||
|
||||
// divide token by '=' to separate key and value if options style=long_allow_adjacent
|
||||
auto pos_eq = arg.find('=');
|
||||
std::string key = arg.substr(0, pos_eq);
|
||||
|
||||
if (options_names.contains(key))
|
||||
// option does not require any changes, because it is already correct
|
||||
return {};
|
||||
|
||||
std::replace(key.begin(), key.end(), '-', '_');
|
||||
if (!options_names.contains(key))
|
||||
// after replacing '-' with '_' argument is still unknown
|
||||
return {};
|
||||
|
||||
std::string value;
|
||||
if (pos_eq != std::string::npos && pos_eq < arg.size())
|
||||
value = arg.substr(pos_eq + 1);
|
||||
|
||||
return {key, value};
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_set<std::string> options_names;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void ClientBase::parseAndCheckOptions(OptionsDescription & options_description, po::variables_map & options, Arguments & arguments)
|
||||
{
|
||||
if (allow_repeated_settings)
|
||||
addProgramOptionsAsMultitokens(cmd_settings, options_description.main_description.value());
|
||||
else
|
||||
addProgramOptions(cmd_settings, options_description.main_description.value());
|
||||
|
||||
if (allow_merge_tree_settings)
|
||||
{
|
||||
/// Add merge tree settings manually, because names of some settings
|
||||
/// may clash. Query settings have higher priority and we just
|
||||
/// skip ambiguous merge tree settings.
|
||||
auto & main_options = options_description.main_description.value();
|
||||
|
||||
std::unordered_set<std::string, TransparentStringHash, std::equal_to<>> main_option_names;
|
||||
for (const auto & option : main_options.options())
|
||||
main_option_names.insert(option->long_name());
|
||||
|
||||
for (const auto & setting : cmd_merge_tree_settings.all())
|
||||
{
|
||||
const auto add_setting = [&](const std::string_view name)
|
||||
{
|
||||
if (auto it = main_option_names.find(name); it != main_option_names.end())
|
||||
return;
|
||||
|
||||
if (allow_repeated_settings)
|
||||
addProgramOptionAsMultitoken(cmd_merge_tree_settings, main_options, name, setting);
|
||||
else
|
||||
addProgramOption(cmd_merge_tree_settings, main_options, name, setting);
|
||||
};
|
||||
|
||||
const auto & setting_name = setting.getName();
|
||||
|
||||
add_setting(setting_name);
|
||||
|
||||
const auto & settings_to_aliases = MergeTreeSettings::Traits::settingsToAliases();
|
||||
if (auto it = settings_to_aliases.find(setting_name); it != settings_to_aliases.end())
|
||||
{
|
||||
for (const auto alias : it->second)
|
||||
{
|
||||
add_setting(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse main commandline options.
|
||||
auto parser = po::command_line_parser(arguments)
|
||||
.options(options_description.main_description.value())
|
||||
.extra_parser(OptionsAliasParser(options_description.main_description.value()))
|
||||
.allow_unregistered();
|
||||
po::parsed_options parsed = parser.run();
|
||||
|
||||
/// Check unrecognized options without positional options.
|
||||
auto unrecognized_options = po::collect_unrecognized(parsed.options, po::collect_unrecognized_mode::exclude_positional);
|
||||
if (!unrecognized_options.empty())
|
||||
{
|
||||
auto hints = this->getHints(unrecognized_options[0]);
|
||||
if (!hints.empty())
|
||||
throw Exception(ErrorCodes::UNRECOGNIZED_ARGUMENTS, "Unrecognized option '{}'. Maybe you meant {}",
|
||||
unrecognized_options[0], toString(hints));
|
||||
|
||||
throw Exception(ErrorCodes::UNRECOGNIZED_ARGUMENTS, "Unrecognized option '{}'", unrecognized_options[0]);
|
||||
}
|
||||
|
||||
/// Check positional options.
|
||||
for (const auto & op : parsed.options)
|
||||
{
|
||||
if (!op.unregistered && op.string_key.empty() && !op.original_tokens[0].starts_with("--")
|
||||
&& !op.original_tokens[0].empty() && !op.value.empty())
|
||||
{
|
||||
/// Two special cases for better usability:
|
||||
/// - if the option contains a whitespace, it might be a query: clickhouse "SELECT 1"
|
||||
/// These are relevant for interactive usage - user-friendly, but questionable in general.
|
||||
/// In case of ambiguity or for scripts, prefer using proper options.
|
||||
|
||||
const auto & token = op.original_tokens[0];
|
||||
po::variable_value value(boost::any(op.value), false);
|
||||
|
||||
const char * option;
|
||||
if (token.contains(' '))
|
||||
option = "query";
|
||||
else
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Positional option `{}` is not supported.", token);
|
||||
|
||||
if (!options.emplace(option, value).second)
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Positional option `{}` is not supported.", token);
|
||||
}
|
||||
}
|
||||
|
||||
po::store(parsed, options);
|
||||
}
|
||||
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
#include <Common/ErrorCodes.h>
|
||||
#include <Common/Exception.h>
|
||||
#include <Common/LockMemoryExceptionInThread.h>
|
||||
#include <Common/Logger.h>
|
||||
#include <Common/MemorySanitizer.h>
|
||||
#include <Common/SensitiveDataMasker.h>
|
||||
#include <Common/config_version.h>
|
||||
@ -100,7 +101,7 @@ Exception::Exception(const MessageMasked & msg_masked, int code, bool remote_)
|
||||
{
|
||||
if (terminate_on_any_exception)
|
||||
std::_Exit(terminate_status_code);
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
handle_error_code(msg_masked.msg, code, remote, getStackFramePointers());
|
||||
}
|
||||
|
||||
@ -110,7 +111,7 @@ Exception::Exception(MessageMasked && msg_masked, int code, bool remote_)
|
||||
{
|
||||
if (terminate_on_any_exception)
|
||||
std::_Exit(terminate_status_code);
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
handle_error_code(message(), code, remote, getStackFramePointers());
|
||||
}
|
||||
|
||||
@ -119,7 +120,7 @@ Exception::Exception(CreateFromPocoTag, const Poco::Exception & exc)
|
||||
{
|
||||
if (terminate_on_any_exception)
|
||||
std::_Exit(terminate_status_code);
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
#ifdef STD_EXCEPTION_HAS_STACK_TRACE
|
||||
auto * stack_trace_frames = exc.get_stack_trace_frames();
|
||||
auto stack_trace_size = exc.get_stack_trace_size();
|
||||
@ -133,7 +134,7 @@ Exception::Exception(CreateFromSTDTag, const std::exception & exc)
|
||||
{
|
||||
if (terminate_on_any_exception)
|
||||
std::_Exit(terminate_status_code);
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
#ifdef STD_EXCEPTION_HAS_STACK_TRACE
|
||||
auto * stack_trace_frames = exc.get_stack_trace_frames();
|
||||
auto stack_trace_size = exc.get_stack_trace_size();
|
||||
@ -223,10 +224,38 @@ Exception::FramePointers Exception::getStackFramePointers() const
|
||||
}
|
||||
|
||||
thread_local bool Exception::enable_job_stack_trace = false;
|
||||
thread_local std::vector<StackTrace::FramePointers> Exception::thread_frame_pointers = {};
|
||||
thread_local bool Exception::can_use_thread_frame_pointers = false;
|
||||
thread_local Exception::ThreadFramePointers Exception::thread_frame_pointers;
|
||||
|
||||
Exception::ThreadFramePointers::ThreadFramePointers()
|
||||
{
|
||||
can_use_thread_frame_pointers = true;
|
||||
}
|
||||
|
||||
Exception::ThreadFramePointers::~ThreadFramePointers()
|
||||
{
|
||||
can_use_thread_frame_pointers = false;
|
||||
}
|
||||
|
||||
Exception::ThreadFramePointersBase Exception::getThreadFramePointers()
|
||||
{
|
||||
if (can_use_thread_frame_pointers)
|
||||
return thread_frame_pointers.frame_pointers;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void Exception::setThreadFramePointers(ThreadFramePointersBase frame_pointers)
|
||||
{
|
||||
if (can_use_thread_frame_pointers)
|
||||
thread_frame_pointers.frame_pointers = std::move(frame_pointers);
|
||||
}
|
||||
|
||||
static void tryLogCurrentExceptionImpl(Poco::Logger * logger, const std::string & start_of_message)
|
||||
{
|
||||
if (!isLoggingEnabled())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
PreformattedMessage message = getCurrentExceptionMessageAndPattern(true);
|
||||
@ -242,6 +271,9 @@ static void tryLogCurrentExceptionImpl(Poco::Logger * logger, const std::string
|
||||
|
||||
void tryLogCurrentException(const char * log_name, const std::string & start_of_message)
|
||||
{
|
||||
if (!isLoggingEnabled())
|
||||
return;
|
||||
|
||||
/// Under high memory pressure, new allocations throw a
|
||||
/// MEMORY_LIMIT_EXCEEDED exception.
|
||||
///
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <cerrno>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/core.h>
|
||||
@ -49,14 +48,14 @@ public:
|
||||
{
|
||||
if (terminate_on_any_exception)
|
||||
std::terminate();
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
}
|
||||
|
||||
Exception(const PreformattedMessage & msg, int code): Exception(msg.text, code)
|
||||
{
|
||||
if (terminate_on_any_exception)
|
||||
std::terminate();
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
message_format_string = msg.format_string;
|
||||
message_format_string_args = msg.format_string_args;
|
||||
}
|
||||
@ -65,18 +64,36 @@ public:
|
||||
{
|
||||
if (terminate_on_any_exception)
|
||||
std::terminate();
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
message_format_string = msg.format_string;
|
||||
message_format_string_args = msg.format_string_args;
|
||||
}
|
||||
|
||||
/// Collect call stacks of all previous jobs' schedulings leading to this thread job's execution
|
||||
static thread_local bool enable_job_stack_trace;
|
||||
static thread_local std::vector<StackTrace::FramePointers> thread_frame_pointers;
|
||||
static thread_local bool can_use_thread_frame_pointers;
|
||||
/// Because of unknown order of static destructor calls,
|
||||
/// thread_frame_pointers can already be uninitialized when a different destructor generates an exception.
|
||||
/// To prevent such scenarios, a wrapper class is created and a function that will return empty vector
|
||||
/// if its destructor is already called
|
||||
using ThreadFramePointersBase = std::vector<StackTrace::FramePointers>;
|
||||
struct ThreadFramePointers
|
||||
{
|
||||
ThreadFramePointers();
|
||||
~ThreadFramePointers();
|
||||
|
||||
ThreadFramePointersBase frame_pointers;
|
||||
};
|
||||
|
||||
static ThreadFramePointersBase getThreadFramePointers();
|
||||
static void setThreadFramePointers(ThreadFramePointersBase frame_pointers);
|
||||
|
||||
/// Callback for any exception
|
||||
static std::function<void(const std::string & msg, int code, bool remote, const Exception::FramePointers & trace)> callback;
|
||||
|
||||
protected:
|
||||
static thread_local ThreadFramePointers thread_frame_pointers;
|
||||
|
||||
// used to remove the sensitive information from exceptions if query_masking_rules is configured
|
||||
struct MessageMasked
|
||||
{
|
||||
@ -178,7 +195,7 @@ class ErrnoException : public Exception
|
||||
public:
|
||||
ErrnoException(std::string && msg, int code, int with_errno) : Exception(msg, code), saved_errno(with_errno)
|
||||
{
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
addMessage(", {}", errnoToString(saved_errno));
|
||||
}
|
||||
|
||||
@ -187,7 +204,7 @@ public:
|
||||
requires std::is_convertible_v<T, String>
|
||||
ErrnoException(int code, T && message) : Exception(message, code), saved_errno(errno)
|
||||
{
|
||||
capture_thread_frame_pointers = thread_frame_pointers;
|
||||
capture_thread_frame_pointers = getThreadFramePointers();
|
||||
addMessage(", {}", errnoToString(saved_errno));
|
||||
}
|
||||
|
||||
|
@ -25,3 +25,15 @@ bool hasLogger(const std::string & name)
|
||||
{
|
||||
return Poco::Logger::has(name);
|
||||
}
|
||||
|
||||
static constinit std::atomic<bool> allow_logging{true};
|
||||
|
||||
bool isLoggingEnabled()
|
||||
{
|
||||
return allow_logging;
|
||||
}
|
||||
|
||||
void disableLogging()
|
||||
{
|
||||
allow_logging = false;
|
||||
}
|
||||
|
@ -64,3 +64,7 @@ LoggerRawPtr createRawLogger(const std::string & name, Poco::Channel * channel,
|
||||
* Otherwise, returns false.
|
||||
*/
|
||||
bool hasLogger(const std::string & name);
|
||||
|
||||
void disableLogging();
|
||||
|
||||
bool isLoggingEnabled();
|
||||
|
@ -89,7 +89,7 @@ void signalHandler(int sig, siginfo_t * info, void * context)
|
||||
writePODBinary(*info, out);
|
||||
writePODBinary(signal_context, out);
|
||||
writePODBinary(stack_trace, out);
|
||||
writeVectorBinary(Exception::enable_job_stack_trace ? Exception::thread_frame_pointers : std::vector<StackTrace::FramePointers>{}, out);
|
||||
writeVectorBinary(Exception::enable_job_stack_trace ? Exception::getThreadFramePointers() : std::vector<StackTrace::FramePointers>{}, out);
|
||||
writeBinary(static_cast<UInt32>(getThreadId()), out);
|
||||
writePODBinary(current_thread, out);
|
||||
|
||||
|
@ -489,24 +489,25 @@ struct CacheEntry
|
||||
|
||||
using CacheEntryPtr = std::shared_ptr<CacheEntry>;
|
||||
|
||||
static constinit std::atomic<bool> can_use_cache = false;
|
||||
static constinit bool can_use_cache = false;
|
||||
|
||||
using StackTraceCacheBase = std::map<StackTraceTriple, CacheEntryPtr, std::less<>>;
|
||||
|
||||
struct StackTraceCache : public StackTraceCacheBase
|
||||
{
|
||||
StackTraceCache()
|
||||
: StackTraceCacheBase()
|
||||
{
|
||||
can_use_cache = true;
|
||||
}
|
||||
|
||||
~StackTraceCache()
|
||||
{
|
||||
can_use_cache = false;
|
||||
}
|
||||
};
|
||||
|
||||
static StackTraceCache & cacheInstance()
|
||||
{
|
||||
static StackTraceCache cache;
|
||||
can_use_cache = true;
|
||||
return cache;
|
||||
}
|
||||
static StackTraceCache cache;
|
||||
|
||||
static DB::SharedMutex stacktrace_cache_mutex;
|
||||
|
||||
@ -524,7 +525,6 @@ String toStringCached(const StackTrace::FramePointers & pointers, size_t offset,
|
||||
/// Calculation of stack trace text is extremely slow.
|
||||
/// We use cache because otherwise the server could be overloaded by trash queries.
|
||||
/// Note that this cache can grow unconditionally, but practically it should be small.
|
||||
StackTraceCache & cache = cacheInstance();
|
||||
CacheEntryPtr cache_entry;
|
||||
|
||||
// Optimistic try for cache hit to avoid any contention whatsoever, should be the main hot code route
|
||||
@ -576,7 +576,7 @@ std::string StackTrace::toString(void * const * frame_pointers_raw, size_t offse
|
||||
void StackTrace::dropCache()
|
||||
{
|
||||
std::lock_guard lock{stacktrace_cache_mutex};
|
||||
cacheInstance().clear();
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
if (!capture_frame_pointers)
|
||||
return;
|
||||
/// Save all previous jobs call stacks and append with current
|
||||
frame_pointers = DB::Exception::thread_frame_pointers;
|
||||
frame_pointers = DB::Exception::getThreadFramePointers();
|
||||
frame_pointers.push_back(StackTrace().getFramePointers());
|
||||
}
|
||||
|
||||
@ -455,7 +455,7 @@ void ThreadPoolImpl<Thread>::worker(typename std::list<Thread>::iterator thread_
|
||||
try
|
||||
{
|
||||
if (DB::Exception::enable_job_stack_trace)
|
||||
DB::Exception::thread_frame_pointers = std::move(job_data->frame_pointers);
|
||||
DB::Exception::setThreadFramePointers(std::move(job_data->frame_pointers));
|
||||
|
||||
CurrentMetrics::Increment metric_active_pool_threads(metric_active_threads);
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
clickhouse_add_executable (mysqlxx_pool_test mysqlxx_pool_test.cpp)
|
||||
target_link_libraries (mysqlxx_pool_test PRIVATE mysqlxx clickhouse_common_config)
|
||||
target_link_libraries (mysqlxx_pool_test PRIVATE mysqlxx clickhouse_common_config loggers_no_text_log)
|
||||
|
@ -158,7 +158,7 @@ BaseDaemon::~BaseDaemon()
|
||||
tryLogCurrentException(&logger());
|
||||
}
|
||||
|
||||
OwnSplitChannel::disableLogging();
|
||||
disableLogging();
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
|
||||
String getFileName() const override { return impl->getFileName(); }
|
||||
|
||||
size_t getFileSize() override { return impl->getFileSize(); }
|
||||
std::optional<size_t> tryGetFileSize() override { return impl->tryGetFileSize(); }
|
||||
|
||||
String getInfoForLog() override { return impl->getInfoForLog(); }
|
||||
|
||||
|
@ -253,16 +253,15 @@ void ReadBufferFromAzureBlobStorage::initialize()
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
size_t ReadBufferFromAzureBlobStorage::getFileSize()
|
||||
std::optional<size_t> ReadBufferFromAzureBlobStorage::tryGetFileSize()
|
||||
{
|
||||
if (!blob_client)
|
||||
blob_client = std::make_unique<Azure::Storage::Blobs::BlobClient>(blob_container_client->GetBlobClient(path));
|
||||
|
||||
if (file_size.has_value())
|
||||
return *file_size;
|
||||
if (!file_size)
|
||||
file_size = blob_client->GetProperties().Value.BlobSize;
|
||||
|
||||
file_size = blob_client->GetProperties().Value.BlobSize;
|
||||
return *file_size;
|
||||
return file_size;
|
||||
}
|
||||
|
||||
size_t ReadBufferFromAzureBlobStorage::readBigAt(char * to, size_t n, size_t range_begin, const std::function<bool(size_t)> & /*progress_callback*/) const
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
|
||||
bool supportsRightBoundedReads() const override { return true; }
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
size_t readBigAt(char * to, size_t n, size_t range_begin, const std::function<bool(size_t)> & progress_callback) const override;
|
||||
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
|
||||
void setReadUntilEnd() override { setReadUntilPosition(getFileSize()); }
|
||||
|
||||
size_t getFileSize() override { return getTotalSize(blobs_to_read); }
|
||||
std::optional<size_t> tryGetFileSize() override { return getTotalSize(blobs_to_read); }
|
||||
|
||||
size_t getFileOffsetOfBufferEnd() const override { return file_offset_of_buffer_end; }
|
||||
|
||||
|
@ -321,7 +321,7 @@ public:
|
||||
off_t getPosition() override { throw Exception(ErrorCodes::UNSUPPORTED_METHOD, "getPosition not supported when reading from archive"); }
|
||||
String getFileName() const override { return handle.getFileName(); }
|
||||
|
||||
size_t getFileSize() override { return handle.getFileInfo().uncompressed_size; }
|
||||
std::optional<size_t> tryGetFileSize() override { return handle.getFileInfo().uncompressed_size; }
|
||||
|
||||
Handle releaseHandle() && { return std::move(handle); }
|
||||
|
||||
|
@ -317,7 +317,7 @@ public:
|
||||
|
||||
String getFileName() const override { return handle.getFileName(); }
|
||||
|
||||
size_t getFileSize() override { return handle.getFileInfo().uncompressed_size; }
|
||||
std::optional<size_t> tryGetFileSize() override { return handle.getFileInfo().uncompressed_size; }
|
||||
|
||||
/// Releases owned handle to pass it to an enumerator.
|
||||
HandleHolder releaseHandle() &&
|
||||
|
@ -244,7 +244,7 @@ void AsynchronousReadBufferFromFileDescriptor::rewind()
|
||||
file_offset_of_buffer_end = 0;
|
||||
}
|
||||
|
||||
size_t AsynchronousReadBufferFromFileDescriptor::getFileSize()
|
||||
std::optional<size_t> AsynchronousReadBufferFromFileDescriptor::tryGetFileSize()
|
||||
{
|
||||
return getSizeFromFileDescriptor(fd, getFileName());
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
/// Seek to the beginning, discarding already read data if any. Useful to reread file that changes on every read.
|
||||
void rewind();
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
size_t getFileOffsetOfBufferEnd() const override { return file_offset_of_buffer_end; }
|
||||
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
off_t seek(off_t off, int whence) override;
|
||||
off_t getPosition() override;
|
||||
|
||||
size_t getFileSize() override { return total_size; }
|
||||
std::optional<size_t> tryGetFileSize() override { return total_size; }
|
||||
|
||||
private:
|
||||
bool nextImpl() override;
|
||||
|
@ -87,7 +87,7 @@ off_t MMapReadBufferFromFileDescriptor::seek(off_t offset, int whence)
|
||||
return new_pos;
|
||||
}
|
||||
|
||||
size_t MMapReadBufferFromFileDescriptor::getFileSize()
|
||||
std::optional<size_t> MMapReadBufferFromFileDescriptor::tryGetFileSize()
|
||||
{
|
||||
return getSizeFromFileDescriptor(getFD(), getFileName());
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
|
||||
int getFD() const;
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
size_t readBigAt(char * to, size_t n, size_t offset, const std::function<bool(size_t)> &) const override;
|
||||
bool supportsReadAt() override { return true; }
|
||||
|
@ -152,7 +152,7 @@ off_t ParallelReadBuffer::seek(off_t offset, int whence)
|
||||
return offset;
|
||||
}
|
||||
|
||||
size_t ParallelReadBuffer::getFileSize()
|
||||
std::optional<size_t> ParallelReadBuffer::tryGetFileSize()
|
||||
{
|
||||
return file_size;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
~ParallelReadBuffer() override { finishAndWait(); }
|
||||
|
||||
off_t seek(off_t off, int whence) override;
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
off_t getPosition() override;
|
||||
|
||||
const SeekableReadBuffer & getReadBuffer() const { return input; }
|
||||
|
@ -19,7 +19,8 @@ private:
|
||||
std::string getFileName() const override { return "<empty>"; }
|
||||
off_t seek(off_t /*off*/, int /*whence*/) override { return 0; }
|
||||
off_t getPosition() override { return 0; }
|
||||
size_t getFileSize() override { return 0; }
|
||||
std::optional<size_t> tryGetFileSize() override { return 0; }
|
||||
size_t getFileOffsetOfBufferEnd() const override { return 0; }
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
|
||||
void setReadUntilEnd() override { in->setReadUntilEnd(); }
|
||||
|
||||
size_t getFileSize() override { return in->getFileSize(); }
|
||||
std::optional<size_t> tryGetFileSize() override { return in->tryGetFileSize(); }
|
||||
|
||||
private:
|
||||
bool nextImpl() override;
|
||||
|
@ -5,11 +5,6 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int UNKNOWN_FILE_SIZE;
|
||||
}
|
||||
|
||||
ReadBufferFromFileBase::ReadBufferFromFileBase() : BufferWithOwnMemory<SeekableReadBuffer>(0)
|
||||
{
|
||||
}
|
||||
@ -26,11 +21,9 @@ ReadBufferFromFileBase::ReadBufferFromFileBase(
|
||||
|
||||
ReadBufferFromFileBase::~ReadBufferFromFileBase() = default;
|
||||
|
||||
size_t ReadBufferFromFileBase::getFileSize()
|
||||
std::optional<size_t> ReadBufferFromFileBase::tryGetFileSize()
|
||||
{
|
||||
if (file_size)
|
||||
return *file_size;
|
||||
throw Exception(ErrorCodes::UNKNOWN_FILE_SIZE, "Cannot find out file size for read buffer");
|
||||
return file_size;
|
||||
}
|
||||
|
||||
void ReadBufferFromFileBase::setProgressCallback(ContextPtr context)
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
clock_type = clock_type_;
|
||||
}
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
void setProgressCallback(ContextPtr context);
|
||||
|
||||
|
@ -52,9 +52,9 @@ bool ReadBufferFromFileDecorator::nextImpl()
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t ReadBufferFromFileDecorator::getFileSize()
|
||||
std::optional<size_t> ReadBufferFromFileDecorator::tryGetFileSize()
|
||||
{
|
||||
return getFileSizeFromReadBuffer(*impl);
|
||||
return tryGetFileSizeFromReadBuffer(*impl);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
|
||||
ReadBuffer & getWrappedReadBuffer() { return *impl; }
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<SeekableReadBuffer> impl;
|
||||
|
@ -253,7 +253,7 @@ void ReadBufferFromFileDescriptor::rewind()
|
||||
file_offset_of_buffer_end = 0;
|
||||
}
|
||||
|
||||
size_t ReadBufferFromFileDescriptor::getFileSize()
|
||||
std::optional<size_t> ReadBufferFromFileDescriptor::tryGetFileSize()
|
||||
{
|
||||
return getSizeFromFileDescriptor(fd, getFileName());
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
/// Seek to the beginning, discarding already read data if any. Useful to reread file that changes on every read.
|
||||
void rewind();
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
bool checkIfActuallySeekable() override;
|
||||
|
||||
|
@ -311,15 +311,15 @@ off_t ReadBufferFromS3::seek(off_t offset_, int whence)
|
||||
return offset;
|
||||
}
|
||||
|
||||
size_t ReadBufferFromS3::getFileSize()
|
||||
std::optional<size_t> ReadBufferFromS3::tryGetFileSize()
|
||||
{
|
||||
if (file_size)
|
||||
return *file_size;
|
||||
return file_size;
|
||||
|
||||
auto object_size = S3::getObjectSize(*client_ptr, bucket, key, version_id);
|
||||
|
||||
file_size = object_size;
|
||||
return *file_size;
|
||||
return file_size;
|
||||
}
|
||||
|
||||
off_t ReadBufferFromS3::getPosition()
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
|
||||
off_t getPosition() override;
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
void setReadUntilPosition(size_t position) override;
|
||||
void setReadUntilEnd() override;
|
||||
|
@ -72,7 +72,6 @@ namespace ErrorCodes
|
||||
extern const int BAD_ARGUMENTS;
|
||||
extern const int CANNOT_SEEK_THROUGH_FILE;
|
||||
extern const int SEEK_POSITION_OUT_OF_BOUND;
|
||||
extern const int UNKNOWN_FILE_SIZE;
|
||||
}
|
||||
|
||||
std::unique_ptr<ReadBuffer> ReadWriteBufferFromHTTP::CallResult::transformToReadBuffer(size_t buf_size) &&
|
||||
@ -121,15 +120,33 @@ void ReadWriteBufferFromHTTP::prepareRequest(Poco::Net::HTTPRequest & request, s
|
||||
credentials.authenticate(request);
|
||||
}
|
||||
|
||||
size_t ReadWriteBufferFromHTTP::getFileSize()
|
||||
std::optional<size_t> ReadWriteBufferFromHTTP::tryGetFileSize()
|
||||
{
|
||||
if (!file_info)
|
||||
file_info = getFileInfo();
|
||||
{
|
||||
try
|
||||
{
|
||||
file_info = getFileInfo();
|
||||
}
|
||||
catch (const HTTPException &)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
catch (const NetException &)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
catch (const Poco::Net::NetException &)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
catch (const Poco::IOException &)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_info->file_size)
|
||||
return *file_info->file_size;
|
||||
|
||||
throw Exception(ErrorCodes::UNKNOWN_FILE_SIZE, "Cannot find out file size for: {}", initial_uri.toString());
|
||||
return file_info->file_size;
|
||||
}
|
||||
|
||||
bool ReadWriteBufferFromHTTP::supportsReadAt()
|
||||
@ -311,12 +328,12 @@ void ReadWriteBufferFromHTTP::doWithRetries(std::function<void()> && callable,
|
||||
error_message = e.displayText();
|
||||
exception = std::current_exception();
|
||||
}
|
||||
catch (DB::NetException & e)
|
||||
catch (NetException & e)
|
||||
{
|
||||
error_message = e.displayText();
|
||||
exception = std::current_exception();
|
||||
}
|
||||
catch (DB::HTTPException & e)
|
||||
catch (HTTPException & e)
|
||||
{
|
||||
if (!isRetriableError(e.getHTTPStatus()))
|
||||
is_retriable = false;
|
||||
@ -324,7 +341,7 @@ void ReadWriteBufferFromHTTP::doWithRetries(std::function<void()> && callable,
|
||||
error_message = e.displayText();
|
||||
exception = std::current_exception();
|
||||
}
|
||||
catch (DB::Exception & e)
|
||||
catch (Exception & e)
|
||||
{
|
||||
is_retriable = false;
|
||||
|
||||
@ -683,7 +700,19 @@ std::optional<time_t> ReadWriteBufferFromHTTP::tryGetLastModificationTime()
|
||||
{
|
||||
file_info = getFileInfo();
|
||||
}
|
||||
catch (...)
|
||||
catch (const HTTPException &)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
catch (const NetException &)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
catch (const Poco::Net::NetException &)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
catch (const Poco::IOException &)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
@ -704,7 +733,7 @@ ReadWriteBufferFromHTTP::HTTPFileInfo ReadWriteBufferFromHTTP::getFileInfo()
|
||||
{
|
||||
getHeadResponse(response);
|
||||
}
|
||||
catch (HTTPException & e)
|
||||
catch (const HTTPException & e)
|
||||
{
|
||||
/// Maybe the web server doesn't support HEAD requests.
|
||||
/// E.g. webhdfs reports status 400.
|
||||
|
@ -118,7 +118,7 @@ private:
|
||||
|
||||
std::unique_ptr<ReadBuffer> initialize();
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
bool supportsReadAt() override;
|
||||
|
||||
|
@ -13,41 +13,47 @@ namespace ErrorCodes
|
||||
extern const int UNKNOWN_FILE_SIZE;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static size_t getFileSize(T & in)
|
||||
size_t WithFileSize::getFileSize()
|
||||
{
|
||||
if (auto * with_file_size = dynamic_cast<WithFileSize *>(&in))
|
||||
{
|
||||
return with_file_size->getFileSize();
|
||||
}
|
||||
if (auto maybe_size = tryGetFileSize())
|
||||
return *maybe_size;
|
||||
|
||||
throw Exception(ErrorCodes::UNKNOWN_FILE_SIZE, "Cannot find out file size");
|
||||
}
|
||||
|
||||
size_t getFileSizeFromReadBuffer(ReadBuffer & in)
|
||||
template <typename T>
|
||||
static std::optional<size_t> tryGetFileSize(T & in)
|
||||
{
|
||||
if (auto * delegate = dynamic_cast<ReadBufferFromFileDecorator *>(&in))
|
||||
{
|
||||
return getFileSize(delegate->getWrappedReadBuffer());
|
||||
}
|
||||
else if (auto * compressed = dynamic_cast<CompressedReadBufferWrapper *>(&in))
|
||||
{
|
||||
return getFileSize(compressed->getWrappedReadBuffer());
|
||||
}
|
||||
if (auto * with_file_size = dynamic_cast<WithFileSize *>(&in))
|
||||
return with_file_size->tryGetFileSize();
|
||||
|
||||
return getFileSize(in);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static size_t getFileSize(T & in)
|
||||
{
|
||||
if (auto maybe_size = tryGetFileSize(in))
|
||||
return *maybe_size;
|
||||
|
||||
throw Exception(ErrorCodes::UNKNOWN_FILE_SIZE, "Cannot find out file size");
|
||||
}
|
||||
|
||||
std::optional<size_t> tryGetFileSizeFromReadBuffer(ReadBuffer & in)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getFileSizeFromReadBuffer(in);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
if (auto * delegate = dynamic_cast<ReadBufferFromFileDecorator *>(&in))
|
||||
return tryGetFileSize(delegate->getWrappedReadBuffer());
|
||||
else if (auto * compressed = dynamic_cast<CompressedReadBufferWrapper *>(&in))
|
||||
return tryGetFileSize(compressed->getWrappedReadBuffer());
|
||||
return tryGetFileSize(in);
|
||||
}
|
||||
|
||||
size_t getFileSizeFromReadBuffer(ReadBuffer & in)
|
||||
{
|
||||
if (auto maybe_size = tryGetFileSizeFromReadBuffer(in))
|
||||
return *maybe_size;
|
||||
|
||||
throw Exception(ErrorCodes::UNKNOWN_FILE_SIZE, "Cannot find out file size");
|
||||
}
|
||||
|
||||
bool isBufferWithFileSize(const ReadBuffer & in)
|
||||
|
@ -10,15 +10,16 @@ class ReadBuffer;
|
||||
class WithFileSize
|
||||
{
|
||||
public:
|
||||
virtual size_t getFileSize() = 0;
|
||||
/// Returns nullopt if couldn't find out file size;
|
||||
virtual std::optional<size_t> tryGetFileSize() = 0;
|
||||
virtual ~WithFileSize() = default;
|
||||
|
||||
size_t getFileSize();
|
||||
};
|
||||
|
||||
bool isBufferWithFileSize(const ReadBuffer & in);
|
||||
|
||||
size_t getFileSizeFromReadBuffer(ReadBuffer & in);
|
||||
|
||||
/// Return nullopt if couldn't find out file size;
|
||||
std::optional<size_t> tryGetFileSizeFromReadBuffer(ReadBuffer & in);
|
||||
|
||||
size_t getDataOffsetMaybeCompressed(const ReadBuffer & in);
|
||||
|
@ -13,10 +13,6 @@
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int LOGICAL_ERROR;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -237,16 +233,8 @@ void SubstituteColumnOptimizer::perform()
|
||||
|
||||
const auto & compare_graph = metadata_snapshot->getConstraints().getGraph();
|
||||
|
||||
// Fill aliases
|
||||
if (select_query->select())
|
||||
{
|
||||
auto * list = select_query->refSelect()->as<ASTExpressionList>();
|
||||
if (!list)
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "List of selected columns must be ASTExpressionList");
|
||||
|
||||
for (ASTPtr & ast : list->children)
|
||||
ast->setAlias(ast->getAliasOrColumnName());
|
||||
}
|
||||
if (compare_graph.getNumOfComponents() == 0)
|
||||
return;
|
||||
|
||||
auto run_for_all = [&](const auto func)
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ struct StorageInMemoryMetadata;
|
||||
using StorageMetadataPtr = std::shared_ptr<const StorageInMemoryMetadata>;
|
||||
|
||||
/// Optimizer that tries to replace columns to equal columns (according to constraints)
|
||||
/// with lower size (according to compressed and uncomressed size).
|
||||
/// with lower size (according to compressed and uncompressed sizes).
|
||||
class SubstituteColumnOptimizer
|
||||
{
|
||||
public:
|
||||
|
@ -16,16 +16,9 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
static constinit std::atomic<bool> allow_logging{true};
|
||||
|
||||
void OwnSplitChannel::disableLogging()
|
||||
{
|
||||
allow_logging = false;
|
||||
}
|
||||
|
||||
void OwnSplitChannel::log(const Poco::Message & msg)
|
||||
{
|
||||
if (!allow_logging)
|
||||
if (!isLoggingEnabled())
|
||||
return;
|
||||
|
||||
#ifndef WITHOUT_TEXT_LOG
|
||||
|
@ -39,8 +39,6 @@ public:
|
||||
|
||||
void setLevel(const std::string & name, int level);
|
||||
|
||||
static void disableLogging();
|
||||
|
||||
private:
|
||||
void logSplit(const Poco::Message & msg);
|
||||
void tryLogSplit(const Poco::Message & msg);
|
||||
|
@ -235,7 +235,13 @@ void ASTTableJoin::formatImplAfterTable(const FormatSettings & settings, FormatS
|
||||
else if (on_expression)
|
||||
{
|
||||
settings.ostr << (settings.hilite ? hilite_keyword : "") << " ON " << (settings.hilite ? hilite_none : "");
|
||||
/// If there is an alias for the whole expression parens should be added, otherwise it will be invalid syntax
|
||||
bool on_has_alias = !on_expression->tryGetAlias().empty();
|
||||
if (on_has_alias)
|
||||
settings.ostr << "(";
|
||||
on_expression->formatImpl(settings, state, frame);
|
||||
if (on_has_alias)
|
||||
settings.ostr << ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
/** Set the alias. */
|
||||
virtual void setAlias(const String & /*to*/)
|
||||
{
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Can't set alias of {}", getColumnName());
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Can't set alias of {} of {}", getColumnName(), getID());
|
||||
}
|
||||
|
||||
/** Get the text that identifies this element. */
|
||||
|
@ -23,7 +23,10 @@ size_t tryConvertOuterJoinToInnerJoin(QueryPlan::Node * parent_node, QueryPlan::
|
||||
return 0;
|
||||
|
||||
const auto & table_join = join->getJoin()->getTableJoin();
|
||||
if (table_join.strictness() == JoinStrictness::Asof)
|
||||
|
||||
/// Any JOIN issue https://github.com/ClickHouse/ClickHouse/issues/66447
|
||||
/// Anti JOIN issue https://github.com/ClickHouse/ClickHouse/issues/67156
|
||||
if (table_join.strictness() != JoinStrictness::All)
|
||||
return 0;
|
||||
|
||||
/// TODO: Support join_use_nulls
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
bool nextImpl() override;
|
||||
off_t seek(off_t off, int whence) override;
|
||||
off_t getPosition() override;
|
||||
size_t getFileSize() override { return remote_file_size; }
|
||||
std::optional<size_t> tryGetFileSize() override { return remote_file_size; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<LocalFileHolder> local_file_holder;
|
||||
|
@ -91,9 +91,9 @@ void AsynchronousReadBufferFromHDFS::prefetch(Priority priority)
|
||||
}
|
||||
|
||||
|
||||
size_t AsynchronousReadBufferFromHDFS::getFileSize()
|
||||
std::optional<size_t> AsynchronousReadBufferFromHDFS::tryGetFileSize()
|
||||
{
|
||||
return impl->getFileSize();
|
||||
return impl->tryGetFileSize();
|
||||
}
|
||||
|
||||
String AsynchronousReadBufferFromHDFS::getFileName() const
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
|
||||
void prefetch(Priority priority) override;
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
String getFileName() const override;
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace ErrorCodes
|
||||
}
|
||||
|
||||
|
||||
struct ReadBufferFromHDFS::ReadBufferFromHDFSImpl : public BufferWithOwnMemory<SeekableReadBuffer>
|
||||
struct ReadBufferFromHDFS::ReadBufferFromHDFSImpl : public BufferWithOwnMemory<SeekableReadBuffer>, public WithFileSize
|
||||
{
|
||||
String hdfs_uri;
|
||||
String hdfs_file_path;
|
||||
@ -90,7 +90,7 @@ struct ReadBufferFromHDFS::ReadBufferFromHDFSImpl : public BufferWithOwnMemory<S
|
||||
hdfsCloseFile(fs.get(), fin);
|
||||
}
|
||||
|
||||
size_t getFileSize() const
|
||||
std::optional<size_t> tryGetFileSize() override
|
||||
{
|
||||
return file_size;
|
||||
}
|
||||
@ -191,9 +191,9 @@ ReadBufferFromHDFS::ReadBufferFromHDFS(
|
||||
|
||||
ReadBufferFromHDFS::~ReadBufferFromHDFS() = default;
|
||||
|
||||
size_t ReadBufferFromHDFS::getFileSize()
|
||||
std::optional<size_t> ReadBufferFromHDFS::tryGetFileSize()
|
||||
{
|
||||
return impl->getFileSize();
|
||||
return impl->tryGetFileSize();
|
||||
}
|
||||
|
||||
bool ReadBufferFromHDFS::nextImpl()
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
|
||||
off_t getPosition() override;
|
||||
|
||||
size_t getFileSize() override;
|
||||
std::optional<size_t> tryGetFileSize() override;
|
||||
|
||||
size_t getFileOffsetOfBufferEnd() const override;
|
||||
|
||||
|
@ -3,10 +3,10 @@ DROP TABLE IF EXISTS mergetree_00673;
|
||||
CREATE TABLE mergetree_00673 (x UInt64) ENGINE = MergeTree ORDER BY x;
|
||||
INSERT INTO mergetree_00673 VALUES (1);
|
||||
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM mergetree_00673 WHERE x IN (SELECT * FROM numbers(10000000))))))))))));
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM mergetree_00673 WHERE x IN (SELECT * FROM numbers(1000000))))))))))))))))))))));
|
||||
|
||||
SET force_primary_key = 1;
|
||||
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM mergetree_00673 WHERE x IN (SELECT * FROM numbers(10000000))))))))))));
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM mergetree_00673 WHERE x IN (SELECT * FROM numbers(1000000))))))))))))))))))))));
|
||||
|
||||
DROP TABLE mergetree_00673;
|
||||
|
@ -5,8 +5,8 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
yes 'CREATE TABLE IF NOT EXISTS table (x UInt8) ENGINE = MergeTree ORDER BY tuple();' | head -n 1000 | $CLICKHOUSE_CLIENT --ignore-error -nm 2>/dev/null &
|
||||
yes 'DROP TABLE table;' | head -n 1000 | $CLICKHOUSE_CLIENT --ignore-error -nm 2>/dev/null &
|
||||
yes 'CREATE TABLE IF NOT EXISTS table (x UInt8) ENGINE = MergeTree ORDER BY tuple();' | head -n 1000 | $CLICKHOUSE_CLIENT --multiquery &
|
||||
yes 'DROP TABLE IF EXISTS table;' | head -n 1000 | $CLICKHOUSE_CLIENT --multiquery &
|
||||
wait
|
||||
|
||||
${CLICKHOUSE_CLIENT} --query "DROP TABLE IF EXISTS table"
|
||||
|
@ -1,4 +0,0 @@
|
||||
275 0 138 136 0
|
||||
275 0
|
||||
275 0 138 136 0
|
||||
275 0
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tags: long, no-parallel, no-ordinary-database, no-debug
|
||||
# Tags: long, no-parallel, no-ordinary-database
|
||||
# Test is too heavy, avoid parallel run in Flaky Check
|
||||
# shellcheck disable=SC2119
|
||||
|
||||
@ -7,82 +7,126 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
set -e
|
||||
set -ue
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS src";
|
||||
$CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS dst";
|
||||
$CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS mv";
|
||||
$CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS tmp";
|
||||
$CLICKHOUSE_CLIENT --query "CREATE TABLE src (n Int8, m Int8, CONSTRAINT c CHECK xxHash32(n+m) % 8 != 0) ENGINE=MergeTree ORDER BY n PARTITION BY 0 < n SETTINGS old_parts_lifetime=0";
|
||||
$CLICKHOUSE_CLIENT --query "CREATE TABLE dst (nm Int16, CONSTRAINT c CHECK xxHash32(nm) % 8 != 0) ENGINE=MergeTree ORDER BY nm SETTINGS old_parts_lifetime=0";
|
||||
$CLICKHOUSE_CLIENT --query "CREATE MATERIALIZED VIEW mv TO dst (nm Int16) AS SELECT n*m AS nm FROM src";
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "CREATE TABLE tmp (x UInt8, nm Int16) ENGINE=MergeTree ORDER BY (x, nm) SETTINGS old_parts_lifetime=0"
|
||||
$CLICKHOUSE_CLIENT --query "CREATE TABLE src (n Int32, m Int32, CONSTRAINT c CHECK xxHash32(n+m) % 8 != 0) ENGINE=MergeTree ORDER BY n PARTITION BY 0 < n SETTINGS old_parts_lifetime=0";
|
||||
$CLICKHOUSE_CLIENT --query "CREATE TABLE dst (nm Int32, CONSTRAINT c CHECK xxHash32(nm) % 8 != 0) ENGINE=MergeTree ORDER BY nm SETTINGS old_parts_lifetime=0";
|
||||
$CLICKHOUSE_CLIENT --query "CREATE MATERIALIZED VIEW mv TO dst (nm Int32) AS SELECT n*m AS nm FROM src";
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "CREATE TABLE tmp (x UInt32, nm Int32) ENGINE=MergeTree ORDER BY (x, nm) SETTINGS old_parts_lifetime=0"
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "INSERT INTO src VALUES (0, 0)"
|
||||
|
||||
# some transactions will fail due to constraint
|
||||
function thread_insert_commit()
|
||||
function get_now()
|
||||
{
|
||||
set -e
|
||||
for i in {1..100}; do
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
BEGIN TRANSACTION;
|
||||
INSERT INTO src VALUES /* ($i, $1) */ ($i, $1);
|
||||
SELECT throwIf((SELECT sum(nm) FROM mv) != $(($i * $1))) FORMAT Null;
|
||||
INSERT INTO src VALUES /* (-$i, $1) */ (-$i, $1);
|
||||
COMMIT;" 2>&1| grep -Fv "is violated at row" | grep -Fv "Transaction is not in RUNNING state" | grep -F "Received from " ||:
|
||||
done
|
||||
date +%s
|
||||
}
|
||||
|
||||
function thread_insert_rollback()
|
||||
is_pid_exist()
|
||||
{
|
||||
local pid=$1
|
||||
ps -p $pid > /dev/null
|
||||
}
|
||||
|
||||
function run_until_deadline_and_at_least_times()
|
||||
{
|
||||
set -e
|
||||
for _ in {1..100}; do
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
BEGIN TRANSACTION;
|
||||
INSERT INTO src VALUES /* (42, $1) */ (42, $1);
|
||||
SELECT throwIf((SELECT count() FROM src WHERE n=42 AND m=$1) != 1) FORMAT Null;
|
||||
ROLLBACK;"
|
||||
|
||||
local deadline=$1; shift
|
||||
local min_iterations=$1; shift
|
||||
local function_to_run=$1; shift
|
||||
|
||||
local started_time
|
||||
started_time=$(get_now)
|
||||
local i=0
|
||||
|
||||
while true
|
||||
do
|
||||
$function_to_run $i "$@"
|
||||
|
||||
[[ $(get_now) -lt $deadline ]] || break
|
||||
|
||||
i=$(($i + 1))
|
||||
done
|
||||
|
||||
[[ $i -gt $min_iterations ]] || echo "$i/$min_iterations : not enough iterations of $function_to_run has been made from $started_time until $deadline" >&2
|
||||
}
|
||||
|
||||
function insert_commit_action()
|
||||
{
|
||||
set -e
|
||||
|
||||
local i=$1; shift
|
||||
local tag=$1; shift
|
||||
|
||||
# some transactions will fail due to constraint
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
BEGIN TRANSACTION;
|
||||
INSERT INTO src VALUES /* ($i, $tag) */ ($i, $tag);
|
||||
SELECT throwIf((SELECT sum(nm) FROM mv) != $(($i * $tag))) /* ($i, $tag) */ FORMAT Null;
|
||||
INSERT INTO src VALUES /* (-$i, $tag) */ (-$i, $tag);
|
||||
COMMIT;
|
||||
" 2>&1 \
|
||||
| grep -Fv "is violated at row" | grep -Fv "Transaction is not in RUNNING state" | grep -F "Received from " ||:
|
||||
}
|
||||
|
||||
|
||||
function insert_rollback_action()
|
||||
{
|
||||
set -e
|
||||
|
||||
local i=$1; shift
|
||||
local tag=$1; shift
|
||||
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
BEGIN TRANSACTION;
|
||||
INSERT INTO src VALUES /* (42, $tag) */ (42, $tag);
|
||||
SELECT throwIf((SELECT count() FROM src WHERE n=42 AND m=$tag) != 1) FORMAT Null;
|
||||
ROLLBACK;"
|
||||
}
|
||||
|
||||
# make merges more aggressive
|
||||
function thread_optimize()
|
||||
function optimize_action()
|
||||
{
|
||||
set -e
|
||||
while true; do
|
||||
optimize_query="OPTIMIZE TABLE src"
|
||||
partition_id=$(( RANDOM % 2 ))
|
||||
if (( RANDOM % 2 )); then
|
||||
optimize_query="OPTIMIZE TABLE dst"
|
||||
partition_id="all"
|
||||
fi
|
||||
if (( RANDOM % 2 )); then
|
||||
optimize_query="$optimize_query PARTITION ID '$partition_id'"
|
||||
fi
|
||||
if (( RANDOM % 2 )); then
|
||||
optimize_query="$optimize_query FINAL"
|
||||
fi
|
||||
action="COMMIT"
|
||||
if (( RANDOM % 4 )); then
|
||||
action="ROLLBACK"
|
||||
fi
|
||||
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
optimize_query="OPTIMIZE TABLE src"
|
||||
partition_id=$(( RANDOM % 2 ))
|
||||
if (( RANDOM % 2 )); then
|
||||
optimize_query="OPTIMIZE TABLE dst"
|
||||
partition_id="all"
|
||||
fi
|
||||
if (( RANDOM % 2 )); then
|
||||
optimize_query="$optimize_query PARTITION ID '$partition_id'"
|
||||
fi
|
||||
if (( RANDOM % 2 )); then
|
||||
optimize_query="$optimize_query FINAL"
|
||||
fi
|
||||
action="COMMIT"
|
||||
if (( RANDOM % 4 )); then
|
||||
action="ROLLBACK"
|
||||
fi
|
||||
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
BEGIN TRANSACTION;
|
||||
$optimize_query;
|
||||
$optimize_query;
|
||||
$action;
|
||||
" 2>&1| grep -Fv "already exists, but it will be deleted soon" | grep -F "Received from " ||:
|
||||
sleep 0.$RANDOM;
|
||||
done
|
||||
" 2>&1 \
|
||||
| grep -Fv "already exists, but it will be deleted soon" | grep -F "Received from " ||:
|
||||
|
||||
sleep 0.$RANDOM;
|
||||
}
|
||||
|
||||
function thread_select()
|
||||
function select_action()
|
||||
{
|
||||
set -e
|
||||
while true; do
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
BEGIN TRANSACTION;
|
||||
SELECT throwIf((SELECT (sum(n), count() % 2) FROM src) != (0, 1)) FORMAT Null;
|
||||
SELECT throwIf((SELECT (sum(nm), count() % 2) FROM mv) != (0, 1)) FORMAT Null;
|
||||
@ -90,14 +134,13 @@ function thread_select()
|
||||
SELECT throwIf((SELECT arraySort(groupArray(nm)) FROM mv) != (SELECT arraySort(groupArray(nm)) FROM dst)) FORMAT Null;
|
||||
SELECT throwIf((SELECT arraySort(groupArray(nm)) FROM mv) != (SELECT arraySort(groupArray(n*m)) FROM src)) FORMAT Null;
|
||||
COMMIT;"
|
||||
done
|
||||
}
|
||||
|
||||
function thread_select_insert()
|
||||
function select_insert_action()
|
||||
{
|
||||
set -e
|
||||
while true; do
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
BEGIN TRANSACTION;
|
||||
SELECT throwIf((SELECT count() FROM tmp) != 0) FORMAT Null;
|
||||
INSERT INTO tmp SELECT 1, n*m FROM src;
|
||||
@ -110,36 +153,69 @@ function thread_select_insert()
|
||||
SELECT throwIf(1 != (SELECT countDistinct(arr) FROM (SELECT x, arraySort(groupArray(nm)) AS arr FROM tmp WHERE x!=4 GROUP BY x))) FORMAT Null;
|
||||
SELECT throwIf((SELECT count(), sum(nm) FROM tmp WHERE x=4) != (SELECT count(), sum(nm) FROM tmp WHERE x!=4)) FORMAT Null;
|
||||
ROLLBACK;"
|
||||
done
|
||||
}
|
||||
|
||||
thread_insert_commit 1 & PID_1=$!
|
||||
thread_insert_commit 2 & PID_2=$!
|
||||
thread_insert_rollback 3 & PID_3=$!
|
||||
MAIN_TIME_PART=400
|
||||
SECOND_TIME_PART=30
|
||||
WAIT_FINISH=60
|
||||
LAST_TIME_GAP=10
|
||||
|
||||
thread_optimize & PID_4=$!
|
||||
thread_select & PID_5=$!
|
||||
thread_select_insert & PID_6=$!
|
||||
sleep 0.$RANDOM;
|
||||
thread_select & PID_7=$!
|
||||
thread_select_insert & PID_8=$!
|
||||
if [[ $((MAIN_TIME_PART + SECOND_TIME_PART + WAIT_FINISH + LAST_TIME_GAP)) -ge 600 ]]; then
|
||||
echo "time sttings are wrong" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
wait $PID_1 && wait $PID_2 && wait $PID_3
|
||||
kill -TERM $PID_4
|
||||
kill -TERM $PID_5
|
||||
kill -TERM $PID_6
|
||||
kill -TERM $PID_7
|
||||
kill -TERM $PID_8
|
||||
wait
|
||||
wait_for_queries_to_finish 40
|
||||
START_TIME=$(get_now)
|
||||
STOP_TIME=$((START_TIME + MAIN_TIME_PART))
|
||||
SECOND_STOP_TIME=$((STOP_TIME + SECOND_TIME_PART))
|
||||
MIN_ITERATIONS=20
|
||||
|
||||
run_until_deadline_and_at_least_times $STOP_TIME $MIN_ITERATIONS insert_commit_action 1 & PID_1=$!
|
||||
run_until_deadline_and_at_least_times $STOP_TIME $MIN_ITERATIONS insert_commit_action 2 & PID_2=$!
|
||||
run_until_deadline_and_at_least_times $STOP_TIME $MIN_ITERATIONS insert_rollback_action 3 & PID_3=$!
|
||||
|
||||
run_until_deadline_and_at_least_times $SECOND_STOP_TIME $MIN_ITERATIONS optimize_action & PID_4=$!
|
||||
run_until_deadline_and_at_least_times $SECOND_STOP_TIME $MIN_ITERATIONS select_action & PID_5=$!
|
||||
run_until_deadline_and_at_least_times $SECOND_STOP_TIME $MIN_ITERATIONS select_insert_action & PID_6=$!
|
||||
sleep 0.$RANDOM
|
||||
run_until_deadline_and_at_least_times $SECOND_STOP_TIME $MIN_ITERATIONS select_action & PID_7=$!
|
||||
run_until_deadline_and_at_least_times $SECOND_STOP_TIME $MIN_ITERATIONS select_insert_action & PID_8=$!
|
||||
|
||||
wait $PID_1 || echo "insert_commit_action has failed with status $?" 2>&1
|
||||
wait $PID_2 || echo "second insert_commit_action has failed with status $?" 2>&1
|
||||
wait $PID_3 || echo "insert_rollback_action has failed with status $?" 2>&1
|
||||
|
||||
is_pid_exist $PID_4 || echo "optimize_action is not running" 2>&1
|
||||
is_pid_exist $PID_5 || echo "select_action is not running" 2>&1
|
||||
is_pid_exist $PID_6 || echo "select_insert_action is not running" 2>&1
|
||||
is_pid_exist $PID_7 || echo "second select_action is not running" 2>&1
|
||||
is_pid_exist $PID_8 || echo "second select_insert_action is not running" 2>&1
|
||||
|
||||
wait $PID_4 || echo "optimize_action has failed with status $?" 2>&1
|
||||
wait $PID_5 || echo "select_action has failed with status $?" 2>&1
|
||||
wait $PID_6 || echo "select_insert_action has failed with status $?" 2>&1
|
||||
wait $PID_7 || echo "second select_action has failed with status $?" 2>&1
|
||||
wait $PID_8 || echo "second select_insert_action has failed with status $?" 2>&1
|
||||
|
||||
wait_for_queries_to_finish $WAIT_FINISH
|
||||
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
BEGIN TRANSACTION;
|
||||
SELECT count(), sum(n), sum(m=1), sum(m=2), sum(m=3) FROM src;
|
||||
SELECT count(), sum(nm) FROM mv";
|
||||
BEGIN TRANSACTION;
|
||||
SELECT throwIf((SELECT (sum(n), count() % 2) FROM src) != (0, 1)) FORMAT Null;
|
||||
SELECT throwIf((SELECT (sum(nm), count() % 2) FROM mv) != (0, 1)) FORMAT Null;
|
||||
SELECT throwIf((SELECT (sum(nm), count() % 2) FROM dst) != (0, 1)) FORMAT Null;
|
||||
SELECT throwIf((SELECT arraySort(groupArray(nm)) FROM mv) != (SELECT arraySort(groupArray(nm)) FROM dst)) FORMAT Null;
|
||||
SELECT throwIf((SELECT arraySort(groupArray(nm)) FROM mv) != (SELECT arraySort(groupArray(n*m)) FROM src)) FORMAT Null;
|
||||
COMMIT;
|
||||
"
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "SELECT count(), sum(n), sum(m=1), sum(m=2), sum(m=3) FROM src"
|
||||
$CLICKHOUSE_CLIENT --query "SELECT count(), sum(nm) FROM mv"
|
||||
$CLICKHOUSE_CLIENT --multiquery --query "
|
||||
SELECT throwIf((SELECT (sum(n), count() % 2) FROM src) != (0, 1)) FORMAT Null;
|
||||
SELECT throwIf((SELECT (sum(nm), count() % 2) FROM mv) != (0, 1)) FORMAT Null;
|
||||
SELECT throwIf((SELECT (sum(nm), count() % 2) FROM dst) != (0, 1)) FORMAT Null;
|
||||
SELECT throwIf((SELECT arraySort(groupArray(nm)) FROM mv) != (SELECT arraySort(groupArray(nm)) FROM dst)) FORMAT Null;
|
||||
SELECT throwIf((SELECT arraySort(groupArray(nm)) FROM mv) != (SELECT arraySort(groupArray(n*m)) FROM src)) FORMAT Null;
|
||||
"
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "DROP TABLE src";
|
||||
$CLICKHOUSE_CLIENT --query "DROP TABLE dst";
|
||||
|
@ -32,10 +32,10 @@
|
||||
1
|
||||
1
|
||||
0
|
||||
SELECT count() AS `count()`
|
||||
SELECT count()
|
||||
FROM constraint_test_constants
|
||||
WHERE (b > 100) OR (c > 100)
|
||||
SELECT count() AS `count()`
|
||||
SELECT count()
|
||||
FROM constraint_test_constants
|
||||
WHERE c > 100
|
||||
QUERY id: 0
|
||||
@ -53,7 +53,7 @@ QUERY id: 0
|
||||
COLUMN id: 6, column_name: c, result_type: Int64, source_id: 3
|
||||
CONSTANT id: 7, constant_value: UInt64_100, constant_value_type: UInt8
|
||||
SETTINGS allow_experimental_analyzer=1
|
||||
SELECT count() AS `count()`
|
||||
SELECT count()
|
||||
FROM constraint_test_constants
|
||||
WHERE c > 100
|
||||
QUERY id: 0
|
||||
@ -71,7 +71,7 @@ QUERY id: 0
|
||||
COLUMN id: 6, column_name: c, result_type: Int64, source_id: 3
|
||||
CONSTANT id: 7, constant_value: UInt64_100, constant_value_type: UInt8
|
||||
SETTINGS allow_experimental_analyzer=1
|
||||
SELECT count() AS `count()`
|
||||
SELECT count()
|
||||
FROM constraint_test_constants
|
||||
QUERY id: 0
|
||||
PROJECTION COLUMNS
|
||||
|
@ -1,6 +1,6 @@
|
||||
SELECT
|
||||
(b AS `cityHash64(a)`) + 10 AS `plus(cityHash64(a), 10)`,
|
||||
(b AS b) + 3 AS `plus(b, 3)`
|
||||
(b AS `cityHash64(a)`) + 10,
|
||||
(b AS b) + 3
|
||||
FROM column_swap_test_test
|
||||
WHERE b = 1
|
||||
QUERY id: 0
|
||||
@ -59,8 +59,8 @@ QUERY id: 0
|
||||
CONSTANT id: 14, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
SETTINGS allow_experimental_analyzer=1
|
||||
SELECT
|
||||
(b AS `cityHash64(a)`) + 10 AS `plus(cityHash64(a), 10)`,
|
||||
(b AS b) + 3 AS `plus(b, 3)`
|
||||
(b AS `cityHash64(a)`) + 10,
|
||||
(b AS b) + 3
|
||||
FROM column_swap_test_test
|
||||
WHERE b = 0
|
||||
QUERY id: 0
|
||||
@ -89,8 +89,8 @@ QUERY id: 0
|
||||
CONSTANT id: 14, constant_value: UInt64_0, constant_value_type: UInt8
|
||||
SETTINGS allow_experimental_analyzer=1
|
||||
SELECT
|
||||
(b AS `cityHash64(a)`) + 10 AS `plus(cityHash64(a), 10)`,
|
||||
(b AS b) + 3 AS `plus(b, 3)`
|
||||
(b AS `cityHash64(a)`) + 10,
|
||||
(b AS b) + 3
|
||||
FROM column_swap_test_test
|
||||
WHERE b = 0
|
||||
QUERY id: 0
|
||||
@ -119,8 +119,8 @@ QUERY id: 0
|
||||
CONSTANT id: 14, constant_value: UInt64_0, constant_value_type: UInt8
|
||||
SETTINGS allow_experimental_analyzer=1
|
||||
SELECT
|
||||
(b AS `cityHash64(a)`) + 10 AS `plus(cityHash64(a), 10)`,
|
||||
(b AS b) + 3 AS `plus(b, 3)`
|
||||
(b AS `cityHash64(a)`) + 10,
|
||||
(b AS b) + 3
|
||||
FROM column_swap_test_test
|
||||
WHERE b = 1
|
||||
QUERY id: 0
|
||||
@ -148,7 +148,7 @@ QUERY id: 0
|
||||
COLUMN id: 13, column_name: b, result_type: UInt64, source_id: 5
|
||||
CONSTANT id: 14, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
SETTINGS allow_experimental_analyzer=1
|
||||
SELECT (b AS `cityHash64(a)`) + 10 AS `plus(cityHash64(a), 10)`
|
||||
SELECT (b AS `cityHash64(a)`) + 10
|
||||
FROM column_swap_test_test
|
||||
WHERE b = 0
|
||||
QUERY id: 0
|
||||
@ -171,8 +171,8 @@ QUERY id: 0
|
||||
CONSTANT id: 10, constant_value: UInt64_0, constant_value_type: UInt8
|
||||
SETTINGS allow_experimental_analyzer=1
|
||||
SELECT
|
||||
(cityHash64(a) AS `cityHash64(a)`) + 10 AS `plus(cityHash64(a), 10)`,
|
||||
a AS a
|
||||
(cityHash64(a) AS `cityHash64(a)`) + 10,
|
||||
a
|
||||
FROM column_swap_test_test
|
||||
WHERE cityHash64(a) = 0
|
||||
QUERY id: 0
|
||||
@ -203,8 +203,8 @@ QUERY id: 0
|
||||
CONSTANT id: 15, constant_value: UInt64_0, constant_value_type: UInt8
|
||||
SETTINGS allow_experimental_analyzer=1
|
||||
SELECT
|
||||
(cityHash64(a) AS b) + 10 AS `plus(b, 10)`,
|
||||
a AS a
|
||||
(cityHash64(a) AS b) + 10,
|
||||
a
|
||||
FROM column_swap_test_test
|
||||
WHERE cityHash64(a) = 0
|
||||
QUERY id: 0
|
||||
|
@ -10,18 +10,38 @@ DEBUG_LOG = os.path.join(
|
||||
os.path.basename(os.path.abspath(__file__)).strip(".python") + ".debuglog",
|
||||
)
|
||||
|
||||
STATE_MAP = {
|
||||
-1: "process did not start",
|
||||
0: "completion was found",
|
||||
1: "process started and said ':)'",
|
||||
2: "completion search was started",
|
||||
3: "completion is missing",
|
||||
}
|
||||
|
||||
|
||||
def run_with_timeout(func, args, timeout):
|
||||
process = multiprocessing.Process(target=func, args=args)
|
||||
process.start()
|
||||
process.join(timeout)
|
||||
for _ in range(5):
|
||||
state = multiprocessing.Value("i", -1)
|
||||
process = multiprocessing.Process(
|
||||
target=func, args=args, kwargs={"state": state}
|
||||
)
|
||||
process.start()
|
||||
process.join(timeout)
|
||||
|
||||
if process.is_alive():
|
||||
process.terminate()
|
||||
print("Timeout")
|
||||
if state.value in (0, 3):
|
||||
return
|
||||
|
||||
if process.is_alive():
|
||||
process.terminate()
|
||||
|
||||
if state.value == -1:
|
||||
continue
|
||||
|
||||
print(f"Timeout, state: {STATE_MAP[state.value]}")
|
||||
return
|
||||
|
||||
|
||||
def test_completion(program, argv, comp_word):
|
||||
def test_completion(program, argv, comp_word, state=None):
|
||||
comp_begin = comp_word[:-3]
|
||||
|
||||
shell_pid, master = pty.fork()
|
||||
@ -41,6 +61,8 @@ def test_completion(program, argv, comp_word):
|
||||
debug_log_fd.write(repr(output_b) + "\n")
|
||||
debug_log_fd.flush()
|
||||
|
||||
state.value = 1
|
||||
|
||||
os.write(master, b"SET " + bytes(comp_begin.encode()))
|
||||
output_b = os.read(master, 4096)
|
||||
output = output_b.decode()
|
||||
@ -55,23 +77,28 @@ def test_completion(program, argv, comp_word):
|
||||
time.sleep(0.01)
|
||||
os.write(master, b"\t")
|
||||
|
||||
state.value = 2
|
||||
|
||||
output_b = os.read(master, 4096)
|
||||
output = output_b.decode()
|
||||
debug_log_fd.write(repr(output_b) + "\n")
|
||||
debug_log_fd.flush()
|
||||
# fail fast if there is a bell character in the output,
|
||||
# meaning no concise completion is found
|
||||
if "\x07" in output:
|
||||
print(f"{comp_word}: FAIL")
|
||||
return
|
||||
|
||||
while not comp_word in output:
|
||||
# fail fast if there is a bell character in the output,
|
||||
# meaning no concise completion is found
|
||||
if "\x07" in output:
|
||||
print(f"{comp_word}: FAIL")
|
||||
state.value = 3
|
||||
return
|
||||
|
||||
output_b = os.read(master, 4096)
|
||||
output += output_b.decode()
|
||||
debug_log_fd.write(repr(output_b) + "\n")
|
||||
debug_log_fd.flush()
|
||||
|
||||
print(f"{comp_word}: OK")
|
||||
state.value = 0
|
||||
finally:
|
||||
os.close(master)
|
||||
debug_log_fd.close()
|
||||
|
@ -1,4 +1,6 @@
|
||||
#!/usr/bin/expect -f
|
||||
# Tags: no-debug, no-tsan, no-msan, no-asan, no-ubsan, no-s3-storage
|
||||
# ^ it can be slower than 60 seconds
|
||||
|
||||
# This is the regression for the concurrent access in ProgressIndication,
|
||||
# so it is important to read enough rows here (10e6).
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tags: no-ubsan, no-fasttest, no-tsan
|
||||
# Tags: no-ubsan, no-fasttest, no-tsan, no-msan, no-asan
|
||||
# It is too slow under TSan
|
||||
# It eats too much memory under ASan or MSan
|
||||
|
||||
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
|
@ -0,0 +1,4 @@
|
||||
create table dist as system.one engine=Distributed(test_shard_localhost, system, one);
|
||||
select sleep(8) from dist settings function_sleep_max_microseconds_per_block=8e9, prefer_localhost_replica=0, receive_timeout=7, async_socket_for_remote=0, use_hedged_requests=1 format Null;
|
||||
select sleep(8) from dist settings function_sleep_max_microseconds_per_block=8e9, prefer_localhost_replica=0, receive_timeout=7, async_socket_for_remote=1, use_hedged_requests=0 format Null;
|
||||
select sleep(8) from dist settings function_sleep_max_microseconds_per_block=8e9, prefer_localhost_replica=0, receive_timeout=7, async_socket_for_remote=0, use_hedged_requests=0 format Null;
|
@ -39,11 +39,22 @@ SELECT * FROM t1 JOIN t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS N
|
||||
2 2 2 2
|
||||
3 3 3 33
|
||||
\N \N \N \N
|
||||
SELECT * FROM t1 JOIN t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( t2.x <> t1.x AND t2.x <> t1.x ) ORDER BY t1.x NULLS LAST; -- { serverError INVALID_JOIN_ON_EXPRESSION }
|
||||
SELECT * FROM t1 JOIN t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( t2.x <> t1.x AND (t2.x IS NULL) AND (t2.x IS NULL) ) ORDER BY t1.x NULLS LAST; -- { serverError INVALID_JOIN_ON_EXPRESSION }
|
||||
-- aliases defined in the join condition are valid
|
||||
-- FIXME(@vdimir) broken query formatting for the following queries:
|
||||
-- SELECT *, e, e2 FROM t1 FULL JOIN t2 ON ( ( ((t1.x == t2.x) AS e) AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( (t2.x IS NULL) AND (t1.x IS NULL) ) AS e2 ) ORDER BY t1.x NULLS LAST, t2.x NULLS LAST;
|
||||
-- SELECT *, e, e2 FROM t1 FULL JOIN t2 ON ( ( ((t1.x == t2.x) AS e) AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) AS e2 ) ORDER BY t1.x NULLS LAST, t2.x NULLS LAST;
|
||||
|
||||
SELECT *, e, e2 FROM t1 FULL JOIN t2 ON ( ( ((t1.x == t2.x) AS e) AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( (t2.x IS NULL) AND (t1.x IS NULL) ) AS e2 ) ORDER BY t1.x NULLS LAST, t2.x NULLS LAST;
|
||||
1 42 \N \N \N 0
|
||||
2 2 2 2 1 1
|
||||
3 3 3 33 1 1
|
||||
\N \N 4 42 \N 0
|
||||
\N \N \N \N \N 1
|
||||
SELECT *, e, e2 FROM t1 FULL JOIN t2 ON ( ( ((t1.x == t2.x) AS e) AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) AS e2 ) ORDER BY t1.x NULLS LAST, t2.x NULLS LAST;
|
||||
1 42 \N \N \N 0
|
||||
2 2 2 2 1 1
|
||||
3 3 3 33 1 1
|
||||
\N \N 4 42 \N 0
|
||||
\N \N \N \N \N 0
|
||||
\N \N \N \N \N 0
|
||||
-- check for non-nullable columns for which `is null` is replaced with constant
|
||||
SELECT * FROM t1n as t1 JOIN t2n as t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( (t2.x IS NULL) AND (t1.x IS NULL) ) ORDER BY t1.x NULLS LAST;
|
||||
2 2 2 2
|
||||
|
@ -35,11 +35,12 @@ SELECT x = y OR (x IS NULL AND y IS NULL) FROM t1 ORDER BY x NULLS LAST;
|
||||
|
||||
SELECT * FROM t1 JOIN t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( (t2.x IS NULL) AND (t1.x IS NULL) ) ORDER BY t1.x NULLS LAST;
|
||||
SELECT * FROM t1 JOIN t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( t2.x <> t1.x AND (t2.x IS NULL) AND (t1.x IS NULL) ) ORDER BY t1.x NULLS LAST;
|
||||
SELECT * FROM t1 JOIN t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( t2.x <> t1.x AND t2.x <> t1.x ) ORDER BY t1.x NULLS LAST; -- { serverError INVALID_JOIN_ON_EXPRESSION }
|
||||
SELECT * FROM t1 JOIN t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( t2.x <> t1.x AND (t2.x IS NULL) AND (t2.x IS NULL) ) ORDER BY t1.x NULLS LAST; -- { serverError INVALID_JOIN_ON_EXPRESSION }
|
||||
|
||||
-- aliases defined in the join condition are valid
|
||||
-- FIXME(@vdimir) broken query formatting for the following queries:
|
||||
-- SELECT *, e, e2 FROM t1 FULL JOIN t2 ON ( ( ((t1.x == t2.x) AS e) AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( (t2.x IS NULL) AND (t1.x IS NULL) ) AS e2 ) ORDER BY t1.x NULLS LAST, t2.x NULLS LAST;
|
||||
-- SELECT *, e, e2 FROM t1 FULL JOIN t2 ON ( ( ((t1.x == t2.x) AS e) AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) AS e2 ) ORDER BY t1.x NULLS LAST, t2.x NULLS LAST;
|
||||
SELECT *, e, e2 FROM t1 FULL JOIN t2 ON ( ( ((t1.x == t2.x) AS e) AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( (t2.x IS NULL) AND (t1.x IS NULL) ) AS e2 ) ORDER BY t1.x NULLS LAST, t2.x NULLS LAST;
|
||||
SELECT *, e, e2 FROM t1 FULL JOIN t2 ON ( ( ((t1.x == t2.x) AS e) AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) AS e2 ) ORDER BY t1.x NULLS LAST, t2.x NULLS LAST;
|
||||
|
||||
-- check for non-nullable columns for which `is null` is replaced with constant
|
||||
SELECT * FROM t1n as t1 JOIN t2n as t2 ON (t1.x == t2.x AND ((t2.x IS NOT NULL) AND (t1.x IS NOT NULL)) ) OR ( (t2.x IS NULL) AND (t1.x IS NULL) ) ORDER BY t1.x NULLS LAST;
|
||||
|
@ -0,0 +1,30 @@
|
||||
|
||||
simple join with analyzer
|
||||
4200000 4200000 4200000 -1400000
|
||||
4200006 4200006 4200006 -1400002
|
||||
4200012 4200012 4200012 -1400004
|
||||
4200018 4200018 4200018 -1400006
|
||||
4200024 4200024 4200024 -1400008
|
||||
4200030 4200030 4200030 -1400010
|
||||
4200036 4200036 4200036 -1400012
|
||||
4200042 4200042 4200042 -1400014
|
||||
4200048 4200048 4200048 -1400016
|
||||
4200054 4200054 4200054 -1400018
|
||||
|
||||
simple (global) join with analyzer and parallel replicas
|
||||
4200000 4200000 4200000 -1400000
|
||||
4200006 4200006 4200006 -1400002
|
||||
4200012 4200012 4200012 -1400004
|
||||
4200018 4200018 4200018 -1400006
|
||||
4200024 4200024 4200024 -1400008
|
||||
4200030 4200030 4200030 -1400010
|
||||
4200036 4200036 4200036 -1400012
|
||||
4200042 4200042 4200042 -1400014
|
||||
4200048 4200048 4200048 -1400016
|
||||
4200054 4200054 4200054 -1400018
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value` FROM `default`.`num_2` AS `__table1` (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value` FROM `default`.`num_2` AS `__table1` (stage: WithMergeableState)
|
||||
<Debug> DefaultCoordinator: Coordination done
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` GLOBAL ALL INNER JOIN `_data_` AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` GLOBAL ALL INNER JOIN `_data_` AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
<Debug> DefaultCoordinator: Coordination done
|
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tags: long, no-random-settings, no-random-merge-tree-settings
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
|
||||
$CLICKHOUSE_CLIENT -nm -q "
|
||||
drop table if exists num_1;
|
||||
drop table if exists num_2;
|
||||
|
||||
create table num_1 (key UInt64, value String) engine = MergeTree order by key;
|
||||
create table num_2 (key UInt64, value Int64) engine = MergeTree order by key;
|
||||
|
||||
insert into num_1 select number * 2, toString(number * 2) from numbers(1e7);
|
||||
insert into num_2 select number * 3, -number from numbers(1.5e6);
|
||||
"
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "simple join with analyzer"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1"
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "simple (global) join with analyzer and parallel replicas"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, allow_experimental_parallel_reading_from_replicas = 2,
|
||||
max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=0"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, allow_experimental_parallel_reading_from_replicas = 2, send_logs_level='trace',
|
||||
max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=0" 2>&1 |
|
||||
grep "executeQuery\|<Debug>.*Coordinator: Coordination done" |
|
||||
grep -o "SELECT.*WithMergeableState)\|<Debug>.*Coordinator: Coordination done" |
|
||||
sed -re 's/_data_[[:digit:]]+_[[:digit:]]+/_data_/g'
|
@ -0,0 +1,57 @@
|
||||
|
||||
simple (local) join with analyzer and parallel replicas
|
||||
4200000 4200000 4200000 -1400000
|
||||
4200006 4200006 4200006 -1400002
|
||||
4200012 4200012 4200012 -1400004
|
||||
4200018 4200018 4200018 -1400006
|
||||
4200024 4200024 4200024 -1400008
|
||||
4200030 4200030 4200030 -1400010
|
||||
4200036 4200036 4200036 -1400012
|
||||
4200042 4200042 4200042 -1400014
|
||||
4200048 4200048 4200048 -1400016
|
||||
4200054 4200054 4200054 -1400018
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4`) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4`) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
<Debug> DefaultCoordinator: Coordination done
|
||||
|
||||
simple (local) join with analyzer and parallel replicas and full sorting merge join
|
||||
4200000 4200000 4200000 -1400000
|
||||
4200006 4200006 4200006 -1400002
|
||||
4200012 4200012 4200012 -1400004
|
||||
4200018 4200018 4200018 -1400006
|
||||
4200024 4200024 4200024 -1400008
|
||||
4200030 4200030 4200030 -1400010
|
||||
4200036 4200036 4200036 -1400012
|
||||
4200042 4200042 4200042 -1400014
|
||||
4200048 4200048 4200048 -1400016
|
||||
4200054 4200054 4200054 -1400018
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4`) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4`) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
<Debug> WithOrderCoordinator: Coordination done
|
||||
|
||||
nested join with analyzer
|
||||
420000 420000 420000 -140000
|
||||
420042 420042 420042 -140014
|
||||
420084 420084 420084 -140028
|
||||
420126 420126 420126 -140042
|
||||
420168 420168 420168 -140056
|
||||
420210 420210 420210 -140070
|
||||
420252 420252 420252 -140084
|
||||
420294 420294 420294 -140098
|
||||
420336 420336 420336 -140112
|
||||
420378 420378 420378 -140126
|
||||
|
||||
nested join with analyzer and parallel replicas, both local
|
||||
420000 420000 420000 -140000
|
||||
420042 420042 420042 -140014
|
||||
420084 420084 420084 -140028
|
||||
420126 420126 420126 -140042
|
||||
420168 420168 420168 -140056
|
||||
420210 420210 420210 -140070
|
||||
420252 420252 420252 -140084
|
||||
420294 420294 420294 -140098
|
||||
420336 420336 420336 -140112
|
||||
420378 420378 420378 -140126
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4` ALL INNER JOIN (SELECT `__table6`.`number` * 7 AS `key` FROM numbers(100000.) AS `__table6`) AS `__table5` ON `__table4`.`key` = `__table5`.`key` SETTINGS parallel_replicas_prefer_local_join = 1) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(10000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4` ALL INNER JOIN (SELECT `__table6`.`number` * 7 AS `key` FROM numbers(100000.) AS `__table6`) AS `__table5` ON `__table4`.`key` = `__table5`.`key` SETTINGS parallel_replicas_prefer_local_join = 1) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(10000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
<Debug> WithOrderCoordinator: Coordination done
|
103
tests/queries/0_stateless/02967_parallel_replicas_join_algo_and_analyzer_2.sh
Executable file
103
tests/queries/0_stateless/02967_parallel_replicas_join_algo_and_analyzer_2.sh
Executable file
@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tags: long, no-random-settings, no-random-merge-tree-settings
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
|
||||
$CLICKHOUSE_CLIENT -nm -q "
|
||||
drop table if exists num_1;
|
||||
drop table if exists num_2;
|
||||
|
||||
create table num_1 (key UInt64, value String) engine = MergeTree order by key;
|
||||
create table num_2 (key UInt64, value Int64) engine = MergeTree order by key;
|
||||
|
||||
insert into num_1 select number * 2, toString(number * 2) from numbers(1e7);
|
||||
insert into num_2 select number * 3, -number from numbers(1.5e6);
|
||||
"
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "simple (local) join with analyzer and parallel replicas"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1,
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, send_logs_level='trace',
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1" 2>&1 |
|
||||
grep "executeQuery\|<Debug>.*Coordinator: Coordination done" |
|
||||
grep -o "SELECT.*WithMergeableState)\|<Debug>.*Coordinator: Coordination done" |
|
||||
sed -re 's/_data_[[:digit:]]+_[[:digit:]]+/_data_/g'
|
||||
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "simple (local) join with analyzer and parallel replicas and full sorting merge join"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, join_algorithm='full_sorting_merge',
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, join_algorithm='full_sorting_merge', send_logs_level='trace',
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1" 2>&1 |
|
||||
grep "executeQuery\|<Debug>.*Coordinator: Coordination done" |
|
||||
grep -o "SELECT.*WithMergeableState)\|<Debug>.*Coordinator: Coordination done" |
|
||||
sed -re 's/_data_[[:digit:]]+_[[:digit:]]+/_data_/g'
|
||||
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "nested join with analyzer"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2 inner join
|
||||
(select number * 7 as key from numbers(1e5)) as nn on num_2.key = nn.key settings parallel_replicas_prefer_local_join=1) r
|
||||
on l.key = r.key order by l.key limit 10 offset 10000
|
||||
SETTINGS allow_experimental_analyzer=1"
|
||||
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "nested join with analyzer and parallel replicas, both local"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2 inner join
|
||||
(select number * 7 as key from numbers(1e5)) as nn on num_2.key = nn.key settings parallel_replicas_prefer_local_join=1) r
|
||||
on l.key = r.key order by l.key limit 10 offset 10000
|
||||
SETTINGS allow_experimental_analyzer=1,
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2 inner join
|
||||
(select number * 7 as key from numbers(1e5)) as nn on num_2.key = nn.key settings parallel_replicas_prefer_local_join=1) r
|
||||
on l.key = r.key order by l.key limit 10 offset 10000
|
||||
SETTINGS allow_experimental_analyzer=1, join_algorithm='full_sorting_merge', send_logs_level='trace',
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1" 2>&1 |
|
||||
grep "executeQuery\|<Debug>.*Coordinator: Coordination done" |
|
||||
grep -o "SELECT.*WithMergeableState)\|<Debug>.*Coordinator: Coordination done" |
|
||||
sed -re 's/_data_[[:digit:]]+_[[:digit:]]+/_data_/g'
|
@ -1,91 +1,4 @@
|
||||
|
||||
simple join with analyzer
|
||||
4200000 4200000 4200000 -1400000
|
||||
4200006 4200006 4200006 -1400002
|
||||
4200012 4200012 4200012 -1400004
|
||||
4200018 4200018 4200018 -1400006
|
||||
4200024 4200024 4200024 -1400008
|
||||
4200030 4200030 4200030 -1400010
|
||||
4200036 4200036 4200036 -1400012
|
||||
4200042 4200042 4200042 -1400014
|
||||
4200048 4200048 4200048 -1400016
|
||||
4200054 4200054 4200054 -1400018
|
||||
|
||||
simple (global) join with analyzer and parallel replicas
|
||||
4200000 4200000 4200000 -1400000
|
||||
4200006 4200006 4200006 -1400002
|
||||
4200012 4200012 4200012 -1400004
|
||||
4200018 4200018 4200018 -1400006
|
||||
4200024 4200024 4200024 -1400008
|
||||
4200030 4200030 4200030 -1400010
|
||||
4200036 4200036 4200036 -1400012
|
||||
4200042 4200042 4200042 -1400014
|
||||
4200048 4200048 4200048 -1400016
|
||||
4200054 4200054 4200054 -1400018
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value` FROM `default`.`num_2` AS `__table1` (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value` FROM `default`.`num_2` AS `__table1` (stage: WithMergeableState)
|
||||
<Debug> DefaultCoordinator: Coordination done
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` GLOBAL ALL INNER JOIN `_data_` AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` GLOBAL ALL INNER JOIN `_data_` AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
<Debug> DefaultCoordinator: Coordination done
|
||||
|
||||
simple (local) join with analyzer and parallel replicas
|
||||
4200000 4200000 4200000 -1400000
|
||||
4200006 4200006 4200006 -1400002
|
||||
4200012 4200012 4200012 -1400004
|
||||
4200018 4200018 4200018 -1400006
|
||||
4200024 4200024 4200024 -1400008
|
||||
4200030 4200030 4200030 -1400010
|
||||
4200036 4200036 4200036 -1400012
|
||||
4200042 4200042 4200042 -1400014
|
||||
4200048 4200048 4200048 -1400016
|
||||
4200054 4200054 4200054 -1400018
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4`) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4`) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
<Debug> DefaultCoordinator: Coordination done
|
||||
|
||||
simple (local) join with analyzer and parallel replicas and full sorting merge join
|
||||
4200000 4200000 4200000 -1400000
|
||||
4200006 4200006 4200006 -1400002
|
||||
4200012 4200012 4200012 -1400004
|
||||
4200018 4200018 4200018 -1400006
|
||||
4200024 4200024 4200024 -1400008
|
||||
4200030 4200030 4200030 -1400010
|
||||
4200036 4200036 4200036 -1400012
|
||||
4200042 4200042 4200042 -1400014
|
||||
4200048 4200048 4200048 -1400016
|
||||
4200054 4200054 4200054 -1400018
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4`) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4`) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(700000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
<Debug> WithOrderCoordinator: Coordination done
|
||||
|
||||
nested join with analyzer
|
||||
420000 420000 420000 -140000
|
||||
420042 420042 420042 -140014
|
||||
420084 420084 420084 -140028
|
||||
420126 420126 420126 -140042
|
||||
420168 420168 420168 -140056
|
||||
420210 420210 420210 -140070
|
||||
420252 420252 420252 -140084
|
||||
420294 420294 420294 -140098
|
||||
420336 420336 420336 -140112
|
||||
420378 420378 420378 -140126
|
||||
|
||||
nested join with analyzer and parallel replicas, both local
|
||||
420000 420000 420000 -140000
|
||||
420042 420042 420042 -140014
|
||||
420084 420084 420084 -140028
|
||||
420126 420126 420126 -140042
|
||||
420168 420168 420168 -140056
|
||||
420210 420210 420210 -140070
|
||||
420252 420252 420252 -140084
|
||||
420294 420294 420294 -140098
|
||||
420336 420336 420336 -140112
|
||||
420378 420378 420378 -140126
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4` ALL INNER JOIN (SELECT `__table6`.`number` * 7 AS `key` FROM numbers(100000.) AS `__table6`) AS `__table5` ON `__table4`.`key` = `__table5`.`key` SETTINGS parallel_replicas_prefer_local_join = 1) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(10000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
SELECT `__table1`.`key` AS `key`, `__table1`.`value` AS `value`, `__table3`.`key` AS `r.key`, `__table3`.`value` AS `r.value` FROM (SELECT `__table2`.`key` AS `key`, `__table2`.`value` AS `value` FROM `default`.`num_1` AS `__table2`) AS `__table1` ALL INNER JOIN (SELECT `__table4`.`key` AS `key`, `__table4`.`value` AS `value` FROM `default`.`num_2` AS `__table4` ALL INNER JOIN (SELECT `__table6`.`number` * 7 AS `key` FROM numbers(100000.) AS `__table6`) AS `__table5` ON `__table4`.`key` = `__table5`.`key` SETTINGS parallel_replicas_prefer_local_join = 1) AS `__table3` ON `__table1`.`key` = `__table3`.`key` ORDER BY `__table1`.`key` ASC LIMIT _CAST(10000, 'UInt64'), _CAST(10, 'UInt64') (stage: WithMergeableState)
|
||||
<Debug> WithOrderCoordinator: Coordination done
|
||||
|
||||
nested join with analyzer and parallel replicas, both global
|
||||
420000 420000 420000 -140000
|
||||
420042 420042 420042 -140014
|
@ -17,125 +17,6 @@ insert into num_1 select number * 2, toString(number * 2) from numbers(1e7);
|
||||
insert into num_2 select number * 3, -number from numbers(1.5e6);
|
||||
"
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "simple join with analyzer"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1"
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "simple (global) join with analyzer and parallel replicas"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, allow_experimental_parallel_reading_from_replicas = 2,
|
||||
max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=0"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, allow_experimental_parallel_reading_from_replicas = 2, send_logs_level='trace',
|
||||
max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=0" 2>&1 |
|
||||
grep "executeQuery\|<Debug>.*Coordinator: Coordination done" |
|
||||
grep -o "SELECT.*WithMergeableState)\|<Debug>.*Coordinator: Coordination done" |
|
||||
sed -re 's/_data_[[:digit:]]+_[[:digit:]]+/_data_/g'
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "simple (local) join with analyzer and parallel replicas"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1,
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, send_logs_level='trace',
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1" 2>&1 |
|
||||
grep "executeQuery\|<Debug>.*Coordinator: Coordination done" |
|
||||
grep -o "SELECT.*WithMergeableState)\|<Debug>.*Coordinator: Coordination done" |
|
||||
sed -re 's/_data_[[:digit:]]+_[[:digit:]]+/_data_/g'
|
||||
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "simple (local) join with analyzer and parallel replicas and full sorting merge join"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, join_algorithm='full_sorting_merge',
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2) r on l.key = r.key
|
||||
order by l.key limit 10 offset 700000
|
||||
SETTINGS allow_experimental_analyzer=1, join_algorithm='full_sorting_merge', send_logs_level='trace',
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1" 2>&1 |
|
||||
grep "executeQuery\|<Debug>.*Coordinator: Coordination done" |
|
||||
grep -o "SELECT.*WithMergeableState)\|<Debug>.*Coordinator: Coordination done" |
|
||||
sed -re 's/_data_[[:digit:]]+_[[:digit:]]+/_data_/g'
|
||||
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "nested join with analyzer"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2 inner join
|
||||
(select number * 7 as key from numbers(1e5)) as nn on num_2.key = nn.key settings parallel_replicas_prefer_local_join=1) r
|
||||
on l.key = r.key order by l.key limit 10 offset 10000
|
||||
SETTINGS allow_experimental_analyzer=1"
|
||||
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "nested join with analyzer and parallel replicas, both local"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2 inner join
|
||||
(select number * 7 as key from numbers(1e5)) as nn on num_2.key = nn.key settings parallel_replicas_prefer_local_join=1) r
|
||||
on l.key = r.key order by l.key limit 10 offset 10000
|
||||
SETTINGS allow_experimental_analyzer=1,
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
select * from (select key, value from num_1) l
|
||||
inner join (select key, value from num_2 inner join
|
||||
(select number * 7 as key from numbers(1e5)) as nn on num_2.key = nn.key settings parallel_replicas_prefer_local_join=1) r
|
||||
on l.key = r.key order by l.key limit 10 offset 10000
|
||||
SETTINGS allow_experimental_analyzer=1, join_algorithm='full_sorting_merge', send_logs_level='trace',
|
||||
allow_experimental_parallel_reading_from_replicas = 2, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1,
|
||||
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', parallel_replicas_prefer_local_join=1" 2>&1 |
|
||||
grep "executeQuery\|<Debug>.*Coordinator: Coordination done" |
|
||||
grep -o "SELECT.*WithMergeableState)\|<Debug>.*Coordinator: Coordination done" |
|
||||
sed -re 's/_data_[[:digit:]]+_[[:digit:]]+/_data_/g'
|
||||
|
||||
|
||||
##############
|
||||
echo
|
||||
echo "nested join with analyzer and parallel replicas, both global"
|
@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tags: no-random-settings
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
|
||||
query_id="02982_$RANDOM"
|
||||
$CLICKHOUSE_CLIENT --query_id $query_id --log_query_threads 1 --query="select number, uniq(number) from numbers_mt(1e7) group by number limit 100 format Null;"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "system flush logs;"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "select count() > 0 from system.query_thread_log where query_id = '$query_id' and current_database = currentDatabase() and thread_name = 'AggregDestruct';"
|
@ -6,8 +6,8 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
|
||||
function test
|
||||
{
|
||||
$CLICKHOUSE_LOCAL --allow_experimental_dynamic_type=1 --allow_experimental_variant_type=1 --output_format_binary_encode_types_in_binary_format=1 -q "select $1 as value format RowBinaryWithNamesAndTypes" | $CLICKHOUSE_LOCAL --input-format RowBinaryWithNamesAndTypes --input_format_binary_decode_types_in_binary_format=1 -q "select value, toTypeName(value) from table"
|
||||
$CLICKHOUSE_LOCAL --allow_experimental_dynamic_type=1 --allow_experimental_variant_type=1 --output_format_native_encode_types_in_binary_format=1 -q "select $1 as value format Native" | $CLICKHOUSE_LOCAL --input-format Native --input_format_native_decode_types_in_binary_format=1 -q "select value, toTypeName(value) from table"
|
||||
$CLICKHOUSE_LOCAL --allow_experimental_dynamic_type=1 --allow_experimental_variant_type=1 --output_format_binary_encode_types_in_binary_format=1 -q "select $1 as value format RowBinaryWithNamesAndTypes" | $CLICKHOUSE_LOCAL --input-format RowBinaryWithNamesAndTypes --input_format_binary_decode_types_in_binary_format=1 -q "select value, toTypeName(value) from table"
|
||||
$CLICKHOUSE_LOCAL --allow_experimental_dynamic_type=1 --allow_experimental_variant_type=1 --output_format_native_encode_types_in_binary_format=1 -q "select $1 as value format Native" | $CLICKHOUSE_LOCAL --input-format Native --input_format_native_decode_types_in_binary_format=1 -q "select value, toTypeName(value) from table"
|
||||
}
|
||||
|
||||
test "materialize(42)::UInt8"
|
||||
|
@ -4,10 +4,23 @@ CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CUR_DIR"/../shell_config.sh
|
||||
|
||||
${CLICKHOUSE_CLIENT} -t -q "SELECT sleepEachRow(2) FORMAT Null" 2>&1 | grep -q "^2\." && echo "Ok" || echo "Fail"
|
||||
${CLICKHOUSE_CLIENT} --time -q "SELECT sleepEachRow(2) FORMAT Null" 2>&1 | grep -q "^2\." && echo "Ok" || echo "Fail"
|
||||
${CLICKHOUSE_CLIENT} --memory-usage -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1 | grep -q "^[0-9]\+$" && echo "Ok" || echo "Fail"
|
||||
${CLICKHOUSE_CLIENT} --memory-usage=none -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" # expected no output
|
||||
${CLICKHOUSE_CLIENT} --memory-usage=default -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1 | grep -q "^[0-9]\+$" && echo "Ok" || echo "Fail"
|
||||
${CLICKHOUSE_CLIENT} --memory-usage=readable -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1 | grep -q "^[0-9].*B$" && echo "Ok" || echo "Fail"
|
||||
${CLICKHOUSE_CLIENT} --memory-usage=unknown -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1 | grep -q "BAD_ARGUMENTS" && echo "Ok" || echo "Fail"
|
||||
output=$(${CLICKHOUSE_CLIENT} -t -q "SELECT sleepEachRow(2) FORMAT Null" 2>&1)
|
||||
{ echo "$output" | grep -q "^2\." && echo "Ok"; } || { echo "Fail"; echo "'$output'"; }
|
||||
|
||||
output=$(${CLICKHOUSE_CLIENT} --time -q "SELECT sleepEachRow(2) FORMAT Null" 2>&1)
|
||||
{ echo "$output" | grep -q "^2\." && echo "Ok"; } || { echo "Fail"; echo "'$output'"; }
|
||||
|
||||
output=$(${CLICKHOUSE_CLIENT} --memory-usage -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1)
|
||||
{ echo "$output" | grep -q "^[0-9]\+$" && echo "Ok"; } || { echo "Fail"; echo "'$output'"; }
|
||||
|
||||
output=$(${CLICKHOUSE_CLIENT} --memory-usage=none -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1)
|
||||
echo -n "$output" # expected no output
|
||||
|
||||
output=$(${CLICKHOUSE_CLIENT} --memory-usage=default -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1)
|
||||
{ echo "$output" | grep -q "^[0-9]\+$" && echo "Ok"; } || { echo "Fail"; echo "'$output'"; }
|
||||
|
||||
output=$(${CLICKHOUSE_CLIENT} --memory-usage=readable -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1)
|
||||
{ echo "$output" | grep -q "^[0-9].*B$" && echo "Ok"; } || { echo "Fail"; echo "'$output'"; }
|
||||
|
||||
output=$(${CLICKHOUSE_CLIENT} --memory-usage=unknown -q "SELECT sum(number) FROM numbers(10_000) FORMAT Null" 2>&1)
|
||||
{ echo "$output" | grep -q "BAD_ARGUMENTS" && echo "Ok"; } || { echo "Fail"; echo "'$output'"; }
|
||||
|
4
tests/queries/0_stateless/03204_format_join_on.reference
Normal file
4
tests/queries/0_stateless/03204_format_join_on.reference
Normal file
@ -0,0 +1,4 @@
|
||||
SELECT * FROM t1 INNER JOIN t2 ON ((t1.x = t2.x) AND (t1.x IS NULL) AS e2)
|
||||
SELECT * FROM t1 INNER JOIN t2 ON ((t1.x = t2.x) AND (t1.x IS NULL) AS e2)
|
||||
SELECT * FROM t1 INNER JOIN t2 ON (t1.x = t2.x) AND ((t1.x IS NULL) AS e2)
|
||||
SELECT * FROM t1 INNER JOIN t2 ON t1.x = t2.x
|
15
tests/queries/0_stateless/03204_format_join_on.sh
Executable file
15
tests/queries/0_stateless/03204_format_join_on.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CUR_DIR"/../shell_config.sh
|
||||
|
||||
# regression for the JOIN ON alias for the whole expression
|
||||
phase1="$($CLICKHOUSE_FORMAT --oneline --query "SELECT * FROM t1 JOIN t2 ON ((t1.x = t2.x) AND (t1.x IS NULL) AS e2)")"
|
||||
echo "$phase1"
|
||||
# phase 2
|
||||
$CLICKHOUSE_FORMAT --oneline --query "$phase1"
|
||||
|
||||
# other test cases
|
||||
$CLICKHOUSE_FORMAT --oneline --query "SELECT * FROM t1 JOIN t2 ON (t1.x = t2.x) AND (t1.x IS NULL AS e2)"
|
||||
$CLICKHOUSE_FORMAT --oneline --query "SELECT * FROM t1 JOIN t2 ON t1.x = t2.x"
|
@ -0,0 +1 @@
|
||||
Hello world
|
7
tests/queries/0_stateless/03206_no_exceptions_clickhouse_local.sh
Executable file
7
tests/queries/0_stateless/03206_no_exceptions_clickhouse_local.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
CLICKHOUSE_TERMINATE_ON_ANY_EXCEPTION=1 ${CLICKHOUSE_LOCAL} --query "SELECT * FROM table" --input-format CSV <<<"Hello, world"
|
@ -0,0 +1,3 @@
|
||||
1 tx1 US
|
||||
1 tx2 US
|
||||
1 tx3 US
|
@ -0,0 +1,33 @@
|
||||
DROP TABLE IF EXISTS user_country;
|
||||
DROP TABLE IF EXISTS user_transactions;
|
||||
|
||||
CREATE TABLE user_country (
|
||||
user_id UInt64,
|
||||
country String
|
||||
)
|
||||
ENGINE = ReplacingMergeTree
|
||||
ORDER BY user_id;
|
||||
|
||||
CREATE TABLE user_transactions (
|
||||
user_id UInt64,
|
||||
transaction_id String
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY user_id;
|
||||
|
||||
INSERT INTO user_country (user_id, country) VALUES (1, 'US');
|
||||
INSERT INTO user_transactions (user_id, transaction_id) VALUES (1, 'tx1'), (1, 'tx2'), (1, 'tx3'), (2, 'tx1');
|
||||
|
||||
-- Expected 3 rows, got only 1. Removing 'ANY' and adding 'FINAL' fixes
|
||||
-- the issue (but it is not always possible). Moving filter by 'country' to
|
||||
-- an outer query doesn't help. Query without filter by 'country' works
|
||||
-- as expected (returns 3 rows).
|
||||
SELECT * FROM user_transactions
|
||||
ANY LEFT JOIN user_country USING (user_id)
|
||||
WHERE
|
||||
user_id = 1
|
||||
AND country = 'US'
|
||||
ORDER BY ALL;
|
||||
|
||||
DROP TABLE user_country;
|
||||
DROP TABLE user_transactions;
|
@ -0,0 +1,19 @@
|
||||
DATA
|
||||
┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━┓
|
||||
┃ c0 ┃ c1 ┃ c2 ┃
|
||||
┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━┩
|
||||
1. │ 826636805 │ 0 │ │
|
||||
├───────────┼───────────┼────┤
|
||||
2. │ 0 │ 150808457 │ │
|
||||
└───────────┴───────────┴────┘
|
||||
NUMBER OF ROWS IN FIRST SHOULD BE EQUAL TO SECOND
|
||||
FISRT
|
||||
|
||||
SECOND
|
||||
1
|
||||
TO DEBUG I TOOK JUST A SUBQUERY AND IT HAS 1 ROW
|
||||
THIRD
|
||||
1
|
||||
AND I ADDED SINGLE CONDITION THAT CONDITION <>0 THAT IS 1 IN THIRD QUERY AND IT HAS NO RESULT!!!
|
||||
FOURTH
|
||||
1
|
@ -0,0 +1,45 @@
|
||||
DROP TABLE IF EXISTS t0;
|
||||
|
||||
CREATE TABLE t0 (c0 Int32, c1 Int32, c2 String) ENGINE = Log() ;
|
||||
INSERT INTO t0(c0, c1, c2) VALUES (826636805,0, ''), (0, 150808457, '');
|
||||
|
||||
SELECT 'DATA';
|
||||
SELECT * FROM t0 FORMAT PrettyMonoBlock;
|
||||
|
||||
SELECT 'NUMBER OF ROWS IN FIRST SHOULD BE EQUAL TO SECOND';
|
||||
|
||||
|
||||
SELECT 'FISRT';
|
||||
SELECT left.c2 FROM t0 AS left
|
||||
LEFT ANTI JOIN t0 AS right_0 ON ((left.c0)=(right_0.c1))
|
||||
WHERE (abs ((- ((sign (right_0.c1))))));
|
||||
|
||||
SELECT 'SECOND';
|
||||
SELECT SUM(check <> 0)
|
||||
FROM
|
||||
(
|
||||
SELECT (abs ((- ((sign (right_0.c1)))))) AS `check`
|
||||
FROM t0 AS left
|
||||
LEFT ANTI JOIN t0 AS right_0 ON ((left.c0)=(right_0.c1))
|
||||
);
|
||||
|
||||
|
||||
SELECT 'TO DEBUG I TOOK JUST A SUBQUERY AND IT HAS 1 ROW';
|
||||
|
||||
SELECT 'THIRD';
|
||||
|
||||
SELECT (abs ((- ((sign (right_0.c1)))))) AS `check`
|
||||
FROM t0 AS left
|
||||
LEFT ANTI JOIN t0 AS right_0 ON ((left.c0)=(right_0.c1));
|
||||
|
||||
|
||||
SELECT 'AND I ADDED SINGLE CONDITION THAT CONDITION <>0 THAT IS 1 IN THIRD QUERY AND IT HAS NO RESULT!!!';
|
||||
|
||||
|
||||
SELECT 'FOURTH';
|
||||
SELECT (abs ((- ((sign (right_0.c1)))))) AS `check`
|
||||
FROM t0 AS left
|
||||
LEFT ANTI JOIN t0 AS right_0 ON ((left.c0)=(right_0.c1))
|
||||
WHERE check <> 0;
|
||||
|
||||
DROP TABLE t0;
|
@ -0,0 +1,13 @@
|
||||
DROP TABLE IF EXISTS test_table;
|
||||
CREATE TABLE test_table
|
||||
(
|
||||
id UInt64,
|
||||
value String
|
||||
) ENGINE=TinyLog;
|
||||
|
||||
EXPLAIN SYNTAX
|
||||
WITH 1 AS compound_value SELECT * APPLY (x -> compound_value.*)
|
||||
FROM test_table WHERE x > 0
|
||||
SETTINGS convert_query_to_cnf = true, optimize_using_constraints = true, optimize_substitute_columns = true; -- { serverError UNKNOWN_IDENTIFIER }
|
||||
|
||||
DROP TABLE test_table;
|
@ -17,11 +17,11 @@ $CLICKHOUSE_CLIENT -q "OPTIMIZE TABLE hits_s3_sampled FINAL"
|
||||
$CLICKHOUSE_CLIENT -q "SYSTEM DROP FILESYSTEM CACHE"
|
||||
|
||||
# Warm up the cache
|
||||
$CLICKHOUSE_CLIENT -q "SELECT * FROM hits_s3_sampled WHERE URL LIKE '%google%' ORDER BY EventTime LIMIT 10 FORMAT Null"
|
||||
$CLICKHOUSE_CLIENT -q "SELECT * FROM hits_s3_sampled WHERE URL LIKE '%google%' ORDER BY EventTime LIMIT 10 FORMAT Null"
|
||||
$CLICKHOUSE_CLIENT -q "SELECT * FROM hits_s3_sampled WHERE URL LIKE '%google%' ORDER BY EventTime LIMIT 10 FORMAT Null SETTINGS filesystem_cache_reserve_space_wait_lock_timeout_milliseconds=2000"
|
||||
$CLICKHOUSE_CLIENT -q "SELECT * FROM hits_s3_sampled WHERE URL LIKE '%google%' ORDER BY EventTime LIMIT 10 FORMAT Null SETTINGS filesystem_cache_reserve_space_wait_lock_timeout_milliseconds=2000"
|
||||
|
||||
query_id=02906_read_from_cache_$RANDOM
|
||||
$CLICKHOUSE_CLIENT --query_id ${query_id} -q "SELECT * FROM hits_s3_sampled WHERE URL LIKE '%google%' ORDER BY EventTime LIMIT 10 FORMAT Null"
|
||||
$CLICKHOUSE_CLIENT --query_id ${query_id} -q "SELECT * FROM hits_s3_sampled WHERE URL LIKE '%google%' ORDER BY EventTime LIMIT 10 FORMAT Null SETTINGS filesystem_cache_reserve_space_wait_lock_timeout_milliseconds=2000"
|
||||
|
||||
$CLICKHOUSE_CLIENT -nq "
|
||||
SYSTEM FLUSH LOGS;
|
||||
|
Loading…
Reference in New Issue
Block a user